-
Notifications
You must be signed in to change notification settings - Fork 397
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
ICS33: Multi-hop Channel Spec #882
Changes from all commits
fb716fc
3bc1800
f7f1a6c
1421d33
2be7894
eb0193c
3e167eb
f773339
437c6f9
337d393
4d62c51
280fc28
c1f8bd0
6dcb58a
bb4f37e
1af38b5
fc34fdf
ebc08ee
9ee66b2
a7ecb58
87795f8
eca9ded
44e4ac1
c85c8aa
7f133d7
1213e61
3784cef
bd6c39e
f4baac5
c04a201
5e0d503
4f91306
17da31d
594a5bb
12e7ad5
9265373
dd84773
4dd2204
243bd2e
804a828
b9ca4ca
9f13123
7bebf3b
f69e191
56e0f0a
73ef434
4262a63
6f52039
c76b25a
d0024c6
e385e8d
071b4ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -258,11 +258,83 @@ function verifyNextSequenceRecv( | |
return verifyMembership(clientState, height, connection.delayPeriodTime, connection.delayPeriodBlocks, proof, path, nextSequenceRecv) | ||
} | ||
|
||
function verifyMultihopMembership( | ||
connection: ConnectionEnd, // the connection end corresponding to the receiving chain. | ||
height: Height, | ||
proof: MultihopProof, | ||
connectionHops: Identifier[], | ||
key: CommitmentPath, | ||
value: bytes) { | ||
|
||
// the connectionEnd corresponding to the end of the multi-hop channel path (sending/counterparty chain). | ||
multihopConnectionEnd = abortTransactionUnless(getMultihopConnectionEnd(proof)) | ||
prefix = multihopConnectionEnd.GetCounterparty().GetPrefix() | ||
client = queryClient(connection.clientIdentifier) | ||
consensusState = queryConsensusState(connection.clientIdentifier, height) | ||
|
||
abortTransactionUnless(client.Status() === "active") | ||
abortTransactionUnless(client.GetLatestHeight() >= height) | ||
|
||
// verify maximum delay period has passed | ||
expectedTimePerBlock = queryMaxExpectedTimePerBlock() | ||
delayPeriodTime = abortTransactionUnless(getMaximumDelayPeriod(proof, connection)) | ||
delayPeriodBlocks = getBlockDelay(delayPeriodTime, expectedTimePerBlock) | ||
abortTransactionUnless(tendermint.VerifyDelayPeriodPassed(height, delayPeriodTime, delayPeriodBlocks)) | ||
|
||
return multihop.VerifyMultihopMembership(consensusState, connectionHops, proof, prefix, key, value) // see ics-033 | ||
} | ||
|
||
function verifyMultihopNonMembership( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this used anywhere? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should be added to the timeoutPacket pseudo code in ics-004 which I overlooked. Will add. |
||
connection: ConnectionEnd, // the connection end corresponding to the receiving chain. | ||
height: Height, | ||
proof: MultihopProof, | ||
connectionHops: Identifier[], | ||
key: CommitmentPath) { | ||
|
||
// the connectionEnd corresponding to the end of the multi-hop channel path (sending/counterparty chain). | ||
multihopConnectionEnd = abortTransactionUnless(getMultihopConnectionEnd(proof)) | ||
prefix = multihopConnectionEnd.GetCounterparty().GetPrefix() | ||
client = queryClient(connection.clientIdentifier) | ||
consensusState = queryConsensusState(connection.clientIdentifier, height) | ||
|
||
abortTransactionUnless(client.Status() === "active") | ||
abortTransactionUnless(client.GetLatestHeight() >= height) | ||
|
||
// verify maximum delay period has passed | ||
expectedTimePerBlock = queryMaxExpectedTimePerBlock() | ||
delayPeriodTime = abortTransactionUnless(getMaximumDelayPeriod(proof, connection)) | ||
delayPeriodBlocks = getBlockDelay(delayPeriodTime, expectedTimePerBlock) | ||
abortTransactionUnless(tendermint.VerifyDelayPeriodPassed(height, delayPeriodTime, delayPeriodBlocks)) | ||
|
||
return multihop.VerifyMultihopNonMembership(consensusState, connectionHops, proof, prefix, key) // see ics-033 | ||
} | ||
|
||
// Return the maximum expected time per block from the paramstore. | ||
// See 03-connection - GetMaxExpectedTimePerBlock. | ||
function queryMaxExpectedTimePerBlock(): uint64 | ||
|
||
function getTimestampAtHeight( | ||
connection: ConnectionEnd, | ||
height: Height) { | ||
return queryConsensusState(connection.clientIdentifier, height).getTimestamp() | ||
} | ||
|
||
// Return the connectionEnd corresponding to the source chain. | ||
function getMultihopConnectionEnd(proof: MultihopProof): ConnectionEnd { | ||
return abortTransactionUnless(Unmarshal(proof.ConnectionProofs[proof.ConnectionProofs.length - 1].Value)) | ||
} | ||
|
||
// Return the maximum delay period in seconds across all connections in the channel path. | ||
function getMaximumDelayPeriod(proof: MultihopProof, lastConnection: ConnectionEnd): number { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should return two numbers. The delayPeriodBlock and delayPeriodTime There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no problem, the block delay is computed below, but I'll refactor this to return timeDelay and blockDelay There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. was this done? |
||
delayPeriodTime = lastConnection.GetDelayPeriod() | ||
for connData in range proofs.ConnectionProofs { | ||
connectionEnd = abortTransactionUnless(Unmarshal(connData.Value)) | ||
if (connectionEnd.DelayPeriod > delayPeriodTime) { | ||
delayPeriodTime = connectionEnd.DelayPeriod | ||
} | ||
} | ||
return delayPeriodTime | ||
} | ||
``` | ||
|
||
### Sub-protocols | ||
|
@@ -282,7 +354,7 @@ The validation function `validateConnectionIdentifier` MAY be provided. | |
type validateConnectionIdentifier = (id: Identifier) => boolean | ||
``` | ||
|
||
If not provided, the default `validateConnectionIdentifier` function will always return `true`. | ||
If not provided, the default `validateConnectionIdentifier` function will always return `true`. | ||
|
||
#### Versioning | ||
|
||
|
@@ -301,7 +373,7 @@ specifies IBC 1.0.0. | |
|
||
The `features` field specifies a list of features compatible with the specified | ||
identifier. The values `"ORDER_UNORDERED"` and `"ORDER_ORDERED"` specify | ||
unordered and ordered channels, respectively. | ||
unordered and ordered channels, respectively. | ||
|
||
Host state machine MUST utilise the version data to negotiate encodings, | ||
priorities, or connection-specific metadata related to custom logic on top of | ||
|
@@ -367,7 +439,7 @@ function connOpenInit( | |
|
||
abortTransactionUnless(queryClientState(clientIdentifier) !== null) | ||
abortTransactionUnless(provableStore.get(connectionPath(identifier)) == null) | ||
|
||
state = INIT | ||
if version != "" { | ||
// manually selected version must be one we can support | ||
|
@@ -404,7 +476,7 @@ function connOpenTry( | |
) { | ||
// generate a new identifier | ||
identifier = generateIdentifier() | ||
|
||
abortTransactionUnless(queryClientState(clientIdentifier) !== null) | ||
abortTransactionUnless(validateSelfClient(clientState)) | ||
abortTransactionUnless(consensusHeight < getCurrentHeight()) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not clear to me why we do this only for proofing the
key/value
. We could get the store prefix at intermediate hops andapplyPrefix
when proving connection and consenus states.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, the PrefixKey is already stored with the intermediate multihop proofs so this step is not required. However the expected key/value are created on the receiver depending on what proof is expected so the PrefixKey is created using
applyPrefix