-
Notifications
You must be signed in to change notification settings - Fork 955
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
Non-existence proof verification failed #92
Comments
The proof and the verification work well, however, sparse-merkle-tree(SMT) isn't compatible with the current IBC integration. We need to replace the Merkle tree implementation. The problem is that the non-existence proof-verification requires a different proof spec from that of the existence proof verification.
LeafOp {
hash: H::hash_op().into(),
prehash_key: H::hash_op().into(),
prehash_value: H::hash_op().into(),
length: LengthOp::NoPrefix.into(),
prefix: H256::zero().as_slice().to_vec(),
}
LeafOp {
hash: hash_op.into(),
prehash_key: HashOp::NoHash.into(),
prehash_value: HashOp::NoHash.into(),
length: LengthOp::NoPrefix.into(),
prefix: H256::zero().as_slice().to_vec(),
} The non-existence proof needs a different proof spec because sparse-merkle-tree (SMT) returns the proof with the hashed key and value of neighbors in SMT. For the existence proof, we can replace the key and value in the proof generated by SMT with a non-hashed(original) key and value to verify it with ICS23 verification which checks if the key and value are equal to the target key and value. So, the proof spec's pub struct ExistenceProof {
#[prost(bytes = "vec", tag = "1")]
pub key: ::prost::alloc::vec::Vec<u8>,
#[prost(bytes = "vec", tag = "2")]
pub value: ::prost::alloc::vec::Vec<u8>,
#[prost(message, optional, tag = "3")]
pub leaf: ::core::option::Option<LeafOp>,
#[prost(message, repeated, tag = "4")]
pub path: ::prost::alloc::vec::Vec<InnerOp>,
}
We want to replace the hashed key and value for the non-existence proof, but we cannot. That's because they are hashed and we don't know the original key and value of the neighbors (we know only the target key at that time). pub struct NonExistenceProof {
#[prost(bytes = "vec", tag = "1")]
pub key: ::prost::alloc::vec::Vec<u8>,
#[prost(message, optional, tag = "2")]
pub left: ::core::option::Option<ExistenceProof>,
#[prost(message, optional, tag = "3")]
pub right: ::core::option::Option<ExistenceProof>,
} I tried to modify SMT to have the original key and value in each leaf and to get the proof with them. But ICS23 refused the proof. ICS23 verification checks also the key order for the non-existence proof. The original keys order is not the same as hashed keys' order in the tree. That's why it failed. |
Returns specifically the non-existence-proof with the hashed key and value of neighbors?
Hmm, we must be storing the key and value of the neighbors in the tree somewhere, right? Can we look them up in order to produce the proofs?
Hmm, I don't quite follow - if you have the original key and value in each leaf, why would the key order be different? Are some intermediate values still being hashed an extra time, compared to what ICS23 expects? |
@cwgoes Thank you for your comments!
non-existence-proof consists of existence-proofs of
Yes, I could store a non-hashed key-value pair as
The key order in SMT is arranged with the hashed keys. However, ICS23 checks the order with the given key. When the given key is non-hashed (in the case of IBC), the order isn't the same as hashed keys' order, e.g. the hashed key of the left should be smaller than the hashed given key in SMT, but the non-hashed key of the left might be larger than the given key. |
We can verify the non-existence proof with another proof spec because the left or right leaf's key and value are hashed in Sparse Merkle Tree.
However, we cannot switch the proof spec in the IBC client module. The proof spec is used for both the existence and non-existence proof verification.
The text was updated successfully, but these errors were encountered: