From 9cef9dc75e168a11a8a6da58851045a277839372 Mon Sep 17 00:00:00 2001 From: Guillaume Ballet <3272758+gballet@users.noreply.github.com> Date: Wed, 28 Jan 2026 13:28:34 -0500 Subject: [PATCH] rework activation --- core/state/database.go | 67 +++++++++++++++++++++++++++++++---------- core/state_processor.go | 5 +++ eth/state_accessor.go | 7 +++++ miner/worker.go | 6 ++++ 4 files changed, 69 insertions(+), 16 deletions(-) diff --git a/core/state/database.go b/core/state/database.go index 763a73aa19..fc134e8b5e 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -179,14 +179,43 @@ func NewDatabaseForTesting() *CachingDB { } var ( - conversionProgressAddressKey = common.Hash{1} - conversionProgressSlotKey = common.Hash{2} - conversionProgressStorageProcessed = common.Hash{3} + transitionStartedKey = common.Hash{} // slot 0: non-zero if transition started + conversionProgressAddressKey = common.Hash{1} // slot 1: current account pointer + conversionProgressSlotKey = common.Hash{2} // slot 2: current slot pointer + conversionProgressStorageProcessed = common.Hash{3} // slot 3: storage processed flag + transitionEndedKey = common.Hash{4} // slot 4: non-zero if transition ended ) +// isTransitionActive checks if the binary tree transition has been activated +func isTransitionActive(reader StateReader) bool { + val, err := reader.Storage(params.BinaryTransitionRegistryAddress, transitionStartedKey) + if err != nil { + return false + } + return val != (common.Hash{}) +} + // LoadTransitionState retrieves the Verkle transition state associated with // the given state root hash from the database. func LoadTransitionState(reader StateReader, root common.Hash) *overlay.TransitionState { + startedBytes, err := reader.Storage(params.BinaryTransitionRegistryAddress, transitionStartedKey) + if err != nil { + return nil + } + started := startedBytes != (common.Hash{}) + + // If not started, return nil to indicate no active transition + if !started { + return nil + } + + endedBytes, err := reader.Storage(params.BinaryTransitionRegistryAddress, transitionEndedKey) + if err != nil { + // Registry exists but can't read ended flag - treat as still in transition + endedBytes = common.Hash{} + } + ended := endedBytes != (common.Hash{}) + currentAccountBytes, err := reader.Storage(params.BinaryTransitionRegistryAddress, conversionProgressAddressKey) if err != nil { panic(fmt.Errorf("error reading conversion account pointer: %w", err)) @@ -205,6 +234,8 @@ func LoadTransitionState(reader StateReader, root common.Hash) *overlay.Transiti storageProcessed := storageProcessedBytes[0] == 1 return &overlay.TransitionState{ + Started: started, + Ended: ended, CurrentAccountAddress: ¤tAccount, CurrentSlotHash: currentSlotHash, StorageProcessed: storageProcessed, @@ -232,8 +263,11 @@ func (db *CachingDB) StateReader(stateRoot common.Hash) (StateReader, error) { if db.TrieDB().Scheme() == rawdb.PathScheme { reader, err := db.triedb.StateReader(stateRoot) if err == nil { - readers = append(readers, newFlatReader(reader)) - ts = LoadTransitionState(readers[len(readers)-1], stateRoot) + flatReader := newFlatReader(reader) + readers = append(readers, flatReader) + if isTransitionActive(flatReader) || db.triedb.IsVerkle() { + ts = LoadTransitionState(flatReader, stateRoot) + } } } // Configure the trie reader, which is expected to be available as the @@ -274,22 +308,23 @@ func (db *CachingDB) ReadersWithCacheStats(stateRoot common.Hash) (ReaderWithSta // OpenTrie opens the main account trie at a specific root hash. func (db *CachingDB) OpenTrie(root common.Hash) (Trie, error) { - if db.triedb.IsVerkle() { - // if the transition has started, the pointers will be present in the - // overlay tree, and the tree itself will be present, so the tree is - // opened and the pointers read, regardless of what comes afterwards. + reader, err := db.StateReader(root) + if err != nil { + tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb) + if err != nil { + return nil, err + } + return tr, nil + } + + if isTransitionActive(reader) || db.triedb.IsVerkle() { bt, err := bintrie.NewBinaryTrie(root, db.triedb) if err != nil { return nil, fmt.Errorf("could not open the overlay tree: %w", err) } - reader, err := db.StateReader(root) - if err != nil { - return nil, fmt.Errorf("could not get reader for checking overlay status: %w", err) - } ts := LoadTransitionState(reader, root) if !ts.InTransition() { - // Use BinaryTrie instead of VerkleTrie when IsVerkle is set - // (IsVerkle actually means Binary Trie mode in this codebase) + // Transition complete, use BinaryTrie only return bt, nil } @@ -308,7 +343,7 @@ func (db *CachingDB) OpenTrie(root common.Hash) (Trie, error) { // OpenStorageTrie opens the storage trie of an account. func (db *CachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, self Trie) (Trie, error) { - if db.triedb.IsVerkle() { + if self != nil && self.IsVerkle() { return self, nil } tr, err := trie.NewStateTrie(trie.StorageTrieID(stateRoot, crypto.Keccak256Hash(address.Bytes()), root), db.triedb) diff --git a/core/state_processor.go b/core/state_processor.go index b4b22e4318..5d76560825 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -93,6 +93,11 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg if config.IsPrague(block.Number(), block.Time()) || config.IsVerkle(block.Number(), block.Time()) { ProcessParentBlockHash(block.ParentHash(), evm) } + if config.IsVerkle(header.Number, header.Time) { + statedb.SetCode(params.BinaryTransitionRegistryAddress, []byte{1, 2, 3}, tracing.CodeChangeUnspecified) + statedb.SetNonce(params.BinaryTransitionRegistryAddress, 1, tracing.NonceChangeUnspecified) + statedb.SetState(params.BinaryTransitionRegistryAddress, common.Hash{}, common.Hash{1}) + } // Iterate over and process the individual transactions for i, tx := range block.Transactions() { diff --git a/eth/state_accessor.go b/eth/state_accessor.go index 79c91043a3..2ff27581fe 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -26,10 +26,12 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/triedb" ) @@ -251,6 +253,11 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, if eth.blockchain.Config().IsPrague(block.Number(), block.Time()) { core.ProcessParentBlockHash(block.ParentHash(), evm) } + if eth.blockchain.Config().IsVerkle(block.Number(), block.Time()) { + statedb.SetCode(params.BinaryTransitionRegistryAddress, []byte{1, 2, 3}, tracing.CodeChangeUnspecified) + statedb.SetNonce(params.BinaryTransitionRegistryAddress, 1, tracing.NonceChangeUnspecified) + statedb.SetState(params.BinaryTransitionRegistryAddress, common.Hash{}, common.Hash{1}) + } if txIndex == 0 && len(block.Transactions()) == 0 { return nil, context, statedb, release, nil } diff --git a/miner/worker.go b/miner/worker.go index 45d7073ed7..4a7057c505 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/stateless" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" @@ -266,6 +267,11 @@ func (miner *Miner) prepareWork(genParams *generateParams, witness bool) (*envir if miner.chainConfig.IsPrague(header.Number, header.Time) { core.ProcessParentBlockHash(header.ParentHash, env.evm) } + if miner.chainConfig.IsVerkle(header.Number, header.Time) { + env.state.SetCode(params.BinaryTransitionRegistryAddress, []byte{1, 2, 3}, tracing.CodeChangeUnspecified) + env.state.SetNonce(params.BinaryTransitionRegistryAddress, 1, tracing.NonceChangeUnspecified) + env.state.SetState(params.BinaryTransitionRegistryAddress, common.Hash{}, common.Hash{1}) + } return env, nil }