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

Trie proof API refactor #2949

Merged
merged 38 commits into from
Jan 30, 2024
Merged

Trie proof API refactor #2949

merged 38 commits into from
Jan 30, 2024

Conversation

ScottyPoi
Copy link
Contributor

@ScottyPoi ScottyPoi commented Aug 9, 2023

This PR improves upon the proof methods in the Trie library.

The Trie methods fromProof and verifyProof require a new Trie object to be instantiated by the user simply for the purpose of calling the methods. This can be confusing, and seems unnecessarily indirect.

With static versions of the same methods, users can now accomplish these tasks in one step.

  1. Trie.fromProof
  • Works just like trie.fromProof, with an additional opts parameter to pass in keyHashing settings.

Now instead of:

const trie = new Trie(opts)
await trie.fromProof(proof)

We can just do:

const trie = await Trie.fromProof(proof, opts)
  1. Trie.verifyProof
  • Works just like trie.verifyProof, with an additional opts parameter to pass in keyHashing settings.
  • Does not require the rootHash parameter as expected by class method.

Now instead of:

const trie = new Trie(opts)
const val = trie.verifyProof(trie.root(), key, proof, opts)

We can just do:

const val = Trie.verifyProof(key, proof, opts)

@codecov
Copy link

codecov bot commented Aug 9, 2023

Codecov Report

Attention: 21 lines in your changes are missing coverage. Please review.

Comparison is base (6ca6fd5) 86.01% compared to head (7404c04) 87.86%.

Additional details and impacted files

Impacted file tree graph

Flag Coverage Δ
block 88.57% <ø> (ø)
blockchain 91.60% <ø> (ø)
client 84.56% <ø> (+0.03%) ⬆️
common 98.26% <ø> (ø)
devp2p 82.12% <ø> (?)
ethash ∅ <ø> (∅)
evm 76.92% <ø> (ø)
genesis 99.98% <ø> (?)
rlp ∅ <ø> (∅)
statemanager 86.56% <100.00%> (-0.01%) ⬇️
trie 89.13% <76.92%> (-0.59%) ⬇️
tx 95.89% <ø> (ø)
util 89.13% <ø> (ø)
vm 80.26% <ø> (ø)
wallet 88.35% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

@ScottyPoi ScottyPoi marked this pull request as ready for review August 9, 2023 10:18
@scorbajio
Copy link
Contributor

Linking #2927

Copy link
Member

@jochem-brouwer jochem-brouwer left a comment

Choose a reason for hiding this comment

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

I'm not sure if we want to make fromProof static

@@ -113,6 +113,50 @@ export class Trie {
return new Trie(opts)
}

