-
Notifications
You must be signed in to change notification settings - Fork 36
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
Specify proof format and verification algorithm #9
Comments
One thing you might be missing is that all nodes have a key and a value, including inner nodes (unlike the golang IAVL tree). This is why we need a separate kvHash for each node, otherwise merkle branches would require key/value data for unrelated nodes in the branch. So unlike many other tree implementations, inner nodes and leaf nodes have the same format, the only difference is that |
Okay, that is interesting. And enlightening. So, for inner nodes, we are guaranteed left and right to be defined. Correct? And we should have {key, value} or kvHash for all (only leaf to be proven must be in {key, value} format)? |
It is also possible to have one be undefined, at the edges of the tree.
That's correct. |
Okay, I made a sample tree state.foo = 'bar';
state.food = 'yummy';
state.bath = {tub: 'full', room: 'small'};
state.baz = { x: 123, y: { z: 456 } }; And got this:
query { left: 'F4j9DF3/N4rBqoX4JYyW9AdvDAo=',
right:
{ left: null, right: null, key: '.baz.y', value: '{"z":456}' },
key: '.baz',
value: '{"x":123}' } query { left:
{ left:
{ left: null,
right: null,
key: '.',
value: '{"foo":"bar","food":"yummy"}' },
right: null,
key: '.bath',
value: '{"room":"small","tub":"full"}' },
right: 'Z7Rs82itYwVwev3PUp0KFDpX9hc=',
kvHash: '2RiU70Z1dYW4CHRnRkzZ2YlqJDI=' } The fact foo and food are in the same leaf is a bit odd. |
FYI, I made a repo https://github.com/confio/proofs-merk to try to parse these out. I would like to figure out how to extend a generic proof format to hold this info: https://github.com/confio/proofs in particular cosmos/ics23#5 Any collaboration and feedback is more than welcome |
It's not an exact spec, but I outlined the new proof format and verification algorithm in this document: https://github.com/nomic-io/merk/blob/develop/docs/algorithms.md |
Thanks, that is quite a nice document of the proof format and verification/generation algorithm. The examples were very useful to understand the use of |
Closing this since that document exists, can open specific issues in the future around any proof format questions. |
I was curious about how to validate proofs exported from merk.js and reading the code, I wasn't entirely sure. For the purpose of this issue, I just care about existence proofs for exactly one value (it seems you return general range proofs by default, maybe simpler to focus on one case).
The code seems to be this: https://github.com/nomic-io/merk/blob/master/src/verify.js#L15-L47
This is my understanding:
A child node contains
{key, value}
(both strings)An inner node contains
{left, right, kvHash}
In the case of serialized proofs, I would assume for every inner node, either left or right is a base64 hash of the subtree, and the other one is a reference to the child node leading to the leaf of interest.
So far, so good. The hash for a leaf node also seems quite simple:
varint length prefix the key and the value, concatenate, then hash. Solid.
But... looking at:
It seems that the hash of a child node is not just
getKvHash
, butgetHash
. Given left and right are both null for the child node. This ends up like:kvhash = ripemd160(sha256(key.length || key || value.length || value))
Then one step that treats it like an inner node
childHash = ripemd160(sha256([0, 0, ... (40 bytes 0)] || kvhash))
The inner node would be:
innerHash = ripemd160(sha256(child.left || child.right || inner.kvhash))
And then what is
inner.kvhash
?I'd love to understand this algorithm well, and be able to validate it in another language (eg. go) as a step towards unifying merkle proofs on the road to ibc
The text was updated successfully, but these errors were encountered: