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: allow trie put/del ops to skip transforming key for snapsync #2950

Merged
merged 9 commits into from
Aug 13, 2023

Conversation

g11tech
Copy link
Contributor

@g11tech g11tech commented Aug 9, 2023

Snap sync requires building the MPT from the peer tree where key is already hashed. This PR allows trie put/del opts to skip key transform even if trie is set with useKeyHashing. This allows to correctly build the MPT and correctly map addresse lookups to the trie

TODO:

  • add some account lookups in the test to validate trie is build correctly
  • add unit cases for trie

@g11tech g11tech changed the title trie: allow trie put/del ops to skip transforming key trie: allow trie put/del ops to skip transforming key for snapsync Aug 9, 2023
@codecov
Copy link

codecov bot commented Aug 9, 2023

Codecov Report

Merging #2950 (6b6a8be) into master (1f73936) will increase coverage by 0.01%.
The diff coverage is 76.66%.

Additional details and impacted files

Impacted file tree graph

Flag Coverage Δ
block 88.66% <ø> (ø)
blockchain 92.58% <ø> (ø)
client 87.52% <71.42%> (-0.03%) ⬇️
common 98.65% <ø> (ø)
ethash ?
evm 70.43% <ø> (ø)
rlp ∅ <ø> (∅)
statemanager 82.98% <ø> (ø)
trie 89.89% <85.71%> (+0.35%) ⬆️
tx 95.88% <ø> (ø)
util 86.78% <100.00%> (+<0.01%) ⬆️
vm 79.20% <ø> (ø)

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

@g11tech g11tech force-pushed the trie-ops-skipkeytransform branch from 84e9e00 to f23310a Compare August 9, 2023 13:42
@g11tech g11tech force-pushed the trie-ops-skipkeytransform branch from 751eec4 to f313f8a Compare August 9, 2023 15:02
@g11tech
Copy link
Contributor Author

g11tech commented Aug 10, 2023

coverage for snap related fetchers will increase as we do followup PRs for integration

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.

This is looking great! One of the tests fail at the end, seemingly due to a missing account:

 FAIL  test/sim/snapsync.spec.ts > simple mainnet test run > should match entire state
TypeError: Cannot read properties of undefined (reading 'balance')
 ❯ test/sim/snapsync.spec.ts:201:17
    199|       console.log(addressString)
    200|       assert.equal(
    201|         account.balance,
       |                 ^
    202|         BigInt(customGenesisState[addressString][0]),
    203|         `${addressString} balance should match`

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯

 Test Files  1 failed (1)
      Tests  1 failed | 3 passed | 1 skipped (5)
   Start at  13:59:28
   Duration  63.49s (transform 1.97s, setup 0ms, collect 43.23s, tests 19.60s, environment 0ms, prepare 213ms)

But since the roots match, I suspect it's not an issue with the fetchers. Does the test also fail for you when you run the sim test suit locally?

@g11tech
Copy link
Contributor Author

g11tech commented Aug 11, 2023

But since the roots match, I suspect it's not an issue with the fetchers. Does the test also fail for you when you run the sim test suit locally?

hey no, all tests pass for me... let me do some variations of the cmd, might be an edge case somewhere

@@ -376,7 +384,8 @@ export class AccountFetcher extends Fetcher<JobTask, AccountData[], AccountData>
const storageFetchRequests = new Set()
const byteCodeFetchRequests = new Set<Uint8Array>()
for (const account of result) {
await this.accountTrie.put(account.hash, accountBodyToRLP(account.body))
// what we have is hashed account and not its pre-image, so we skipKeyTransform
await this.accountTrie.put(account.hash, accountBodyToRLP(account.body), true)
Copy link
Contributor

@ScottyPoi ScottyPoi Aug 12, 2023

Choose a reason for hiding this comment

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

Does account.hash = keccak(accountBodyToRLP(account.body)) ?

If I understand this correctly, we would end up with a Trie where:

accountTrie.get(accountBodyToRLP(account.body)) = accountBodyToRLP(account.body)

Copy link
Contributor Author

@g11tech g11tech Aug 12, 2023

Choose a reason for hiding this comment

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

i think you got the keyvalue pair mixed up, first is key which is already hashed account lookup key second is value

Copy link
Contributor

@scorbajio scorbajio Aug 13, 2023

Choose a reason for hiding this comment

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

@ScottyPoi to my knowledge, the second one should be accountTrie.get(account.hash) = accountBodyToRLP(account.body) where account.hash is the keccak256 hash of the account address that is derived from the public key of the account's corresponding private key (and can be looked up by walking the account trie and concatenating the key nibbles). The account hash is not derived from the account body.

Copy link
Contributor

Choose a reason for hiding this comment

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

sweet, that makes perfect sense. I was worried that we were mixing up the account address with the DB Key, that's all.

LGTM, 👍

Copy link
Contributor

Choose a reason for hiding this comment

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

So we're setting up a Trie where the key used for put and del is different than the key used for get?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

correct because in snap sync we already get hashed key in the AccountData for e.g. (account.hash for e.g.)

Copy link
Contributor

Choose a reason for hiding this comment

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

We are putting by post-image (and skipping the hashing from pre to post-image) and reading by pre-image, which would be the account address.

@g11tech
Copy link
Contributor Author

g11tech commented Aug 12, 2023

This is looking great! One of the tests fail at the end, seemingly due to a missing account:

 FAIL  test/sim/snapsync.spec.ts > simple mainnet test run > should match entire state
TypeError: Cannot read properties of undefined (reading 'balance')
 ❯ test/sim/snapsync.spec.ts:201:17
    199|       console.log(addressString)
    200|       assert.equal(
    201|         account.balance,
       |                 ^
    202|         BigInt(customGenesisState[addressString][0]),
    203|         `${addressString} balance should match`

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯

 Test Files  1 failed (1)
      Tests  1 failed | 3 passed | 1 skipped (5)
   Start at  13:59:28
   Duration  63.49s (transform 1.97s, setup 0ms, collect 43.23s, tests 19.60s, environment 0ms, prepare 213ms)

But since the roots match, I suspect it's not an issue with the fetchers. Does the test also fail for you when you run the sim test suit locally?

i fixed the edge case, thanks for spotting it 🙂

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.

ACK

@scorbajio scorbajio merged commit 125a696 into master Aug 13, 2023
@holgerd77 holgerd77 deleted the trie-ops-skipkeytransform branch August 14, 2023 09:23
@scorbajio scorbajio mentioned this pull request Aug 17, 2023
9 tasks
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