-
Notifications
You must be signed in to change notification settings - Fork 411
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 1 commit
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 | ||||
---|---|---|---|---|---|---|
|
@@ -262,18 +262,20 @@ func GenerateClientStateProofs(chains []*Chain) []*ProofData { | |||||
|
||||||
The following outlines the general proof verification steps specific to a multi-hop IBC message. | ||||||
|
||||||
1. Unpack the multihop proof bytes into consensus, connection, and channel/commitment proof data. | ||||||
2. Iterate through connection proof data and verify each connectionEnd is in the OPEN state. Check connectionHops during channel handshake. | ||||||
3. Iterate through each clientState and verify the status is active and the clientID matches the clientID for the corresponding consensusState. | ||||||
4. Starting with known `ConsensusState[N-1]` at the given `proofHeight` on `ChainN` prove the prior chain's consensus, clientState, and connection state. | ||||||
5. Repeat step 3, proving `ConsensusState[i-1]`, `ClientState[i-1]`, and `Conn[i-1,i]` until `ConsensusState[0]` on the source chain is proven. | ||||||
1. Unpack the multihop proof bytes into consensus states, connection states, client states and channel/commitment proof data. | ||||||
2. Check the counterparty client on the receiving end is active and the client height is greater than or equal to the proof height. | ||||||
3. Iterate through the connections states to determine the maximum delayPeriod for the channel path and verify that the counterparty consensus state on the receiving chain satisfies the delay requirement. | ||||||
4. Iterate through connection state proofs and verify each connectionEnd is in the OPEN state and check that the connection ids match the channel connectionHops. | ||||||
5. Iterate through each client state and verify that no clients are frozen and the clientID matches the clientID for the corresponding consensus state. | ||||||
6. Verify the intermediate state proofs. Starting with known `ConsensusState[N-1]` at the given `proofHeight` on `ChainN` prove the prior chain's consensus, clientState, and connection state. | ||||||
7. Repeat step 3, proving `ConsensusState[i-1]`, `ClientState[i-1]`, and `Conn[i-1,i]` until `ConsensusState[0]` on the source chain is proven. | ||||||
- Start with i = N-1 | ||||||
- ConsensusState <= ConsensusState[i-1] on Chain[i] | ||||||
- ConsensusProofs[i].Proof.VerifyMembership(ConsensusState.GetRoot(), ConsensusProofs[i].Key, ConsensusProofs[i].Value) | ||||||
- ConnectionProofs[i].Proof.VerifyMembership(ConsensusState.GetRoot(), ConnectionProofs[i].Key, ConnectionProofs[i].Value) | ||||||
- ClientStateProofs[i].Proof.VerifyMembership(ConsensusState.GetRoot(), ClientStateProofs[i].Key, ClientStateProofs[i].Value) | ||||||
- Set ConsensusState from unmarshalled ConsensusProofs[i].Value | ||||||
6. Finally, prove the expected channel or packet commitment in `ConsensusState[0]` | ||||||
8. Finally, prove the expected channel or packet commitment in `ConsensusState[0]` | ||||||
|
||||||
For more details see [ICS4](https://github.com/cosmos/ibc/tree/main/spec/core/ics-004-channel-and-packet-semantics). | ||||||
|
||||||
|
@@ -300,16 +302,21 @@ func VerifyMultihopProof( | |||||
// deserialize proof bytes into multihop proofs | ||||||
proofs := abortTransactionUnless(Unmarshal(proof)) | ||||||
abortTransactionUnless(len(proofs.ConsensusProofs) >= 1) | ||||||
abortTransactionUnless(len(proofs.ConnectionProofs) >= 1) | ||||||
abortTransactionUnless(len(proofs.ClientProofs) >= 1) | ||||||
abortTransactionUnless(len(proofs.ConnectionProofs) == len(proofs.ConsensusProofs)) | ||||||
|
||||||
// verify connection states and ordering | ||||||
abortTransactionUnless(VerifyConnectionStates(proofs.ConnectionProofs, connectionHops)) | ||||||
|
||||||
// verify intermediate consensus and connection states from destination --> source | ||||||
abortTransactionUnless(VerifyMultiHopConsensusAndConnectionStateProofs(consensusState, proofs.ConsensusProofs, proofs.ConnectionProofs)) | ||||||
// verify client states are not frozen | ||||||
abortTransactionUnless(VerifyClientStates(proofs.ClientStates)) | ||||||
|
||||||
// verify the keyproof on source chain's consensus state. | ||||||
abortTransactionUnless(VerifyMultiHopKeyProof(proofs, prefix, key, value)) | ||||||
// verify intermediate consensus, connection, and client states from destination --> source | ||||||
abortTransactionUnless(VerifyIntermediateStateProofs(consensusState, proofs.ConsensusProofs, proofs.ConnectionProofs, proofs.ClientProofs)) | ||||||
|
||||||
// verify a key/value proof on source chain's consensus state. | ||||||
abortTransactionUnless(VerifyKeyValueProof(proofs, prefix, key, value)) | ||||||
} | ||||||
|
||||||
// VerifyConnectionStates checks that each connection in the multihop proof is OPEN and matches the connections in connectionHops. | ||||||
|
@@ -331,18 +338,29 @@ func VerifyConnectionStates( | |||||
} | ||||||
} | ||||||
|
||||||
// VerifyMultiHopConsensusAndConnectionStateProofs verifies the state of each intermediate consensus and | ||||||
// connection state starting from chain[N-1] on the destination (chain[N]) and finally proving the source | ||||||
// chain consensus and connection state. | ||||||
func VerifyMultiHopConsensusAndConnectionStateProofs( | ||||||
// Verify ClientStates checks that each client in the proof chain is not frozen. | ||||||
func VerifyClientStates( | ||||||
clientStateProofs []*MultihopProof, | ||||||
) { | ||||||
for i, data := range clientStateProofs { | ||||||
clientState := abortTransactionUnless(Unmarshal(data.Value)) | ||||||
abortTransactionUnless(clientState.CheckFrozen() == false) | ||||||
} | ||||||
} | ||||||
|
||||||
// VerifyIntermediateStateProofs verifies the state of each intermediate consensus, connection, and | ||||||
// client state starting from chain[N-1] on the destination (chain[N]) and finally proving the source | ||||||
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.
Suggested change
|
||||||
// chain consensus, connection, and client state. | ||||||
func VerifyIntermediateStateProofs( | ||||||
consensusState exported.ConsensusState, | ||||||
consensusProofs []*MultihopProof, | ||||||
connectionProofs []*MultihopProof, | ||||||
clientProofs []*MultihopProof, | ||||||
) { | ||||||
// reverse iterate through proofs to prove from destination to source | ||||||
for i := len(consensusProofs) - 1; i >= 0; i-- { | ||||||
|
||||||
// prove the consensus state of chain[i] in chain[i+1] | ||||||
// prove the consensus state of chain[i] on chain[i+1] | ||||||
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.
Suggested change
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. made this chain[i] on chain[i-1] to match surrounding proof indexing |
||||||
consensusProof := abortTransactionUnless(Unmarshal(consensusProofs[i].Proof)) | ||||||
abortTransactionUnless(consensusProof.VerifyMembership( | ||||||
commitmenttypes.GetSDKSpecs(), | ||||||
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. One question: 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. Yeah currently it is assuming proof specs are equal. 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. imo this is a very important point and we should make it very clear in the spec. |
||||||
|
@@ -351,7 +369,7 @@ func VerifyMultiHopConsensusAndConnectionStateProofs( | |||||
consensusProof.Value, | ||||||
)) | ||||||
|
||||||
// prove the connection state of chain[i] in chain[i+1] | ||||||
// prove the connection state of chain[i] on chain[i+1] | ||||||
connectionProof := abortTransactionUnless(Unmarshal(connectionProofs[i].Proof)) | ||||||
abortTransactionUnless(connectionProof.VerifyMembership( | ||||||
commitmenttypes.GetSDKSpecs(), | ||||||
|
@@ -360,13 +378,23 @@ func VerifyMultiHopConsensusAndConnectionStateProofs( | |||||
connectionProof.Value, | ||||||
)) | ||||||
|
||||||
// prove the client state of chain[i] on chain[i+1] | ||||||
clientProof := abortTransactionUnless(Unmarshal(clientProofs[i].Proof)) | ||||||
abortTransactionUnless(clientProof.VerifyMembership( | ||||||
commitmenttypes.GetSDKSpecs(), | ||||||
consensusState.GetRoot(), | ||||||
*clientProof.PrefixedKey, | ||||||
clientProof.Value, | ||||||
)) | ||||||
|
||||||
|
||||||
// update the consensusState to chain[i] to prove the next consensus/connection states | ||||||
consensusState = abortTransactionUnless(UnmarshalInterface(consensusProof.Value)) | ||||||
} | ||||||
} | ||||||
|
||||||
// VerifyMultiHopKeyProof verifies a key in the source chain consensus state. | ||||||
func VerifyMultiHopKeyProof( | ||||||
// VerifyKeyValueProof verifies a key in the source chain consensus state. | ||||||
func VerifyKeyValueProof( | ||||||
proofs *MsgMultihopProof, | ||||||
prefix exported.Prefix, | ||||||
key string, | ||||||
|
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.
Since we have access to all the intermediate consensus states, we should definitely check that the timestamp in the consensus state is still within the trusting period of the final client. This way we can ensure we are using fresh state