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

[Fix] deletion proof should be collected in log tracing #247

Closed
wants to merge 4 commits into from

Conversation

noel2004
Copy link
Member

Finding that the deletion proof can not be collected from the initialized trie state for each storage slot being touched in the executed txs. Consider following case:

  1. We have a leaf node A in trie at the beginning
  2. The sibling leaf node of A is deleted, as the result, A is pushed up to a new position in trie and now it has another sibling node (call it U)
  3. A itself is being deleted. For the witness generator side, now it need the information of U to deduce the state root after this deletion. However, if we just collect all deletion proofs at the beginning of this tx. We would have no chance to see U and record it.

In this PR we add deletion proof collection step into log trace. For every SSTORE set a storage slot to 0 (i.e. a deletion occur) we collect the sibling of deleted node right before this step as a deletion proof.

@noel2004 noel2004 marked this pull request as ready for review March 25, 2023 07:49
@noel2004
Copy link
Member Author

L2geth running on this build pass the problemic block discovered from block 624236 while getting block trace.

0xmountaintop
0xmountaintop previously approved these changes Mar 27, 2023
if !bytes.Equal(oldValue.Bytes(), storageValue.Bytes()) &&
bytes.Equal(storageValue.Bytes(), common.Hash{}.Bytes()) {

if delSibling, err := l.env.StateDB.GetDeletetionProof(contractAddress, storageKey); err != nil {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the expected performance impact of this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now we need to do a proof on each deletion (SSTORE a non-zero value to 0). The cost depends while considering the storage trie usually is not very high and deletion is not so common I think the impact should be limited.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, sounds acceptable. We just need to think if this can be triggered maliciously somehow.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. I just recognized that current implement would bring an addition commition on the corresponding storage trie so it may bring significant cost by a series well designed malicious txs in one block.

Lucikly if we should have separated and constrainted the logtrace only work while obtaining block trace, such a attack is mitigated for the cost only raised in any following nodes used for providng block trace.

And I think we can further push the deletion generation process to commiting step, I would start this idea in another PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would trace this problem in #253

eth/tracers/api_blocktrace.go Outdated Show resolved Hide resolved
for _, bt := range deletionProofs {
key := crypto.Keccak256Hash(bt)
env.sMu.Lock()
env.deletionProofAgg[key] = bt

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need the last proof for the same key? Not the first one?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deletionProof is not a full proof but just the bytes of a single node (the sibling of deleted leaf node) so each item is unique. From logtrace we may collect the same node so here we use a map for deduplication.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bytes of a node's value? Or its key? If we delete, reinsert, then delete again, this will work?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is in fact bytes of 'the whole node', i.e. trie can read these bytes as a valid node and add it to the (temporary) database.

Such an entry of node in database is immutable and not affected by insert / updating or deletion. It would just lost any reference from trie when being deleted. So adding any node into database would never break the trie, it just take no use in the worst case.

params/version.go Outdated Show resolved Hide resolved
@noel2004
Copy link
Member Author

noel2004 commented Apr 1, 2023

With additional discussion. We plan to use another patch instead of current one and may be discussed in issue #253 first

@noel2004
Copy link
Member Author

noel2004 commented Apr 7, 2023

Now it is replaced by PR #263

@noel2004 noel2004 closed this Apr 7, 2023
@0xmountaintop 0xmountaintop deleted the fix/deletion_proof branch April 10, 2023 12:32
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.

3 participants