static async fromProof(proof: Proof, opts?: TrieOpts): Promise<Trie> {
Copy link
Member

Choose a reason for hiding this comment

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

What if I want to import two proofs? Or, I want to import a new proof in my trie later? This is now not possible anymore, right?

Copy link
Member

Choose a reason for hiding this comment

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

Ok, let's bring this back to the drawing board and first decide if this is a change we want respectively which makes sense and is thought through to the end.

Copy link
Member

Choose a reason for hiding this comment

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

Will give this a "blocked" label for now.

Copy link
Member

Choose a reason for hiding this comment

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

(this change (i.e. make fromProof static) does not seem to be referred in the linked issue)

Copy link
Contributor

@scorbajio scorbajio Aug 9, 2023

Choose a reason for hiding this comment

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

What if I want to import two proofs? Or, I want to import a new proof in my trie later? This is now not possible anymore, right?

It seems like these tasks are possible with the new updateFromProof function.

Copy link
Member

Choose a reason for hiding this comment

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

Ah yes you are right, I somehow missed that.

Copy link
Member

Choose a reason for hiding this comment

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

Feel free to "unblock" this again or course of you guys think you've gotten answers for most of the questions here and things can be introduced in a non breaking way, you guys have a lot better overview than me here what's useful and makes sense regarding all this proof stuff!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, updateFromProof is just the old fromProof with the word update tagged on to distinguish from the other. To avoid actual breaking changes, we could instead use createFromProof for the static method, and leave fromProof as it was.

Copy link
Member

Choose a reason for hiding this comment

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

We now have #3186. I think we want to make the methods static in some cases? (But this is breaking)

Copy link
Contributor

@scorbajio scorbajio Jan 3, 2024

Choose a reason for hiding this comment

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

Yes, the goal is to have a static version of verifyProof so that a new trie instantiation isn't needed for each proof verification, or the less-than-ideal proofTrie pattern where we keep a trie around in both the statemanager and snap sync fetchers to perform proof verification.

The changes for #3186 are included, so we should have a static and non-static version of verifyProof and fromProof. This shouldn't be breaking? Since users can just use the previously available non-static versions if they chose to.

async fromProof(proof: Proof): Promise<void> {

async updateFromProof(proof: Proof): Promise<void> {
if (!equalsBytes(this.root(), this.hash(proof.shift()!))) {
Copy link
Member

Choose a reason for hiding this comment

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

I am not sure if I like this check, have to think about the practical downsides of this 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you try to update a sparse trie with an invalid proof, this will throw.
shift() because the root node is already in the trie, so we'll never need to add it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🤔 I'd have to hear the upside to allowing a trie to update itself from a proof to a different trie!

packages/statemanager/src/stateManager.ts Outdated Show resolved Hide resolved
packages/trie/src/trie.ts Show resolved Hide resolved
@ScottyPoi
Copy link
Contributor Author

Should be non-breaking now 🥚

Copy link
Member

@jochem-brouwer jochem-brouwer left a comment

Choose a reason for hiding this comment

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

I am not entirely sure about the state of this PR. We now have #3186, it seems that if we want this in this seems to be merely marking some methods as static? (Note: we should make this non-breaking, so it should both be static and non-static). I will remove the blocked label until we resolve what we want with this PR. (I think the gist is to make the methods static which should have been static in the first place? 🤔 )

Copy link
Member

Choose a reason for hiding this comment

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

Random changes in this file?

Copy link
Contributor

Choose a reason for hiding this comment

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

Must have been from one of the merges. I fixed it so it's just the single extra space removed and any other unnecessary changes excluded.

packages/client/test/testdata/blocks/kaustinen2.json Outdated Show resolved Hide resolved
packages/statemanager/src/rpcStateManager.ts Outdated Show resolved Hide resolved
@@ -113,6 +113,50 @@ export class Trie {
return new Trie(opts)
}

static async fromProof(proof: Proof, opts?: TrieOpts): Promise<Trie> {
Copy link
Member

Choose a reason for hiding this comment

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

We now have #3186. I think we want to make the methods static in some cases? (But this is breaking)

@holgerd77
Copy link
Member

I will remove the blocked label until we resolve what we want with this PR

@jochem-brouwer I assume that you intended to write "I will not remove..." if not otherwise stated since that would make more sense 🙂

@scorbajio don't know, are you getting along with the things we get from #3186 ? If so, @jochem-brouwer: would you then recommend to close this PR and rather not merge?

@jochem-brouwer
Copy link
Member

Yes indeed I did intend to write: I will not remove :)

I think that this PR can be updated with the changes of #3186, but I think we should update this PR to also include small changes such as also making verifyProof static (besides keeping it non-static, because otherwise it is breaking). So that would change this PR to a few lines of changes.

( @holgerd77 I think you intended to ping @ScottyPoi in your last post)

@holgerd77
Copy link
Member

@jochem-brouwer 👍

Ah, no, I indeed intended to mention @scorbajio since he requested this work to be updated and reviewed for some other follow up work.

Copy link
Contributor

@scorbajio scorbajio left a comment

Choose a reason for hiding this comment

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

LGTM!

Copy link
Member

@jochem-brouwer jochem-brouwer left a comment

Choose a reason for hiding this comment

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

Two nits @scorbajio

keys[keys.length - 1],
keys,
values,
<any>proof,
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to this?

Copy link
Member

Choose a reason for hiding this comment

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

Oh wait, it is client, I think this is beyond the scope of this PR (should do a client type cleanup at some point)

Copy link
Contributor

@scorbajio scorbajio Jan 20, 2024

Choose a reason for hiding this comment

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

Good point. I've reverted it for now. Will make the cleanup in a followup PR.

packages/client/test/net/protocol/snapprotocol.spec.ts Outdated Show resolved Hide resolved
packages/trie/src/trie.ts Show resolved Hide resolved
await trie._db.batch(opStack)
trie.root(trie.hash(proof[0]))
await trie.persistRoot()
return trie
Copy link
Member

Choose a reason for hiding this comment

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

I think this one needs to be checked @scorbajio

@holgerd77
Copy link
Member

Updated this via UI

I think we can take this in after having done a rough review? Will wait for a confirmation from @jochem-brouwer though (then optimally directly merge).

Copy link
Member

@jochem-brouwer jochem-brouwer left a comment

Choose a reason for hiding this comment

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

Resolved merge conflicts and fixed the example. LGTM (assuming CI passes, will directly merge)

@jochem-brouwer jochem-brouwer merged commit 5be55b2 into master Jan 30, 2024
45 of 46 checks passed
@holgerd77 holgerd77 deleted the trie-proof-api branch January 30, 2024 08:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants