rework activation

This commit is contained in:
Guillaume Ballet 2026-01-28 13:28:34 -05:00
parent 09b9c27c83
commit 9cef9dc75e
4 changed files with 69 additions and 16 deletions

View file

@ -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: &currentAccount,
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)

View file

@ -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() {

View file

@ -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
}

View file

@ -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
}