Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ICS 6: Solo Machine Client #331

Merged
merged 9 commits into from
Jan 4, 2020
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ All standards at or past the "Draft" stage are listed here in order of their ICS
| [3](spec/ics-003-connection-semantics) | Instantiation | Connection Semantics | Draft |
| [4](spec/ics-004-channel-and-packet-semantics) | Instantiation | Channel & Packet Semantics | Draft |
| [5](spec/ics-005-port-allocation) | Interface | Port Allocation | Draft |
| [6](spec/ics-006-solo-machine-client) | Instantiation | Solo Machine Client | Draft |
| [18](spec/ics-018-relayer-algorithms) | Interface | Relayer Algorithms | Draft |
| [23](spec/ics-023-vector-commitments) | Interface | Vector Commitments | Draft |
| [24](spec/ics-024-host-requirements) | Interface | Host Requirements | Draft |
Expand Down
4 changes: 2 additions & 2 deletions assets/deps.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion misc/aspell_dict
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
personal_ws-1.1 en 533
personal_ws-1.1 en 534
ABCI
ABI
Agoric
Expand Down Expand Up @@ -508,6 +508,7 @@ untrusted
updateClient
updateConsensusState
updatePort
updateable
validRound
validValue
validateChannelIdentifier
Expand Down
4 changes: 4 additions & 0 deletions spec.pdc
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ urlcolor: cyan

!include spec/ics-027-interchain-accounts/README.md.xfm

# ICS 006 - Solo Machine Client

!include spec/ics-006-solo-machine-client/README.md.xfm

# Appendix A: Use-case Descriptions

!include ibc/4_IBC_USECASES.md.xfm
Expand Down
Binary file modified spec.pdf
Binary file not shown.
7 changes: 7 additions & 0 deletions spec/ics-006-solo-machine-client/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
typecheck:

build:

clean:

.PHONY: typecheck build clean
262 changes: 262 additions & 0 deletions spec/ics-006-solo-machine-client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
---
ics: 6
title: Solo Machine Client
stage: draft
category: IBC/TAO
kind: instantiation
implements: 2
author: Christopher Goes <cwgoes@tendermint.com>
created: 2019-12-09
modified: 2019-12-09
---

## Synopsis

This specification document describes a client (verification algorithm) for a solo machine with a single updateable public key which implements the [ICS 2](../ics-002-client-semantics) interface.

### Motivation

Solo machines — which might be devices such as phones, browsers, or laptops — might like to interface with other machines & replicated ledgers which speak IBC, and they can do so through the uniform client interface.

### Definitions

Functions & terms are as defined in [ICS 2](../ics-002-client-semantics).

### Desired Properties

This specification must satisfy the client interface defined in [ICS 2](../ics-002-client-semantics).

## Technical Specification

This specification contains implementations for all of the functions defined by [ICS 2](../ics-002-client-semantics).

### Client state

The `ClientState` of a solo machine is simply whether or not the client is frozen.

```typescript
interface ClientState {
frozen: boolean
}
```

### Consensus state

The `ConsensusState` of a solo machine consists of the current public key & sequence number.

```typescript
interface ConsensusState {
sequence: uint64
publicKey: PublicKey
}
```

### Headers

`Header`s must only be provided by a solo machine when the machine wishes to update the public key.

```typescript
interface Header {
sequence: uint64
signature: Signature
newPublicKey: PublicKey
}
```

### Evidence

`Evidence` of solo machine misbehaviour consists of a sequence and two signatures over different messages at that sequence.

```typescript
interface Evidence {
sequence: uint64
signatureOne: Signature
signatureTwo: Signature
}
```

### Client initialisation

The solo machine client `initialise` function starts an unfrozen client with the initial consensus state.

```typescript
function initialise(consensusState: ConsensusState): ClientState {
return {
frozen: false,
consensusState
}
}
```

### Validity predicate

The solo machine client `checkValidityAndUpdateState` function checks that the currently registered public key has signed over the new public key with the correct sequence.

```typescript
function checkValidityAndUpdateState(
clientState: ClientState,
header: Header) {
assert(sequence === clientState.consensusState.sequence)
assert(checkSignature(header.newPublicKey, header.sequence, header.signature))
clientState.consensusState.publicKey = header.newPublicKey
clientState.consensusState.sequence++
}
```

### Misbehaviour predicate

Any duplicate signature on different messages by the current public key freezes a solo machine client.

```typescript
function checkMisbehaviourAndUpdateState(
clientState: ClientState,
evidence: Evidence) {
h1 = evidence.h1
h2 = evidence.h2
pubkey = clientState.consensusState.publicKey
assert(evidence.h1.signature.data !== evidence.h2.signature.data)
assert(checkSignature(pubkey, evidence.sequence, evidence.h1.signature))
assert(checkSignature(pubkey, evidence.sequence, evidence.h2.signature))
clientState.frozen = true
}
```

