Skip to content

Commit

Permalink
Merge PR #273: Remaining rc3 feedback in preparation for rc4
Browse files Browse the repository at this point in the history
* Rebuild PDF
* Separate commitment path (ref #258)
* Clarify connection versioning (ref #269)
* Note private store key flexibility (ref #145)
  • Loading branch information
cwgoes authored Sep 20, 2019
1 parent c7dff53 commit 6ee3570
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 38 deletions.
7 changes: 6 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 448
personal_ws-1.1 en 453
unescrow
onChanCloseConfirm
clientKey
Expand Down Expand Up @@ -239,6 +239,7 @@ FungibleTokenPacketData
SpeckleOS
pseudocode
proofAck
getCompatibleVersions
nextSequenceSendKey
datatypes
getRoot
Expand Down Expand Up @@ -304,6 +305,7 @@ clientTypePath
handleClientMisbehaviour
interoperation
tokenising
CommitmentPath
authenticationKey
sharding
scalability
Expand Down Expand Up @@ -394,6 +396,7 @@ validatePortIdentifier
Merkle
clientIdentifier
handleChanOpenTry
pickVersion
chanOpenTimeout
th
unallocated
Expand All @@ -405,6 +408,7 @@ datapipe
ConnCloseAck
VM
ModuleState
indexOf
Strawman
tx
bytestring
Expand All @@ -429,6 +433,7 @@ escrowAddress
UpdateLightClient
newPublicKey
newCapabilityKey
counterpartyVersions
validateChannelIdentifier
Uniswap
onTimeoutPacket
Expand Down
Binary file modified spec.pdf
Binary file not shown.
28 changes: 21 additions & 7 deletions spec/ics-003-connection-semantics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ interface ConnectionEnd {
counterpartyPrefix: CommitmentPrefix
clientIdentifier: Identifier
counterpartyClientIdentifier: Identifier
version: string
version: string | []string
}
```

Expand Down Expand Up @@ -202,6 +202,20 @@ type validateConnectionIdentifier = (id: Identifier) => boolean
If not provided, the default `validateConnectionIdentifier` function will always return `true`.
#### Versioning
An implementation must define a function `getCompatibleVersions` which returns the list of versions it supports, ranked by descending preference order.
```typescript
type getCompatibleVersions = () => []string
```
An implementation must define a function `pickVersion` to choose a version from a list of versions proposed by a counterparty.
```typescript
type pickVersion = ([]string) => string
```
#### Opening Handshake
The opening handshake sub-protocol serves to initialise consensus states for two chains on each other.
Expand Down Expand Up @@ -233,13 +247,12 @@ function connOpenInit(
desiredCounterpartyConnectionIdentifier: Identifier,
counterpartyPrefix: CommitmentPrefix,
clientIdentifier: Identifier,
counterpartyClientIdentifier: Identifier,
version: string) {
counterpartyClientIdentifier: Identifier) {
abortTransactionUnless(validateConnectionIdentifier(identifier))
abortTransactionUnless(provableStore.get(connectionPath(identifier)) == null)
state = INIT
connection = ConnectionEnd{state, desiredCounterpartyConnectionIdentifier, counterpartyPrefix,
clientIdentifier, counterpartyClientIdentifier, version}
clientIdentifier, counterpartyClientIdentifier, getCompatibleVersions()}
provableStore.set(connectionPath(identifier), connection)
addConnectionToClient(clientIdentifier, identifier)
}
Expand All @@ -254,16 +267,16 @@ function connOpenTry(
counterpartyPrefix: CommitmentPrefix,
counterpartyClientIdentifier: Identifier,
clientIdentifier: Identifier,
version: string,
counterpartyVersion: string
counterpartyVersions: string[],
proofInit: CommitmentProof,
proofHeight: uint64,
consensusHeight: uint64) {
abortTransactionUnless(validateConnectionIdentifier(desiredIdentifier))
abortTransactionUnless(consensusHeight <= getCurrentHeight())
expectedConsensusState = getConsensusState(consensusHeight)
expected = ConnectionEnd{INIT, desiredIdentifier, getCommitmentPrefix(), counterpartyClientIdentifier,
clientIdentifier, counterpartyVersion}
clientIdentifier, counterpartyVersions}
version = pickVersion(counterpartyVersions)
connection = ConnectionEnd{state, counterpartyConnectionIdentifier, counterpartyPrefix,
clientIdentifier, counterpartyClientIdentifier, version}
abortTransactionUnless(
Expand Down Expand Up @@ -309,6 +322,7 @@ function connOpenAck(
consensusStatePath(connection.counterpartyClientIdentifier),
expectedConsensusState))
connection.state = OPEN
abortTransactionUnless(getCompatibleVersions().indexOf(version) !== -1)
connection.version = version
provableStore.set(connectionPath(identifier), connection)
}
Expand Down
2 changes: 1 addition & 1 deletion spec/ics-004-channel-and-packet-semantics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ interface Channel {
- The `nextSequenceSend`, stored separately, tracks the sequence number for the next packet to be sent.
- The `nextSequenceRecv`, stored separately, tracks the sequence number for the next packet to be received.
- The `connectionHops` stores the list of connection identifiers, in order, along which packets sent on this channel will travel. At the moment this list must be of length 1. In the future multi-hop channels may be supported.
- The `version` string stores an opaque channel version, which is agreed upon during the handshake. This can determine module-level configuration such as which packet encoding is used for the channel.
- The `version` string stores an opaque channel version, which is agreed upon during the handshake. This can determine module-level configuration such as which packet encoding is used for the channel. This version is not used by the core IBC protocol.

Channel ends have a *state*:

Expand Down
67 changes: 39 additions & 28 deletions spec/ics-023-vector-commitments/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ This document only defines desired properties, not a concrete implementation —

A commitment construction MUST specify the following datatypes, which are otherwise opaque (need not be introspected) but MUST be serialisable:

#### State
#### Commitment State

An `CommitmentState` is the full state of the commitment, which will be stored by the manager.

```typescript
type CommitmentState = object
```
#### Root
#### Commitment Root
An `CommitmentRoot` commits to a particular commitment state and should be constant-size.
Expand All @@ -59,6 +59,14 @@ In certain commitment constructions with constant-size states, `CommitmentState`
type CommitmentRoot = object
```
#### Commitment Path
A `CommitmentPath` is the path used to verify commitment proofs, which can be an arbitrary structured object (defined by a commitment type). It must be computed by `applyPrefix` (defined below).
```typescript
type CommitmentPath = object
```
#### Prefix
A `CommitmentPrefix` defines a store prefix of the commitment proof. It is applied to the path before the path is passed to the proof verification functions.
Expand All @@ -67,13 +75,16 @@ A `CommitmentPrefix` defines a store prefix of the commitment proof. It is appli
type CommitmentPrefix = object
```
The function `applyPrefix` constructs a new path from the arguments. It interprets the path argument in the context of the prefix argument.
The function `applyPrefix` constructs a new commitment path from the arguments. It interprets the path argument in the context of the prefix argument.
For two `(prefix, path)` tuples, `applyPrefix(prefix, path)` MUST return the same key only if the tuple elements are equal.
`applyPrefix` MUST be implemented per `Path`, as `Path` can have different concrete structures. `applyPrefix` MAY accept multiple `CommitmentPrefix` types.
`applyPrefix` does not need to be serialisable.
The `CommitmentPath` returned by `applyPrefix` does not need to be serialisable (e.g. it might be a list of tree node identifiers), but it does need an equality comparison.
```typescript
type applyPrefix = (prefix: CommitmentPrefix, path: Path) => Path
type applyPrefix = (prefix: CommitmentPrefix, path: Path) => CommitmentPath
```
#### Proof
Expand Down Expand Up @@ -126,30 +137,30 @@ type remove = (state: CommitmentState, path: Path) => CommitmentState
#### Proof generation
The `createMembershipProof` function generates a proof that a particular path has been set to a particular value in a commitment.
The `createMembershipProof` function generates a proof that a particular commitment path has been set to a particular value in a commitment.
```typescript
type createMembershipProof = (state: CommitmentState, path: Path, value: Value) => CommitmentProof
type createMembershipProof = (state: CommitmentState, path: CommitmentPath, value: Value) => CommitmentProof
```
The `createNonMembershipProof` function generates a proof that a path has not been set to any value in a commitment.
The `createNonMembershipProof` function generates a proof that a commitment path has not been set to any value in a commitment.
```typescript
type createNonMembershipProof = (state: CommitmentState, path: Path) => CommitmentProof
type createNonMembershipProof = (state: CommitmentState, path: CommitmentPath) => CommitmentProof
```
#### Proof verification
The `verifyMembership` function verifies a proof that a path has been set to a particular value in a commitment.
```typescript
type verifyMembership = (root: CommitmentRoot, proof: CommitmentProof, path: Path, value: Value) => boolean
type verifyMembership = (root: CommitmentRoot, proof: CommitmentProof, path: CommitmentPath, value: Value) => boolean
```
The `verifyNonMembership` function verifies a proof that a path has not been set to any value in a commitment.
```typescript
type verifyNonMembership = (root: CommitmentRoot, proof: CommitmentProof, path: Path) => boolean
type verifyNonMembership = (root: CommitmentRoot, proof: CommitmentProof, path: CommitmentPath) => boolean
```
### Optional functions
Expand All @@ -159,13 +170,13 @@ A commitment construction MAY provide the following functions:
The `batchVerifyMembership` function verifies a proof that many paths have been set to specific values in a commitment.
```typescript
type batchVerifyMembership = (root: CommitmentRoot, proof: CommitmentProof, items: Map<Path, Value>) => boolean
type batchVerifyMembership = (root: CommitmentRoot, proof: CommitmentProof, items: Map<CommitmentPath, Value>) => boolean
```
The `batchVerifyNonMembership` function verifies a proof that many paths have not been set to any value in a commitment.
```typescript
type batchVerifyNonMembership = (root: CommitmentRoot, proof: CommitmentProof, paths: Set<Path>) => boolean
type batchVerifyNonMembership = (root: CommitmentRoot, proof: CommitmentProof, paths: Set<CommitmentPath>) => boolean
```
If defined, these functions MUST produce the same result as the conjunctive union of `verifyMembership` and `verifyNonMembership` respectively (efficiency may vary):
Expand All @@ -190,63 +201,63 @@ Commitments MUST be *complete*, *sound*, and *position binding*. These propertie
Commitment proofs MUST be *complete*: path => value mappings which have been added to the commitment can always be proved to have been included, and paths which have not been included can always be proved to have been excluded, except with probability negligible in `k`.
For any path `path` last set to a value `value` in the commitment `acc`,
For any prefix `prefix` and any path `path` last set to a value `value` in the commitment `acc`,
```typescript
root = getRoot(acc)
proof = createMembershipProof(acc, path, value)
proof = createMembershipProof(acc, applyPrefix(prefix, path), value)
```
```
Probability(verifyMembership(root, proof, path, value) === false) negligible in k
Probability(verifyMembership(root, proof, applyPrefix(prefix, path), value) === false) negligible in k
```
For any path `path` not set in the commitment `acc`, for all values of `proof` and all values of `value`,
For any prefix `prefix` and any path `path` not set in the commitment `acc`, for all values of `proof` and all values of `value`,
```typescript
root = getRoot(acc)
proof = createNonMembershipProof(acc, path)
proof = createNonMembershipProof(acc, applyPrefix(prefix, path))
```
```
Probability(verifyNonMembership(root, proof, path) === false) negligible in k
Probability(verifyNonMembership(root, proof, applyPrefix(prefix, path)) === false) negligible in k
```
#### Soundness
Commitment proofs MUST be *sound*: path => value mappings which have not been added to the commitment cannot be proved to have been included, or paths which have been added to the commitment excluded, except with probability negligible in a configurable security parameter `k`.
For any path `path` last set to a value `value` in the commitment `acc`, for all values of `proof`,
For any prefix `prefix` and any path `path` last set to a value `value` in the commitment `acc`, for all values of `proof`,
```
Probability(verifyNonMembership(root, proof, path) === true) negligible in k
Probability(verifyNonMembership(root, proof, applyPrefix(prefix, path)) === true) negligible in k
```
For any path `path` not set in the commitment `acc`, for all values of `proof` and all values of `value`,
For any prefix `prefix` and any path `path` not set in the commitment `acc`, for all values of `proof` and all values of `value`,
```
Probability(verifyMembership(root, proof, path, value) === true) negligible in k
Probability(verifyMembership(root, proof, applyPrefix(prefix, path), value) === true) negligible in k
```
#### Position binding
Commitment proofs MUST be *position binding*: a given path can only map to one value, and a commitment proof cannot prove that the same path opens to a different value except with probability negligible in k.
Commitment proofs MUST be *position binding*: a given commitment path can only map to one value, and a commitment proof cannot prove that the same path opens to a different value except with probability negligible in k.
For any path `path` set in the commitment `acc`, there is one `value` for which:
For any prefix `prefix` and any path `path` set in the commitment `acc`, there is one `value` for which:
```typescript
root = getRoot(acc)
proof = createMembershipProof(acc, path, value)
proof = createMembershipProof(acc, applyPrefix(prefix, path), value)
```
```
Probability(verifyMembership(root, proof, path, value) === false) negligible in k
Probability(verifyMembership(root, proof, applyPrefix(prefix, path), value) === false) negligible in k
```
For all other values `otherValue` where `value !== otherValue`, for all values of `proof`,
```
Probability(verifyMembership(root, proof, path, otherValue) === true) negligible in k
Probability(verifyMembership(root, proof, applyPrefix(prefix, path), otherValue) === true) negligible in k
```
## Backwards Compatibility
Expand Down
8 changes: 7 additions & 1 deletion spec/ics-024-host-requirements/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,13 @@ The `privateStore`:
### Path-space
At present, IBC/TAO utilises the following path prefixes for the `provableStore` and `privateStore`. Future paths may be used in future versions of the protocol, so the entire key-space in both stores MUST be reserved for the IBC handler.
At present, IBC/TAO utilises the following path prefixes for the `provableStore` and `privateStore`.
Future paths may be used in future versions of the protocol, so the entire key-space in the provable store MUST be reserved for the IBC handler.
Parts of the private store MAY safely be used for other purposes as long as the IBC handler has exclusive access to the specific keys required.
Keys used in the private store MAY safely vary as long as there exists a bipartite mapping between the key formats defined herein and the ones
actually used in the private store implementation.
| Store | Path format | Value type | Defined in |
| -------------- | ------------------------------------------------------------------------ | ----------------- | ---------------------- |
Expand Down

0 comments on commit 6ee3570

Please sign in to comment.