self-review

This commit is contained in:
Guillaume Ballet 2026-04-30 14:31:38 +02:00
parent d8ed290a40
commit 9a5140a590
No known key found for this signature in database
8 changed files with 54 additions and 52 deletions

View file

@ -2149,18 +2149,18 @@ type ExecuteConfig struct {
// transition, a transition UBTDatabase is built; otherwise (transition // transition, a transition UBTDatabase is built; otherwise (transition
// ended, or chainConfig.UBTTransitionEndTime crossed) a plain UBTDatabase // ended, or chainConfig.UBTTransitionEndTime crossed) a plain UBTDatabase
// is returned with the transition wrap disabled. // is returned with the transition wrap disabled.
func (bc *BlockChain) stateDatabase(parentRoot common.Hash, header *types.Header) state.Database { func (bc *BlockChain) stateDatabase(parentRoot common.Hash, header *types.Header) (state.Database, error) {
if !bc.chainConfig.IsUBT(header.Number, header.Time) { if !bc.chainConfig.IsUBT(header.Number, header.Time) {
return state.NewMPTDatabase(bc.triedb, bc.codedb).WithSnapshot(bc.snaps) return state.NewMPTDatabase(bc.triedb, bc.codedb).WithSnapshot(bc.snaps), nil
} }
// Past the configured transition end: pure binary, no wrap, no MPT base. // Past the configured transition end: pure binary, no wrap, no MPT base.
if !bc.chainConfig.UBTTransitionActive(header.Number, header.Time) { if !bc.chainConfig.UBTTransitionActive(header.Number, header.Time) {
return state.NewUBTDatabase(bc.bintriedbOrMain(), bc.codedb).WithTransitionTreeWrap(false) return state.NewUBTDatabase(bc.bintriedbOrMain(), bc.codedb).WithTransitionTreeWrap(false), nil
} }
// First UBT block: parent is pre-UBT; seed the transition with parent root. // First UBT block: parent is pre-UBT; seed the transition with parent root.
parent := bc.GetHeaderByHash(header.ParentHash) parent := bc.GetHeaderByHash(header.ParentHash)
if parent != nil && !bc.chainConfig.IsUBT(parent.Number, parent.Time) { if parent != nil && !bc.chainConfig.IsUBT(parent.Number, parent.Time) {
return state.NewTransitionUBTDatabase(bc.bintriedbOrMain(), bc.triedb, bc.codedb, parentRoot) return state.NewTransitionUBTDatabase(bc.bintriedbOrMain(), bc.triedb, bc.codedb, parentRoot), nil
} }
// Subsequent UBT block while the transition is active: probe the registry // Subsequent UBT block while the transition is active: probe the registry
// to see whether a base root is still recorded. // to see whether a base root is still recorded.
@ -2180,18 +2180,21 @@ func (bc *BlockChain) bintriedbOrMain() *triedb.Database {
// probeTransitionDatabase reads the transition registry from the binary trie // probeTransitionDatabase reads the transition registry from the binary trie
// at the given root and chooses between a transition-mode UBTDatabase (if // at the given root and chooses between a transition-mode UBTDatabase (if
// the registry still records a base root) and a plain UBTDatabase otherwise. // the registry still records a base root) and a plain UBTDatabase otherwise.
func (bc *BlockChain) probeTransitionDatabase(root common.Hash) state.Database { func (bc *BlockChain) probeTransitionDatabase(root common.Hash) (state.Database, error) {
bindb := bc.bintriedbOrMain() bindb := bc.bintriedbOrMain()
plain := state.NewUBTDatabase(bindb, bc.codedb) plain := state.NewUBTDatabase(bindb, bc.codedb)
reader, err := plain.StateReader(root) reader, err := plain.StateReader(root)
if err != nil { if err != nil {
return plain return nil, err
}
ts, err := overlay.LoadTransitionState(storageReaderFunc(reader.Storage))
if err != nil {
return nil, err
} }
ts := overlay.LoadTransitionState(storageReaderFunc(reader.Storage), root)
if ts == nil || ts.Transitioned() || ts.BaseRoot == (common.Hash{}) { if ts == nil || ts.Transitioned() || ts.BaseRoot == (common.Hash{}) {
return plain return plain, nil
} }
return state.NewTransitionUBTDatabase(bindb, bc.triedb, bc.codedb, ts.BaseRoot) return state.NewTransitionUBTDatabase(bindb, bc.triedb, bc.codedb, ts.BaseRoot), nil
} }
// storageReaderFunc adapts a state-reader Storage method to overlay.StorageReader. // storageReaderFunc adapts a state-reader Storage method to overlay.StorageReader.
@ -2212,7 +2215,10 @@ func (bc *BlockChain) ProcessBlock(ctx context.Context, parentRoot common.Hash,
) )
defer interrupt.Store(true) // terminate the prefetch at the end defer interrupt.Store(true) // terminate the prefetch at the end
sdb := bc.stateDatabase(parentRoot, block.Header()) sdb, err := bc.stateDatabase(parentRoot, block.Header())
if err != nil {
return nil, err
}
// If prefetching is enabled, run that against the current state to pre-cache // If prefetching is enabled, run that against the current state to pre-cache
// transactions and probabilistically some of the account/storage trie nodes. // transactions and probabilistically some of the account/storage trie nodes.
// //

View file

@ -421,13 +421,21 @@ func (bc *BlockChain) State() (*state.StateDB, error) {
// StateAt returns a new mutable state based on a particular point in time. // StateAt returns a new mutable state based on a particular point in time.
func (bc *BlockChain) StateAt(header *types.Header) (*state.StateDB, error) { func (bc *BlockChain) StateAt(header *types.Header) (*state.StateDB, error) {
return state.New(header.Root, bc.stateDatabase(header.Root, header)) db, err := bc.stateDatabase(header.Root, header)
if err != nil {
return nil, err
}
return state.New(header.Root, db)
} }
// StateAtForkBoundary returns a new mutable state based on the parent state // StateAtForkBoundary returns a new mutable state based on the parent state
// and the given header, handling the transition across the UBT fork. // and the given header, handling the transition across the UBT fork.
func (bc *BlockChain) StateAtForkBoundary(parent *types.Header, header *types.Header) (*state.StateDB, error) { func (bc *BlockChain) StateAtForkBoundary(parent *types.Header, header *types.Header) (*state.StateDB, error) {
return state.New(parent.Root, bc.stateDatabase(parent.Root, header)) db, err := bc.stateDatabase(parent.Root, header)
if err != nil {
return nil, err
}
return state.New(parent.Root, db)
} }
// HistoricState returns a historic state specified by the given header. // HistoricState returns a historic state specified by the given header.

View file

@ -39,9 +39,8 @@ type StorageReader interface {
Storage(addr common.Address, slot common.Hash) (common.Hash, error) Storage(addr common.Address, slot common.Hash) (common.Hash, error)
} }
// TransitionState holds the progress markers of the MPT-to-binary // TransitionState is a structure that holds the progress markers of the
// translation process. It is reconstructed on demand from the storage of the // translation process.
// binary transition registry system contract.
type TransitionState struct { type TransitionState struct {
CurrentAccountAddress *common.Address // address of the last translated account CurrentAccountAddress *common.Address // address of the last translated account
CurrentSlotHash common.Hash // hash of the last translated storage slot CurrentSlotHash common.Hash // hash of the last translated storage slot
@ -98,10 +97,13 @@ func IsTransitionActive(reader StorageReader) bool {
// //
// The root parameter is unused; it is retained on the signature so callers // The root parameter is unused; it is retained on the signature so callers
// can express the state version they intend to read. // can express the state version they intend to read.
func LoadTransitionState(reader StorageReader, root common.Hash) *TransitionState { func LoadTransitionState(reader StorageReader) (*TransitionState, error) {
started, err := reader.Storage(params.BinaryTransitionRegistryAddress, transitionStartedKey) started, err := reader.Storage(params.BinaryTransitionRegistryAddress, transitionStartedKey)
if err != nil || started == (common.Hash{}) { if err != nil {
return nil return nil, err
}
if started == (common.Hash{}) {
return nil, nil
} }
ended, _ := reader.Storage(params.BinaryTransitionRegistryAddress, transitionEndedKey) ended, _ := reader.Storage(params.BinaryTransitionRegistryAddress, transitionEndedKey)
@ -114,8 +116,14 @@ func LoadTransitionState(reader StorageReader, root common.Hash) *TransitionStat
currentAddr = &addr currentAddr = &addr
} }
slotHash, _ := reader.Storage(params.BinaryTransitionRegistryAddress, conversionProgressSlotKey) slotHash, err := reader.Storage(params.BinaryTransitionRegistryAddress, conversionProgressSlotKey)
storageProcessed, _ := reader.Storage(params.BinaryTransitionRegistryAddress, conversionProgressStorageProcessed) if err != nil {
return nil, err
}
storageProcessed, err := reader.Storage(params.BinaryTransitionRegistryAddress, conversionProgressStorageProcessed)
if err != nil {
return nil, err
}
return &TransitionState{ return &TransitionState{
Started: true, Started: true,
@ -124,5 +132,5 @@ func LoadTransitionState(reader StorageReader, root common.Hash) *TransitionStat
CurrentAccountAddress: currentAddr, CurrentAccountAddress: currentAddr,
CurrentSlotHash: slotHash, CurrentSlotHash: slotHash,
StorageProcessed: storageProcessed != (common.Hash{}), StorageProcessed: storageProcessed != (common.Hash{}),
} }, nil
} }

View file

@ -457,4 +457,3 @@ func trienodeHistoryIndexBlockKey(addressHash common.Hash, path []byte, blockID
return out return out
} }

View file

@ -138,9 +138,7 @@ func (db *UBTDatabase) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Rea
return ra, rb, nil return ra, rb, nil
} }
// OpenTrie opens the main account trie at a specific root hash. During an // OpenTrie opens the main account trie at a specific root hash.
// active transition, the binary trie is wrapped in a TransitionTrie so writes
// land on the binary trie while reads fall through to the frozen MPT base.
func (db *UBTDatabase) OpenTrie(root common.Hash) (Trie, error) { func (db *UBTDatabase) OpenTrie(root common.Hash) (Trie, error) {
bt, err := bintrie.NewBinaryTrie(root, db.triedb) bt, err := bintrie.NewBinaryTrie(root, db.triedb)
if err != nil { if err != nil {
@ -157,9 +155,7 @@ func (db *UBTDatabase) OpenTrie(root common.Hash) (Trie, error) {
} }
// OpenStorageTrie opens the storage trie of an account. In binary trie mode // OpenStorageTrie opens the storage trie of an account. In binary trie mode
// the unified trie carries all state, so the main trie is reused. During the // the unified trie carries all state, so the main trie is reused.
// transition, an MPT storage trie is opened for accounts that have not yet
// been migrated.
func (db *UBTDatabase) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, self Trie) (Trie, error) { func (db *UBTDatabase) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, self Trie) (Trie, error) {
if self != nil && self.IsUBT() { if self != nil && self.IsUBT() {
return self, nil return self, nil

View file

@ -288,7 +288,11 @@ func newUBTTrieReader(root common.Hash, bindb *triedb.Database, mptdb *triedb.Da
} }
var base *trie.StateTrie var base *trie.StateTrie
if wrapInTransitionTrie && mptdb != nil { if wrapInTransitionTrie && mptdb != nil {
if ts := overlay.LoadTransitionState(&binTrieStorageReader{tr: binTrie}, root); ts != nil && ts.BaseRoot != (common.Hash{}) { ts, err := overlay.LoadTransitionState(&binTrieStorageReader{tr: binTrie})
if err != nil {
return nil, err
}
if ts != nil && ts.BaseRoot != (common.Hash{}) {
base, err = trie.NewStateTrie(trie.StateTrieID(ts.BaseRoot), mptdb) base, err = trie.NewStateTrie(trie.StateTrieID(ts.BaseRoot), mptdb)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -469,12 +469,8 @@ type ChainConfig struct {
UBTTime *uint64 `json:"ubtTime,omitempty"` // UBT switch time (nil = no fork, 0 = already on UBT) UBTTime *uint64 `json:"ubtTime,omitempty"` // UBT switch time (nil = no fork, 0 = already on UBT)
// UBTTransitionEndTime is the timestamp at which the MPT-to-binary // UBTTransitionEndTime is the timestamp at which the MPT-to-binary
// transition tree is no longer applied. While UBT is active and the // transition tree is no longer applied. Mirrors the threshold semantics
// timestamp is below this value (or nil), state access is wrapped in a // of TerminalTotalDifficulty.
// TransitionTrie that overlays the binary trie on the frozen MPT base.
// Once headers reach this time, the transition wrapper is dropped and
// state is read directly from the binary trie. nil = wrapper stays on
// indefinitely. Mirrors the threshold semantics of TerminalTotalDifficulty.
UBTTransitionEndTime *uint64 `json:"ubtTransitionEndTime,omitempty"` UBTTransitionEndTime *uint64 `json:"ubtTransitionEndTime,omitempty"`
// TerminalTotalDifficulty is the amount of total difficulty reached by // TerminalTotalDifficulty is the amount of total difficulty reached by
@ -897,16 +893,7 @@ func (c *ChainConfig) UBTTransitionActive(num *big.Int, time uint64) bool {
return c.UBTTransitionEndTime == nil || time < *c.UBTTransitionEndTime return c.UBTTransitionEndTime == nil || time < *c.UBTTransitionEndTime
} }
// IsUBTGenesis checks whether the verkle fork is activated at the genesis block. // IsUBTGenesis checks whether the UBT fork is activated at the genesis block.
//
// Verkle mode is considered enabled if the verkle fork time is configured,
// regardless of whether the local time has surpassed the fork activation time.
// This is a temporary workaround for verkle devnet testing, where verkle is
// activated at genesis, and the configured activation date has already passed.
//
// In production networks (mainnet and public testnets), verkle activation
// always occurs after the genesis block, making this function irrelevant in
// those cases.
func (c *ChainConfig) IsUBTGenesis() bool { func (c *ChainConfig) IsUBTGenesis() bool {
return c.EnableUBTAtGenesis return c.EnableUBTAtGenesis
} }

View file

@ -224,13 +224,7 @@ var (
ConsolidationQueueCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd") ConsolidationQueueCode = common.FromHex("3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd")
// BinaryTransitionRegistryAddress is the system contract that exposes the // BinaryTransitionRegistryAddress is the system contract that exposes the
// MPT-to-binary transition state via storage slots: // MPT-to-binary transition state via storage slots.
// slot 0 = transition started flag
// slot 1 = address of the last translated account
// slot 2 = hash of the last translated storage slot
// slot 3 = "storage processed" flag
// slot 4 = transition ended flag
// slot 5 = frozen MPT base root
BinaryTransitionRegistryAddress = common.HexToAddress("0x1622162216221622162216221622162216221622") BinaryTransitionRegistryAddress = common.HexToAddress("0x1622162216221622162216221622162216221622")
) )