Fix verify_proof host functions for Substrate compact proofs#2250
Closed
x3c41a wants to merge 1 commit into
Closed
Fix verify_proof host functions for Substrate compact proofs#2250x3c41a wants to merge 1 commit into
x3c41a wants to merge 1 commit into
Conversation
The implementation added in paritytech#2221 used trie::proof_decode::decode_and_verify_proof, which expects regular Merkle proofs where every node is fully encoded and looked up by its blake2b hash. Substrate generates compact proofs via sp_trie::generate_trie_proof (trie-db's generate_proof): along the proven path, child references are replaced by an empty inline placeholder and the actual child nodes follow as the next proof entries. At the target leaf the value is also omitted and reconstructed from the caller-supplied expected_value (hashed if state version V1 and >= 32 bytes). This commit adds verify_compact_trie_proof in trie::proof_decode and wires ext_trie_blake2_256_verify_proof_version_{1,2} to it. The verifier walks proof entries in order, descends into placeholders by consuming the next entry, and unwinds by re-encoding each node with reconstructed children. The final root node's blake2b hash must equal the expected root. Verified against paseo-bulletin-rpc.polkadot.io: replaying five blocks that emit transactionStorage.ProofChecked (1503870, 1504069, 1504256, 1504290, 1504307, 1504375) through chopsticks run-block now completes finalize_block without panicking on the "Storage proof must be checked once in the block" assertion.
Contributor
Author
|
Closing — re-opening against the active upstream paritytech/smoldot, which is where new development happens. This repo (smoldot-archive) is the older fork and chopsticks pulls from it via the smol-dot/smoldot redirect, but the host function fix should land in the active fork first. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the implementation of
ext_trie_blake2_256_verify_proof_version_1and_version_2added in #2221. That PR usedproof_decode::decode_and_verify_proof, which expects regular Merkle proofs where every node is fully encoded and looked up by its blake2b hash. Substrate generates compact proofs viasp_trie::generate_trie_proof(trie-db'sgenerate_proof): along the proven path, child references are replaced by an empty inline placeholder and the actual child nodes follow as the next proof entries; the target leaf's value is also omitted and reconstructed from the caller-supplied expected value (hashed if state version V1 and >= 32 bytes).What this PR does
Adds
verify_compact_trie_proofintrie::proof_decodeand wires the two host functions to it. The verifier:UnhashedorHashed(blake2b(value))based on state version and value length).Tests
Seven unit tests in
trie::proof_decode::testscover the verifier using proof bytes captured live from paseo-bulletin-rpc.polkadot.io block #1503870 (a 256-byte chunk-trie proof from pallet-transaction-storage'sapply_block_inherents):verify_compact_proof_accepts_valid_substrate_proof— positive case.verify_compact_proof_rejects_wrong_root— flipping a bit in the root.verify_compact_proof_rejects_wrong_value— flipping a bit in the value.verify_compact_proof_rejects_wrong_key— different key.verify_compact_proof_rejects_wrong_state_version— V0 instead of V1.verify_compact_proof_rejects_tampered_proof_byte— corrupted byte inside the root node entry.verify_compact_proof_rejects_truncated_proof— missing the leaf entry.End-to-end, replaying five real ProofChecked-emitting blocks (1503870, 1504069, 1504256, 1504290, 1504307, 1504375) through chopsticks
run-blockagainst paseo-bulletin now completesfinalize_blockwithout panicking on theStorage proof must be checked once in the blockassertion. Previously, with #2221's implementation, all of them panicked.Ref: paritytech/polkadot-bulletin-chain#341