### State verification functions

All solo machine client state verification functions simply check a signature, which must be provided by the solo machine.

```typescript
function verifyClientConsensusState(
clientState: ClientState,
height: uint64,
prefix: CommitmentPrefix,
proof: CommitmentProof,
clientIdentifier: Identifier,
consensusState: ConsensusState) {
path = applyPrefix(prefix, "clients/{clientIdentifier}/consensusState")
abortTransactionUnless(!clientState.frozen)
value = clientState.consensusState.sequence + path + consensusState
assert(checkSignature(clientState.consensusState.pubKey, value, proof))
clientState.consensusState.sequence++
}

function verifyConnectionState(
clientState: ClientState,
height: uint64,
prefix: CommitmentPrefix,
proof: CommitmentProof,
connectionIdentifier: Identifier,
connectionEnd: ConnectionEnd) {
path = applyPrefix(prefix, "connection/{connectionIdentifier}")
abortTransactionUnless(!clientState.frozen)
value = clientState.consensusState.sequence + path + connectionEnd
assert(checkSignature(clientState.consensusState.pubKey, value, proof))
clientState.consensusState.sequence++
}

function verifyChannelState(
clientState: ClientState,
height: uint64,
prefix: CommitmentPrefix,
proof: CommitmentProof,
portIdentifier: Identifier,
channelIdentifier: Identifier,
channelEnd: ChannelEnd) {
path = applyPrefix(prefix, "ports/{portIdentifier}/channels/{channelIdentifier}")
abortTransactionUnless(!clientState.frozen)
value = clientState.consensusState.sequence + path + channelEnd
assert(checkSignature(clientState.consensusState.pubKey, value, proof))
clientState.consensusState.sequence++
}

function verifyPacketCommitment(
clientState: ClientState,
height: uint64,
prefix: CommitmentPrefix,
proof: CommitmentProof,
portIdentifier: Identifier,
channelIdentifier: Identifier,
sequence: uint64,
commitment: bytes) {
path = applyPrefix(prefix, "ports/{portIdentifier}/channels/{channelIdentifier}/packets/{sequence}")
abortTransactionUnless(!clientState.frozen)
value = clientState.consensusState.sequence + path + commitment
assert(checkSignature(clientState.consensusState.pubKey, value, proof))
clientState.consensusState.sequence++
}

function verifyPacketAcknowledgement(
clientState: ClientState,
height: uint64,
prefix: CommitmentPrefix,
proof: CommitmentProof,
portIdentifier: Identifier,
channelIdentifier: Identifier,
sequence: uint64,
acknowledgement: bytes) {
path = applyPrefix(prefix, "ports/{portIdentifier}/channels/{channelIdentifier}/acknowledgements/{sequence}")
abortTransactionUnless(!clientState.frozen)
value = clientState.consensusState.sequence + path + acknowledgement
assert(checkSignature(clientState.consensusState.pubKey, value, proof))
clientState.consensusState.sequence++
}

function verifyPacketAcknowledgementAbsence(
clientState: ClientState,
height: uint64,
prefix: CommitmentPrefix,
proof: CommitmentProof,
portIdentifier: Identifier,
channelIdentifier: Identifier,
sequence: uint64) {
path = applyPrefix(prefix, "ports/{portIdentifier}/channels/{channelIdentifier}/acknowledgements/{sequence}")
abortTransactionUnless(!clientState.frozen)
value = clientState.consensusState.sequence + path
assert(checkSignature(clientState.consensusState.pubKey, value, proof))
clientState.consensusState.sequence++
}

function verifyNextSequenceRecv(
clientState: ClientState,
height: uint64,
prefix: CommitmentPrefix,
proof: CommitmentProof,
portIdentifier: Identifier,
channelIdentifier: Identifier,
nextSequenceRecv: uint64) {
path = applyPrefix(prefix, "ports/{portIdentifier}/channels/{channelIdentifier}/nextSequenceRecv")
abortTransactionUnless(!clientState.frozen)
value = clientState.consensusState.sequence + path + nextSequenceRecv
assert(checkSignature(clientState.consensusState.pubKey, value, proof))
clientState.consensusState.sequence++
}
```

### Properties & Invariants

Instantiates the interface defined in [ICS 2](../ics-002-client-semantics).

## Backwards Compatibility

Not applicable.

## Forwards Compatibility

Not applicable. Alterations to the client verification algorithm will require a new client standard.

## Example Implementation

None yet.

## Other Implementations

None at present.

## History

December 9th, 2019 - Initial version
December 17th, 2019 - Final first draft

## Copyright

All content herein is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0).