-
Notifications
You must be signed in to change notification settings - Fork 69
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
Introduce module in trie-db for generating/verifying trie proofs. #45
Conversation
Is there a plan to expose this API in |
There was paritytech/substrate#4938 , not sure how I will attempt to resume work on it (I recently updated the branch though, but I am also considering different approach to integrate it) |
I wrote a solidity version of the verification. I am working on the storage proof of substrate, Could you give me the specification of substrate's storage. Thanks! |
https://github.com/w3f/polkadot-spec/blob/master/host-spec/c02-state.tm (https://github.com/w3f/polkadot-spec/releases) gives you the basis for the trie state encoding. (maybe reading gossamer or kogame implementation can be interesting (different language and code base so can be easier for some)). For compact proof, it is the same thing except nodes needs to be ordered in a specific way and useless encoded hashes are replaced by encoding of a 0 length inline node ( trie/trie-db/src/trie_codec.rs Line 144 in f054631
Useless encoded hash are those that can be recalculated when rebuilding the trie (any child hash that point to a node that is already in the proof). There is also a variant of compact proof where we want to check if a set of storage values did change, and where we also omit writing the value in the encoded nodes (basically code in https://github.com/paritytech/trie/tree/master/trie-db/src/proof). But mostly I don't think there is written spec of those compact proof except code documentation. |
Trie node encoding specificationNote that for the following definitions, Branch encoding: Leaf encoding: This is the trie node specification, I found it in gossamer and https://github.com/w3f/polkadot-spec/blob/master/host-spec/c02-state.tm
|
At trie node level it is the same (compact uses 'empty inline node' which is impossible as a way to add information without changing the encoding). Then at proof level: One other tiny difference is that for compact proof you cannot have a single proof with nodes from different tries, so in case of child trie used by the proof, compact will need a different encoded where the proof is split by trie (in the PR I did, this was named Full when Flat was a single trie proof).
The set of nodes is put in a hashmap with key being the encoded node hash. So if we check a single key access, then we start from root, fetch the encoded root node from the hashmap, decode it, get the child hash for this key, fetch the child encoded node, decode it, repeat In https://github.com/paritytech/substrate/blob/f7a8b1001d1819b7a887ae36d6beae84617499d8/primitives/state-machine/src/lib.rs#L816 |
I implemented a solidity version of the two verification. Welcome advice~
|
Amazing 👍 |
It is a good advice, but mappings can only be stored in the storage data location. I will test mapping in the storage maybe cheaper. |
Oh, sounds bad, probably will need to keep array hashes for refund, but still I remember storage ops being so much more expensive. Not sure testing is worth it :) |
Generation and verification of compact proofs for Merkle-Patricia tries. These have the benefit over the compact trie encoding of omitting the values from the proof data. Apart from being a more standard logical separation for a proof interface, this can result in bandwidth savings if the verifier already has the values. For example, they may request a proof that a value at a key is the same as it is with respect to another trie root.
Using this module, it is possible to generate a logarithmic-space proof of inclusion or non-inclusion of certain key-value pairs in a trie with a known root. The proof contains information so that the verifier can reconstruct the subset of nodes in the trie required to lookup the keys. The trie nodes are not included in their entirety as data which the verifier can compute for themself is omitted. In particular, the values of included keys and and hashes of other trie nodes in the proof are omitted.
The proof is a sequence of the subset of nodes in the trie traversed while performing lookups on all keys. The trie nodes are listed in pre-order traversal order with some values and internal hashes omitted. In particular, values on leaf nodes, child references on extension nodes, values on branch nodes corresponding to a key in the statement, and child references on branch nodes corresponding to another node in the proof are all omitted. The proof is verified by iteratively reconstructing the trie nodes using the values proving as part of the statement and the hashes of other reconstructed nodes. Since the nodes in the proof are arranged in pre-order traversal order, the construction can be done efficiently using a stack.
Fixes paritytech/substrate#3782.