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

overlay transition #198

Closed
wants to merge 1 commit into from
Closed

Conversation

gballet
Copy link
Owner

@gballet gballet commented Apr 21, 2023

Implement the general structure of the overlay transition from an EL client point of view. The details of the optimization and insertion in the tree are left to ethereum/go-verkle#314.

TL;DR; This creates a series of "adapter" patterns that, based on context, will forward requests either to the verkle (overlay) backend, or to the base (MPT) backend.

For example, this implements a TransitionTrie that implements the state.Trie interface. When (*TransitionTrie).TryGet is called, it will try to read from the verkle tree, and if no value is found there, it will search the MPT.

NOTE This is just the general structure, it compiles but probably won't work

TODO

  • agree with @jsign and integrate with that PR
  • Fix all the loose parts and use it for replay
  • Rework the OpenStorageTrie interface

conversionBlock := uint64(17000) // random block number for now
if parent.Number.Uint64() == conversionBlock {
bc.StartVerkleTransition(parent.Root, emptyVerkleRoot)
}
Copy link
Owner Author

Choose a reason for hiding this comment

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

This is where the blockchain realizes that the transition should start, and signal a ForkedDB/TransitionTrie adapter should be used.

trie/transition.go Outdated Show resolved Hide resolved
return t.overlay.GetKey(key)
}
return t.base.GetKey(key)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why we need to do the t.overlay.GetKey(...) call if resolving this is only related to a query to the preimages database? Shouldn't we always ask and know we'll get a correct answer from the base tree?

Also, I looked what GetKey(...) means for verkle and I'm not sure that implementation is correct. As in, not really resolving what is expected and actually making the logic here work incorrectly.

Copy link
Owner Author

Choose a reason for hiding this comment

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

yup it's all buggy. To be fair, this function isn't used very often, if at all, and there's a proposal by Vitalik to also put the preimage in the C-level polynomial so we never have to worry about converting again. I don't think it makes sense to spend time implementing this function at all, tbh, so I'll replace it with a panic.

Comment on lines 56 to 67
if t.overlay.GetKey(key) != nil {
return t.overlay.TryGet(addr, key)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Uhm, maybe you're planning to give t.overlay.GetKey(key) other semantics.
Can't we do t.overlay.TryGet and if that returns an empty value (not present), then call the base?

Copy link
Owner Author

Choose a reason for hiding this comment

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

no that's completely incorrect and most likely the result of some dumb copy/paste.

return t.overlay.TryGet(addr, key)
}
// TODO also insert value into overlay
return t.base.TryGet(nil, key)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this nil intentional?

Copy link
Owner Author

Choose a reason for hiding this comment

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

yes, because that parameter isn't needed for the MPT. But we can pass the address if you're more comfortable with it.

if t.overlay.GetKey(key) != nil {
return t.overlay.TryGet(addr, key)
}
// TODO also insert value into overlay
Copy link
Collaborator

Choose a reason for hiding this comment

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

Tangent thought: doing this vs not doing may change the gas fee dynamics for users. Not sure if that's relevant for deciding doing this or not (from my perspective it would be better doing it, as we talked). But... just sharing the thought if UX could be impacted in a negative way.

Copy link
Owner Author

@gballet gballet Apr 21, 2023

Choose a reason for hiding this comment

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

well technically no gas will be charged at this layer. So if we change the gas costs during the transition (we should), then we should charge a blanket cost of : reading into vkt + reading into mpt

core/state/trie_prefetcher.go Outdated Show resolved Hide resolved
// CopyTrie implements Database
func (fdb *ForkingDB) CopyTrie(t Trie) Trie {
mpt := fdb.cachingDB.CopyTrie(t)
overlay := fdb.VerkleDB.CopyTrie(t)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure how expensive is overlay := fdb.VerkleDB.CopyTrie(t), but if !fdb.started we don't use the result; so maybe we can move it inside the if statement below.

core/state_processor.go Outdated Show resolved Hide resolved
Comment on lines 112 to 125
// move N=500 accounts into the verkle tree, starting with the
// slots from the previous account.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we skip always the first result of the iterator? Asking since LastAccHash/LastSlotHash I think point to the last migrated value; so in theory we'd like continue with the next?

Copy link
Owner Author

Choose a reason for hiding this comment

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

indeed

Comment on lines 115 to 145
for ; stIt.Next() && count < 500; count++ {
slotnr := rawdb.ReadPreimage(statedb.Database().DiskDB(), stIt.Hash())

// @jsign: do your magic here adding the slot `slotnr`
}

// if less than 500 slots were moved, move to the next account
for count < 500 {
if accIt.Next() {
acc, err := snapshot.FullAccount(accIt.Account())
if err != nil {
log.Error("Invalid account encountered during traversal", "error", err)
return err
}
addr := rawdb.ReadPreimage(statedb.Database().DiskDB(), accIt.Hash())

// @jsign: do your magic here adding the account at `addr

// Store the account code if present
if !bytes.Equal(acc.CodeHash, emptyCode) {
code := rawdb.ReadCode(statedb.Database().DiskDB(), common.BytesToHash(acc.CodeHash))
chunks := trie.ChunkifyCode(code)

// @jsign: do your magic here with the code chunks
}

if !bytes.Equal(acc.Root, emptyRoot[:]) {
for ; stIt.Next() && count < 500; count++ {
slotnr := rawdb.ReadPreimage(statedb.Database().DiskDB(), stIt.Hash())

// @jsign do your magic here with extra slots
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍

return mpt
}

// OpenStorageTrie implements Database
Copy link
Owner Author

Choose a reason for hiding this comment

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

So this implementation is somewhat tacky: there are several trees in the MPT world, but only one in the verkle world. I usually worked around the problem by making sure this would never get called, and it's probably the right approach still.

But I'm also thinking that this function should disappear from the interface in upstream altogether: one can see all these trees as only one tree, after all. I need to think it over, but this hack should work for now.

func (fdb *ForkingDB) StartTransition(originalRoot, translatedRoot common.Hash) {
fmt.Println(`
__________.__ .__ .__ __ .__ .__ ____
\__ ___| |__ ____ ____ | | ____ ______ | |__ _____ _____/ |_ | |__ _____ ______ __ _ _|__| ____ / ___\ ______
Copy link
Owner Author

Choose a reason for hiding this comment

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

you don't want to know where this comes from 🤣

trie/transition.go Outdated Show resolved Hide resolved
Fix some bugs identified in the code review

Co-authored-by: Ignacio Hagopian <[email protected]>

Include base -> overlay key-values migration logic (#199)

* mod: add go-verkle version with key-value migration new apis

Signed-off-by: Ignacio Hagopian <[email protected]>

* core/stateprocessor: use constant for max number of migrated key-values

Signed-off-by: Ignacio Hagopian <[email protected]>

* core: add base->overlay key-values migration logic

Signed-off-by: Ignacio Hagopian <[email protected]>

* core: fix some compiler errors

Signed-off-by: Ignacio Hagopian <[email protected]>

* trie: consider removing transition trie api in the future

Signed-off-by: Ignacio Hagopian <[email protected]>

* mod: use latest go-verkle

Signed-off-by: Ignacio Hagopian <[email protected]>

---------

Signed-off-by: Ignacio Hagopian <[email protected]>

fix some unit tests errors

get convresion block from file

fix compilation issues

fix initialization issue in migrator

fix: changes needed to run the first 28 blocks

important sutff: fix the banner

fix: use nonce instead of balance in nonce leaf (#202)

fixes for performing the overlay transition (#203)

* fixes for performing the overlay transition

* fixes for the full replay

* fix: deletion-and-recreation of EoA

* fixes to replay 2M+ blocks

* upgrade to go-verkle@master

* fix: proper number of chunk evals

* rewrite conversion loop to fix known issues

changes to make replay work with the overlay method (#216)

* fixes for performing the overlay transition

fixes for the full replay

fix: deletion-and-recreation of EoA

fixes to replay 2M+ blocks

upgrade to go-verkle@master

fix: proper number of chunk evals

rewrite conversion loop to fix known issues

changes to make replay work with the overlay method

fixes to replay 2M+ blocks

update to latest go-verkle@master

* use a PBSS-like scheme for internal nodes (#221)

* use a PBSS-like scheme for internal nodes

* a couple of fixes coming from debugging replay

* fix: use an error to notify the transition tree that a deleted account was found in the overlay tree (#222)

* fixes for pbss replay (#227)

* fixes for pbss replay

* trie/verkle: use capped batch size (#229)

* trie/verkle: use capped batch size

Signed-off-by: Ignacio Hagopian <[email protected]>

* trie/verkle: avoid path variable allocation per db.Put

Signed-off-by: Ignacio Hagopian <[email protected]>

* don't keep more than 32 state root conversions in RAM (#230)

---------

Signed-off-by: Ignacio Hagopian <[email protected]>
Co-authored-by: Guillaume Ballet <[email protected]>

* cleanup some code

* mod: update go-verkle

Signed-off-by: Ignacio Hagopian <[email protected]>

* re-enable snapshot (#231)

* re-enable cancun block / snapshot (#226)

* clear storage conversion key upon translating account (#234)

* clear storage conversion key upon translating account

* mod: use latest go-verkle

Signed-off-by: Ignacio Hagopian <[email protected]>

---------

Signed-off-by: Ignacio Hagopian <[email protected]>
Co-authored-by: Ignacio Hagopian <[email protected]>

* fix: self-deadlock with translated root map mutex (#236)

* return compressed commitment as root commitment (#237)

---------

Signed-off-by: Ignacio Hagopian <[email protected]>
Co-authored-by: Ignacio Hagopian <[email protected]>

---------

Signed-off-by: Ignacio Hagopian <[email protected]>
Co-authored-by: Ignacio Hagopian <[email protected]>

---------

Signed-off-by: Ignacio Hagopian <[email protected]>
Co-authored-by: Ignacio Hagopian <[email protected]>

fix first panic in *TransitionTrie.Copy()

upgrade go-verkle to latest master

mod: update go-verkle (#239)

Signed-off-by: Ignacio Hagopian <[email protected]>

core: print state root every 100 blocks (#240)

Signed-off-by: Ignacio Hagopian <[email protected]>

fix: only Commit the account trie (#242)

fixes to get TestProcessVerkle to work with the overlay branch (#238)

* fixes to get TestProcessVerkle to work with the overlay branch

* fix all panics in verkle state processor test

* fix proof verification
@gballet gballet force-pushed the overlay-implementation branch from b3d393f to 54dd265 Compare July 26, 2023 12:36
@gballet gballet closed this Mar 2, 2024
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