core, params: transition tree initialization

This commit is contained in:
Guillaume Ballet 2026-01-26 15:01:47 +01:00
parent c2595381bf
commit 397497c0f6
5 changed files with 60 additions and 39 deletions

View file

@ -17,17 +17,21 @@
package overlay
import (
"bytes"
"encoding/gob"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/trie/bintrie"
)
// TransitionState is a structure that holds the progress markers of the
// translation process.
// TODO gballet:
// * see if I can get rid of the pointer now that this piece
// has been rewritten.
// * the conversion pointers should no longer be necessary,
// remove them when it's been confirmed.
// * we can't keep the preimage offset in the file
type TransitionState struct {
CurrentAccountAddress *common.Address // addresss of the last translated account
CurrentSlotHash common.Hash // hash of the last translated storage slot
@ -69,38 +73,32 @@ func (ts *TransitionState) Copy() *TransitionState {
return ret
}
var (
conversionProgressAddressKey = common.Hash{1}
conversionProgressSlotKey = common.Hash{2}
conversionProgressStorageProcessed = common.Hash{3}
)
// LoadTransitionState retrieves the Verkle transition state associated with
// the given state root hash from the database.
func LoadTransitionState(db ethdb.KeyValueReader, root common.Hash, isVerkle bool) *TransitionState {
var ts *TransitionState
data, _ := rawdb.ReadVerkleTransitionState(db, root)
// if a state could be read from the db, attempt to decode it
if len(data) > 0 {
var (
newts TransitionState
buf = bytes.NewBuffer(data[:])
dec = gob.NewDecoder(buf)
)
// Decode transition state
err := dec.Decode(&newts)
if err != nil {
log.Error("failed to decode transition state", "err", err)
return nil
}
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])
if len(leaf) == 0 {
return &TransitionState{}
}
// Fallback that should only happen before the transition
if ts == nil {
// Initialize the first transition state, with the "ended"
// field set to true if the database was created
// as a verkle database.
log.Debug("no transition state found, starting fresh", "verkle", isVerkle)
// Start with a fresh state
ts = &TransitionState{Ended: isVerkle}
node, err := bintrie.DeserializeNode(leaf, 0)
if err != nil {
panic("could not deserialize conversion pointers contract storage")
}
leafNode := node.(*bintrie.StemNode)
currentAccount := common.BytesToAddress(leafNode.Values[65][12:])
currentSlotHash := common.BytesToHash(leafNode.Values[66])
storageProcessed := len(leafNode.Values[67]) > 0 && leafNode.Values[67][0] != 0
return &TransitionState{
CurrentAccountAddress: &currentAccount,
CurrentSlotHash: currentSlotHash,
StorageProcessed: storageProcessed,
}
return ts
}

View file

@ -239,15 +239,24 @@ 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() {
ts := overlay.LoadTransitionState(db.TrieDB().Disk(), root, db.triedb.IsVerkle())
if ts.InTransition() {
panic("state tree transition isn't supported yet")
// if the transition has started, it will be present in the overlay tree,
// so we open it regardless.
bt, err := bintrie.NewBinaryTrie(root, db.triedb)
if err != nil {
return nil, fmt.Errorf("could not open the overlay tree: %w", err)
}
if ts.Transitioned() {
ts := overlay.LoadTransitionState(db.TrieDB().Disk(), root)
if !ts.InTransition() {
// Use BinaryTrie instead of VerkleTrie when IsVerkle is set
// (IsVerkle actually means Binary Trie mode in this codebase)
return bintrie.NewBinaryTrie(root, db.triedb)
return bt, nil
}
base, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb)
if err != nil {
return nil, fmt.Errorf("could not create base trie in OpenTrie: %w", err)
}
return transitiontrie.NewTransitionTrie(base, bt, false), nil
}
tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb)
if err != nil {

View file

@ -330,7 +330,7 @@ func newTrieReader(root common.Hash, db *triedb.Database) (*trieReader, error) {
// Based on the transition status, determine if the overlay
// tree needs to be created, or if a single, target tree is
// to be picked.
ts := overlay.LoadTransitionState(db.Disk(), root, true)
ts := overlay.LoadTransitionState(db.Disk(), root)
if ts.InTransition() {
mpt, err := trie.NewStateTrie(trie.StateTrieID(ts.BaseRoot), db)
if err != nil {

View file

@ -349,6 +349,17 @@ func (s *StateDB) GetStorageRoot(addr common.Address) common.Hash {
return common.Hash{}
}
// TransitionComplete checks if the EIP-7612 transition is complete.
func (s *StateDB) InTransition() bool {
completeKey := common.Hash{} // slot 0 for completion flag
completeValue := s.GetState(params.BinaryTransitionRegistryAddress, completeKey)
return completeValue != (common.Hash{})
}
func (s *StateDB) ProcessBinaryTreeTransition(maxSlot uint64) {
}
// TxIndex returns the current transaction index set by SetTxContext.
func (s *StateDB) TxIndex() int {
return s.txIndex

View file

@ -219,4 +219,7 @@ var (
// EIP-7251 - Increase the MAX_EFFECTIVE_BALANCE
ConsolidationQueueAddress = common.HexToAddress("0x0000BBdDc7CE488642fb579F8B00f3a590007251")
ConsolidationQueueCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd")
// EIP-7612 - Tree transition registry contract address
BinaryTransitionRegistryAddress = common.HexToAddress("0x1622162216221622162216221622162216221622162216221622162216221622")
)