Skip to content
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

statemine proof_decode fails #1362

Closed

Conversation

ermalkaleci
Copy link
Contributor

We use decode_proof on chopsticks to decode current validation data, modify storage value and create new proof for the new block. This method worked fine and still works with current statemine but 3 days ago it failed. This is a test with proof nodes from block 5,800,000 which fails and one with recent block which works fine. Any idea why it fails and if it can happen again?

@tomaka
Copy link
Contributor

tomaka commented Nov 19, 2023

Since a proof can contain multiple trie roots (main trie and child tries), the proof decoding code takes all the nodes that are decodable, then removes the ones that are children of another proof entry. The ones that remain are considered as trie roots.

Storage values are also proof entries, but usually they aren't decodable and so they are discarded.
However, here, entry e80300000090010000900100000000000000000001d198d83e299dc6445b36551102a4b2eaa47abacd3b0657b5b1e498475cd9dd2b005039278c0400000000000000000000005039278c0400000000000000000000 happens to be a decodable storage value. It is decodable, but its children aren't, hence the error.

I did it this way in order to avoid having to hardcode in the proof decoding code the child tries prefix (:child_trie:default:). If that entry was the storage value of a key that starts with :child_trie:default:, then the error would be legitimate.

@tomaka
Copy link
Contributor

tomaka commented Nov 19, 2023

This is a situation that can now happen as a result of the trie V1 format. It wasn't a problem when I wrote the code, and then later I didn't think about this.

There are two different ways of fixing this:

  • Hardcode the child trie prefix in the proof decoding.
  • Treat errors as non-fatal unless all the trie nodes in the proof are invalid.

I think I would go for the latter.

@ermalkaleci
Copy link
Contributor Author

Since a proof can contain multiple trie roots (main trie and child tries), the proof decoding code takes all the nodes that are decodable, then removes the ones that are children of another proof entry. The ones that remain are considered as trie roots.

Storage values are also proof entries, but usually they aren't decodable and so they are discarded. However, here, entry e80300000090010000900100000000000000000001d198d83e299dc6445b36551102a4b2eaa47abacd3b0657b5b1e498475cd9dd2b005039278c0400000000000000000000005039278c0400000000000000000000 happens to be a decodable storage value. It is decodable, but its children aren't, hence the error.

I did it this way in order to avoid having to hardcode in the proof decoding code the child tries prefix (:child_trie:default:). If that entry was the storage value of a key that starts with :child_trie:default:, then the error would be legitimate.

I did a little digging but didn't understand why there were 2 root hashes, now it makes sense

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants