Skip to content

core, params: transition tree initialization#33685

Open
gballet wants to merge 10 commits intoethereum:masterfrom
gballet:geth-system-contract-transition
Open

core, params: transition tree initialization#33685
gballet wants to merge 10 commits intoethereum:masterfrom
gballet:geth-system-contract-transition

Conversation

@gballet
Copy link
Copy Markdown
Member

@gballet gballet commented Jan 26, 2026

This implements another piece of the binary tree transition: the creation of the transition tree. The conversion itself will be the topic of a further PR, but the tree initialization logic is complex enough to deserve its own review unit.

TODO:

  • Get feedback on how the contract state is read
  • address todos in state_transition.go

ts = &newts
func LoadTransitionState(db ethdb.KeyValueReader, root common.Hash) *TransitionState {
stem := bintrie.GetBinaryTreeKeyStorageSlot(params.BinaryTransitionRegistryAddress, conversionProgressAddressKey[:])
leaf := rawdb.ReadStorageTrieNode(db, common.Hash{}, stem[:bintrie.StemSize])
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

There is a chicken-and-egg problem here, when we want to read the conversion progress from the tree, but we need the result to know how the tree must be opened.

Here, I am going to read the data straight from the tree, but this is assuming the state on disk is up to date with all layers, which isn't always the case, so it needs to be aware of the caches, if present.

}
ts = &newts
func LoadTransitionState(db ethdb.KeyValueReader, root common.Hash) *TransitionState {
stem := bintrie.GetBinaryTreeKeyStorageSlot(params.BinaryTransitionRegistryAddress, conversionProgressAddressKey[:])
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

When we try to do the state conversion, I would assume the flat states will be available. Actually with the BAL, this assumption is always held that the flat states and associated trie data is all available once the sync is completed, regardless of the type of sync.

We can load the conversion pointers from the contract from the flat state isn't it?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

And also, read trie node directly from the disk is definitely wrong. We must read the progress marker from the associated state reader.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

thought I had responded, yeah I had missed that the "flat reader" is actually reading the tree, and therefore is always present. That changes the outlook of things. I have updated it, I have a build issue that I need to fix but this should be it.

@gballet
Copy link
Copy Markdown
Member Author

gballet commented Feb 2, 2026

getting this in dev mode:

INFO [02-02|09:58:20.611] Forkchoice requested sync to new head    number=7 hash=ab908c..522168 finalized=unknown
INFO [02-02|09:58:20.611] Block synchronisation started
INFO [02-02|09:58:20.612] Reenabled snap-sync as chain is stateless
INFO [02-02|09:58:20.612] Disabled trie database due to state sync
panic: error reading conversion account pointer: layer stale

goroutine 7457 [running]:
github.com/ethereum/go-ethereum/core/state.LoadTransitionState({0x2286848, 0xc00081c8a0}, {0x3, 0x16, 0xdf, 0x3, 0x63, 0x95, 0x2, 0x90, ...})
        /home/gballet/geth-system-contract-transition/core/state/database.go:221 +0x556
github.com/ethereum/go-ethereum/core/state.(*CachingDB).StateReader(0xc000802400, {0x3, 0x16, 0xdf, 0x3, 0x63, 0x95, 0x2, 0x90, 0xb1, ...})
        /home/gballet/geth-system-contract-transition/core/state/database.go:269 +0x30f
github.com/ethereum/go-ethereum/core/state.(*CachingDB).OpenTrie(0xc000802400, {0x3, 0x16, 0xdf, 0x3, 0x63, 0x95, 0x2, 0x90, 0xb1, ...})
        /home/gballet/geth-system-contract-transition/core/state/database.go:311 +0x45
github.com/ethereum/go-ethereum/core.(*BlockChain).HasState(0xc00213d9d0?, {0x3, 0x16, 0xdf, 0x3, 0x63, 0x95, 0x2, 0x90, 0xb1, ...})
        /home/gballet/geth-system-contract-transition/core/blockchain_reader.go:374 +0x2a
github.com/ethereum/go-ethereum/eth/downloader.(*syncModer).get(0xc000809830, 0x44?)
        /home/gballet/geth-system-contract-transition/eth/downloader/syncmode.go:102 +0x225
github.com/ethereum/go-ethereum/eth/downloader.(*Downloader).ConfigSyncMode(...)
        /home/gballet/geth-system-contract-transition/eth/downloader/downloader.go:427
github.com/ethereum/go-ethereum/eth.(*handler).blockRangeLoop(0xc00024a8c0, 0xc001aa0420)
        /home/gballet/geth-system-contract-transition/eth/handler.go:570 +0x13d
created by github.com/ethereum/go-ethereum/eth.(*handler).Start in goroutine 1
        /home/gballet/geth-system-contract-transition/eth/handler.go:426 +0x19c
exit status 2

if config.IsPrague(block.Number(), block.Time()) || config.IsVerkle(block.Number(), block.Time()) {
ProcessParentBlockHash(block.ParentHash(), evm)
}
if config.IsVerkle(header.Number, header.Time) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we treat the TransitionRegistry contract like the deposit contract? We can pre-deploy it across all the network with the same address and update it according to the transition status?

It feels wrong to me to manually update it here.

ts := overlay.LoadTransitionState(db.TrieDB().Disk(), root, db.triedb.IsVerkle())
if ts.InTransition() {
panic("state tree transition isn't supported yet")
reader, err := db.StateReader(root)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

get flat state reader only

@gballet gballet marked this pull request as ready for review February 3, 2026 13:12
…le() checks (#564)

 - Fix an issue in which the prefetcher was creating a new MPT tree in verkle mode, based on the fact that triedb.IsVerkle() was false.
 - Also fix the tree bootstrapping in the reader
 - generally, no longer use db.triedb.IsVerkle() as it's only true if the db is used when starting in verkle mode.
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.

2 participants