cmd, core, triedb: rework database interface

This commit is contained in:
Gary Rong 2026-04-14 10:08:05 +08:00
parent 890b02fd98
commit 9f33f194b2
15 changed files with 144 additions and 167 deletions

View file

@ -2121,9 +2121,9 @@ 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
if bc.chainConfig.IsUBT(block.Number(), block.Time()) { if bc.chainConfig.IsUBT(block.Number(), block.Time()) {
sdb = state.NewUBTDB(bc.triedb, bc.codedb) sdb = state.NewUBTDatabase(bc.triedb, bc.codedb)
} else { } else {
sdb = state.NewMerkleDB(bc.triedb, bc.codedb).WithSnapshot(bc.snaps) sdb = state.NewMPTDatabase(bc.triedb, bc.codedb).WithSnapshot(bc.snaps)
} }
// 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

@ -422,7 +422,7 @@ 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(root common.Hash) (*state.StateDB, error) { func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
// TODO(rjl493456442) support ubt later // TODO(rjl493456442) support ubt later
return state.New(root, state.NewMerkleDB(bc.triedb, bc.codedb).WithSnapshot(bc.snaps)) return state.New(root, state.NewMPTDatabase(bc.triedb, bc.codedb).WithSnapshot(bc.snaps))
} }
// HistoricState returns a historic state specified by the given root. // HistoricState returns a historic state specified by the given root.

View file

@ -126,7 +126,7 @@ func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transacti
// Merge the tx-local access event into the "block-local" one, in order to collect // Merge the tx-local access event into the "block-local" one, in order to collect
// all values, so that the witness can be built. // all values, so that the witness can be built.
if b.statedb.Database().TrieDB().IsUBT() { if b.statedb.Database().Type().Is(state.TypeUBT) {
b.statedb.AccessEvents().Merge(evm.AccessEvents) b.statedb.AccessEvents().Merge(evm.AccessEvents)
} }
b.txs = append(b.txs, tx) b.txs = append(b.txs, tx)

View file

@ -21,7 +21,6 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state/snapshot"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
@ -30,8 +29,27 @@ import (
"github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb"
) )
// DatabaseType represents the type of trie backing the state database.
type DatabaseType int
const (
// TypeMPT indicates a Merkle Patricia Trie (MPT) backed database.
TypeMPT DatabaseType = iota
// TypeUBT indicates a Unified Binary Trie (UBT) backed database.
TypeUBT
)
// Is returns the flag indicating the database type equals to the given one.
func (typ DatabaseType) Is(t DatabaseType) bool {
return typ == t
}
// Database wraps access to tries and contract code. // Database wraps access to tries and contract code.
type Database interface { type Database interface {
// Type returns the trie type backing this database (MPT or UBT).
Type() DatabaseType
// Reader returns a state reader associated with the specified state root. // Reader returns a state reader associated with the specified state root.
Reader(root common.Hash) (Reader, error) Reader(root common.Hash) (Reader, error)
@ -52,9 +70,6 @@ type Database interface {
// committing the changes to the underlying storage. It returns an error // committing the changes to the underlying storage. It returns an error
// if the commit fails. // if the commit fails.
Commit(update *stateUpdate) error Commit(update *stateUpdate) error
// Snapshot returns the underlying state snapshot.
Snapshot() *snapshot.Tree
} }
// Trie is a Ethereum Merkle Patricia trie. // Trie is a Ethereum Merkle Patricia trie.
@ -144,12 +159,12 @@ type Trie interface {
// NewDatabase creates a state database with the provided data sources. // NewDatabase creates a state database with the provided data sources.
// //
// Deprecated, please use NewMerkleDB or NewUBTDB directly. // Deprecated, please use NewMPTDatabase or NewUBTDatabase directly.
func NewDatabase(tdb *triedb.Database, codedb *CodeDB) Database { func NewDatabase(tdb *triedb.Database, codedb *CodeDB) Database {
if tdb.IsUBT() { if tdb.IsUBT() {
return NewUBTDB(tdb, codedb) return NewUBTDatabase(tdb, codedb)
} }
return NewMerkleDB(tdb, codedb) return NewMPTDatabase(tdb, codedb)
} }
// NewDatabaseForTesting is similar to NewDatabase, but it initializes the caching // NewDatabaseForTesting is similar to NewDatabase, but it initializes the caching

View file

@ -22,7 +22,6 @@ import (
"sync" "sync"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state/snapshot"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
@ -224,6 +223,12 @@ type HistoricDB struct {
codedb *CodeDB codedb *CodeDB
} }
// Type returns the trie type of the underlying database.
func (db *HistoricDB) Type() DatabaseType {
// TODO(rjl493456442) support UBT in the future
return TypeMPT
}
// NewHistoricDatabase creates a historic state database. // NewHistoricDatabase creates a historic state database.
func NewHistoricDatabase(triedb *triedb.Database, codedb *CodeDB) *HistoricDB { func NewHistoricDatabase(triedb *triedb.Database, codedb *CodeDB) *HistoricDB {
return &HistoricDB{ return &HistoricDB{
@ -301,18 +306,3 @@ func (db *HistoricDB) Commit(update *stateUpdate) error {
func (db *HistoricDB) Iteratee(root common.Hash) (Iteratee, error) { func (db *HistoricDB) Iteratee(root common.Hash) (Iteratee, error) {
return nil, errors.New("not implemented") return nil, errors.New("not implemented")
} }
// WithSnapshot is not supported by historic database.
func (db *HistoricDB) WithSnapshot(snap *snapshot.Tree) Database {
return db
}
// Snapshot returns nil as historic database does not support snapshots.
func (db *HistoricDB) Snapshot() *snapshot.Tree {
return nil
}
// StateReader is not supported by historic database; use Reader instead.
func (db *HistoricDB) StateReader(stateRoot common.Hash) (StateReader, error) {
return nil, errors.New("not implemented")
}

View file

@ -26,36 +26,38 @@ import (
"github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb"
) )
// MerkleDB is an implementation of Database interface for Merkle Patricia Tries. // MPTDatabase is an implementation of Database interface for Merkle Patricia Tries.
// It leverages both trie and state snapshot to provide functionalities for state // It leverages both trie and state snapshot to provide functionalities for state
// access. It's meant to be a long-live object and has a few caches inside for // access.
// sharing between blocks. type MPTDatabase struct {
type MerkleDB struct {
triedb *triedb.Database triedb *triedb.Database
codedb *CodeDB codedb *CodeDB
snap *snapshot.Tree snap *snapshot.Tree
} }
// NewMerkleDB creates a state database with the Merkle Patricia Trie manner. // Type returns Merkle, indicating this database is backed by a Merkle Patricia Trie.
func NewMerkleDB(tdb *triedb.Database, codedb *CodeDB) *MerkleDB { func (db *MPTDatabase) Type() DatabaseType { return TypeMPT }
// NewMPTDatabase creates a state database with the Merkle Patricia Trie manner.
func NewMPTDatabase(tdb *triedb.Database, codedb *CodeDB) *MPTDatabase {
if codedb == nil { if codedb == nil {
codedb = NewCodeDB(tdb.Disk()) codedb = NewCodeDB(tdb.Disk())
} }
return &MerkleDB{ return &MPTDatabase{
triedb: tdb, triedb: tdb,
codedb: codedb, codedb: codedb,
} }
} }
// WithSnapshot configures the provided contract code cache. Note that this // WithSnapshot configures the provided state snapshot. Note that this
// registration must be performed before the MerkleDB is used. // registration must be performed before the MPTDatabase is used.
func (db *MerkleDB) WithSnapshot(snapshot *snapshot.Tree) Database { func (db *MPTDatabase) WithSnapshot(snapshot *snapshot.Tree) Database {
db.snap = snapshot db.snap = snapshot
return db return db
} }
// StateReader returns a state reader associated with the specified state root. // StateReader returns a state reader associated with the specified state root.
func (db *MerkleDB) StateReader(stateRoot common.Hash) (StateReader, error) { func (db *MPTDatabase) StateReader(stateRoot common.Hash) (StateReader, error) {
var readers []StateReader var readers []StateReader
// Configure the state reader using the standalone snapshot in hash mode. // Configure the state reader using the standalone snapshot in hash mode.
@ -90,7 +92,7 @@ func (db *MerkleDB) StateReader(stateRoot common.Hash) (StateReader, error) {
// Reader implements Database, returning a reader associated with the specified // Reader implements Database, returning a reader associated with the specified
// state root. // state root.
func (db *MerkleDB) Reader(stateRoot common.Hash) (Reader, error) { func (db *MPTDatabase) Reader(stateRoot common.Hash) (Reader, error) {
sr, err := db.StateReader(stateRoot) sr, err := db.StateReader(stateRoot)
if err != nil { if err != nil {
return nil, err return nil, err
@ -101,7 +103,7 @@ func (db *MerkleDB) Reader(stateRoot common.Hash) (Reader, error) {
// ReadersWithCacheStats creates a pair of state readers that share the same // ReadersWithCacheStats creates a pair of state readers that share the same
// underlying state reader and internal state cache, while maintaining separate // underlying state reader and internal state cache, while maintaining separate
// statistics respectively. // statistics respectively.
func (db *MerkleDB) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reader, error) { func (db *MPTDatabase) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reader, error) {
r, err := db.StateReader(stateRoot) r, err := db.StateReader(stateRoot)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@ -113,7 +115,7 @@ func (db *MerkleDB) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reader
} }
// OpenTrie opens the main account trie at a specific root hash. // OpenTrie opens the main account trie at a specific root hash.
func (db *MerkleDB) OpenTrie(root common.Hash) (Trie, error) { func (db *MPTDatabase) OpenTrie(root common.Hash) (Trie, error) {
tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb) tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb)
if err != nil { if err != nil {
return nil, err return nil, err
@ -122,7 +124,7 @@ func (db *MerkleDB) OpenTrie(root common.Hash) (Trie, error) {
} }
// OpenStorageTrie opens the storage trie of an account. // OpenStorageTrie opens the storage trie of an account.
func (db *MerkleDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, self Trie) (Trie, error) { func (db *MPTDatabase) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, self Trie) (Trie, error) {
tr, err := trie.NewStateTrie(trie.StorageTrieID(stateRoot, crypto.Keccak256Hash(address.Bytes()), root), db.triedb) tr, err := trie.NewStateTrie(trie.StorageTrieID(stateRoot, crypto.Keccak256Hash(address.Bytes()), root), db.triedb)
if err != nil { if err != nil {
return nil, err return nil, err
@ -131,19 +133,14 @@ func (db *MerkleDB) OpenStorageTrie(stateRoot common.Hash, address common.Addres
} }
// TrieDB retrieves any intermediate trie-node caching layer. // TrieDB retrieves any intermediate trie-node caching layer.
func (db *MerkleDB) TrieDB() *triedb.Database { func (db *MPTDatabase) TrieDB() *triedb.Database {
return db.triedb return db.triedb
} }
// Snapshot returns the underlying state snapshot.
func (db *MerkleDB) Snapshot() *snapshot.Tree {
return db.snap
}
// Commit flushes all pending writes and finalizes the state transition, // Commit flushes all pending writes and finalizes the state transition,
// committing the changes to the underlying storage. It returns an error // committing the changes to the underlying storage. It returns an error
// if the commit fails. // if the commit fails.
func (db *MerkleDB) Commit(update *stateUpdate) error { func (db *MPTDatabase) Commit(update *stateUpdate) error {
// Short circuit if nothing to commit // Short circuit if nothing to commit
if update.empty() { if update.empty() {
return nil return nil
@ -176,6 +173,6 @@ func (db *MerkleDB) Commit(update *stateUpdate) error {
// Iteratee returns a state iteratee associated with the specified state root, // Iteratee returns a state iteratee associated with the specified state root,
// through which the account iterator and storage iterator can be created. // through which the account iterator and storage iterator can be created.
func (db *MerkleDB) Iteratee(root common.Hash) (Iteratee, error) { func (db *MPTDatabase) Iteratee(root common.Hash) (Iteratee, error) {
return newStateIteratee(true, root, db.triedb, db.snap) return newStateIteratee(true, root, db.triedb, db.snap)
} }

View file

@ -19,41 +19,34 @@ package state
import ( import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state/snapshot"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/trie/bintrie" "github.com/ethereum/go-ethereum/trie/bintrie"
"github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb"
) )
// UBTDB is an implementation of Database interface for Universal Binary Tries. // UBTDatabase is an implementation of Database interface for Unified Binary Trie.
// It provides the same functionality as MerkleDB but uses binary tries for state // It provides the same functionality as MPTDatabase but uses unified binary
// storage instead of Merkle Patricia Tries. // trie for state hashing instead of Merkle Patricia Tries.
type UBTDB struct { type UBTDatabase struct {
triedb *triedb.Database triedb *triedb.Database
codedb *CodeDB codedb *CodeDB
snap *snapshot.Tree
} }
// NewUBTDB creates a state database with the Unified binary trie manner. // Type returns Binary, indicating this database is backed by a Universal Binary Trie.
func NewUBTDB(triedb *triedb.Database, codedb *CodeDB) *UBTDB { func (db *UBTDatabase) Type() DatabaseType { return TypeUBT }
// NewUBTDatabase creates a state database with the Unified binary trie manner.
func NewUBTDatabase(triedb *triedb.Database, codedb *CodeDB) *UBTDatabase {
if codedb == nil { if codedb == nil {
codedb = NewCodeDB(triedb.Disk()) codedb = NewCodeDB(triedb.Disk())
} }
return &UBTDB{ return &UBTDatabase{
triedb: triedb, triedb: triedb,
codedb: codedb, codedb: codedb,
} }
} }
// WithSnapshot configures the snapshot tree. Note that this registration must
// be performed before the UBTDB is used.
func (db *UBTDB) WithSnapshot(snapshot *snapshot.Tree) Database {
db.snap = snapshot
return db
}
// StateReader returns a state reader associated with the specified state root. // StateReader returns a state reader associated with the specified state root.
func (db *UBTDB) StateReader(stateRoot common.Hash) (StateReader, error) { func (db *UBTDatabase) StateReader(stateRoot common.Hash) (StateReader, error) {
var readers []StateReader var readers []StateReader
// Configure the state reader using the path database in path mode. // Configure the state reader using the path database in path mode.
@ -79,7 +72,7 @@ func (db *UBTDB) StateReader(stateRoot common.Hash) (StateReader, error) {
// Reader implements Database, returning a reader associated with the specified // Reader implements Database, returning a reader associated with the specified
// state root. // state root.
func (db *UBTDB) Reader(stateRoot common.Hash) (Reader, error) { func (db *UBTDatabase) Reader(stateRoot common.Hash) (Reader, error) {
sr, err := db.StateReader(stateRoot) sr, err := db.StateReader(stateRoot)
if err != nil { if err != nil {
return nil, err return nil, err
@ -90,7 +83,7 @@ func (db *UBTDB) Reader(stateRoot common.Hash) (Reader, error) {
// ReadersWithCacheStats creates a pair of state readers that share the same // ReadersWithCacheStats creates a pair of state readers that share the same
// underlying state reader and internal state cache, while maintaining separate // underlying state reader and internal state cache, while maintaining separate
// statistics respectively. // statistics respectively.
func (db *UBTDB) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reader, error) { func (db *UBTDatabase) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reader, error) {
r, err := db.StateReader(stateRoot) r, err := db.StateReader(stateRoot)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@ -102,30 +95,25 @@ func (db *UBTDB) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reader, e
} }
// OpenTrie opens the main account trie at a specific root hash. // OpenTrie opens the main account trie at a specific root hash.
func (db *UBTDB) OpenTrie(root common.Hash) (Trie, error) { func (db *UBTDatabase) OpenTrie(root common.Hash) (Trie, error) {
return bintrie.NewBinaryTrie(root, db.triedb) return bintrie.NewBinaryTrie(root, db.triedb)
} }
// OpenStorageTrie opens the storage trie of an account. In binary trie mode, // OpenStorageTrie opens the storage trie of an account. In binary trie mode,
// all state objects share one unified trie, so the main trie is returned. // all state objects share one unified trie, so the main trie is returned.
func (db *UBTDB) 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) {
return self, nil return self, nil
} }
// TrieDB retrieves any intermediate trie-node caching layer. // TrieDB retrieves any intermediate trie-node caching layer.
func (db *UBTDB) TrieDB() *triedb.Database { func (db *UBTDatabase) TrieDB() *triedb.Database {
return db.triedb return db.triedb
} }
// Snapshot returns the underlying state snapshot.
func (db *UBTDB) Snapshot() *snapshot.Tree {
return db.snap
}
// Commit flushes all pending writes and finalizes the state transition, // Commit flushes all pending writes and finalizes the state transition,
// committing the changes to the underlying storage. It returns an error // committing the changes to the underlying storage. It returns an error
// if the commit fails. // if the commit fails.
func (db *UBTDB) Commit(update *stateUpdate) error { func (db *UBTDatabase) Commit(update *stateUpdate) error {
// Short circuit if nothing to commit // Short circuit if nothing to commit
if update.empty() { if update.empty() {
return nil return nil
@ -140,24 +128,11 @@ func (db *UBTDB) Commit(update *stateUpdate) error {
return err return err
} }
} }
// If snapshotting is enabled, update the snapshot tree with this new version
if db.snap != nil && db.snap.Snapshot(update.originRoot) != nil {
if err := db.snap.Update(update.root, update.originRoot, update.accounts, update.storages); err != nil {
log.Warn("Failed to update snapshot tree", "from", update.originRoot, "to", update.root, "err", err)
}
// Keep 128 diff layers in the memory, persistent layer is 129th.
// - head layer is paired with HEAD state
// - head-1 layer is paired with HEAD-1 state
// - head-127 layer(bottom-most diff layer) is paired with HEAD-127 state
if err := db.snap.Cap(update.root, TriesInMemory); err != nil {
log.Warn("Failed to cap snapshot tree", "root", update.root, "layers", TriesInMemory, "err", err)
}
}
return db.triedb.Update(update.root, update.originRoot, update.blockNumber, update.nodes, update.stateSet()) return db.triedb.Update(update.root, update.originRoot, update.blockNumber, update.nodes, update.stateSet())
} }
// Iteratee returns a state iteratee associated with the specified state root, // Iteratee returns a state iteratee associated with the specified state root,
// through which the account iterator and storage iterator can be created. // through which the account iterator and storage iterator can be created.
func (db *UBTDB) Iteratee(root common.Hash) (Iteratee, error) { func (db *UBTDatabase) Iteratee(root common.Hash) (Iteratee, error) {
return newStateIteratee(false, root, db.triedb, db.snap) return newStateIteratee(false, root, db.triedb, nil)
} }

View file

@ -154,7 +154,7 @@ func (s *stateObject) getTrie() (Trie, error) {
func (s *stateObject) getPrefetchedTrie() Trie { func (s *stateObject) getPrefetchedTrie() Trie {
// If there's nothing to meaningfully return, let the user figure it out by // If there's nothing to meaningfully return, let the user figure it out by
// pulling the trie from disk. // pulling the trie from disk.
if (s.data.Root == types.EmptyRootHash && !s.db.db.TrieDB().IsUBT()) || s.db.prefetcher == nil { if (s.data.Root == types.EmptyRootHash && s.db.db.Type().Is(TypeMPT)) || s.db.prefetcher == nil {
return nil return nil
} }
// Attempt to retrieve the trie from the prefetcher // Attempt to retrieve the trie from the prefetcher

View file

@ -190,7 +190,7 @@ func NewWithReader(root common.Hash, db Database, reader Reader) (*StateDB, erro
accessList: newAccessList(), accessList: newAccessList(),
transientStorage: newTransientStorage(), transientStorage: newTransientStorage(),
} }
if db.TrieDB().IsUBT() { if db.Type().Is(TypeUBT) {
sdb.accessEvents = NewAccessEvents() sdb.accessEvents = NewAccessEvents()
} }
return sdb, nil return sdb, nil
@ -858,7 +858,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
start = time.Now() start = time.Now()
workers errgroup.Group workers errgroup.Group
) )
if s.db.TrieDB().IsUBT() { if s.db.Type().Is(TypeUBT) {
// Bypass per-account updateTrie() for binary trie. In binary trie mode // Bypass per-account updateTrie() for binary trie. In binary trie mode
// there is only one unified trie (OpenStorageTrie returns self), so the // there is only one unified trie (OpenStorageTrie returns self), so the
// per-account trie setup in updateTrie() (getPrefetchedTrie, getTrie, // per-account trie setup in updateTrie() (getPrefetchedTrie, getTrie,
@ -922,9 +922,9 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
} }
} }
// If witness building is enabled, gather all the read-only accesses. // If witness building is enabled, gather all the read-only accesses.
// Skip witness collection in Verkle mode, they will be gathered // Skip witness collection in Unified-binary-trie mode, they will be
// together at the end. // gathered together at the end.
if s.witness != nil && !s.db.TrieDB().IsUBT() { if s.witness != nil && s.db.Type().Is(TypeMPT) {
// Pull in anything that has been accessed before destruction // Pull in anything that has been accessed before destruction
for _, obj := range s.stateObjectsDestruct { for _, obj := range s.stateObjectsDestruct {
// Skip any objects that haven't touched their storage // Skip any objects that haven't touched their storage
@ -965,7 +965,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
// only a single trie is used for state hashing. Replacing a non-nil verkle tree // only a single trie is used for state hashing. Replacing a non-nil verkle tree
// here could result in losing uncommitted changes from storage. // here could result in losing uncommitted changes from storage.
start = time.Now() start = time.Now()
if s.prefetcher != nil && !s.db.TrieDB().IsUBT() { if s.prefetcher != nil && s.db.Type().Is(TypeMPT) {
if trie := s.prefetcher.trie(common.Hash{}, s.originalRoot); trie == nil { if trie := s.prefetcher.trie(common.Hash{}, s.originalRoot); trie == nil {
log.Error("Failed to retrieve account pre-fetcher trie") log.Error("Failed to retrieve account pre-fetcher trie")
} else { } else {
@ -1126,7 +1126,7 @@ func (s *StateDB) handleDestruction(noStorageWiping bool) (map[common.Hash]*acco
deletes[addrHash] = op deletes[addrHash] = op
// Short circuit if the origin storage was empty. // Short circuit if the origin storage was empty.
if prev.Root == types.EmptyRootHash || s.db.TrieDB().IsUBT() { if prev.Root == types.EmptyRootHash || s.db.Type().Is(TypeUBT) {
continue continue
} }
if noStorageWiping { if noStorageWiping {

View file

@ -209,7 +209,7 @@ func (test *stateTest) run() bool {
if i != 0 { if i != 0 {
root = roots[len(roots)-1] root = roots[len(roots)-1]
} }
state, err := New(root, NewDatabase(tdb, nil).WithSnapshot(snaps)) state, err := New(root, NewMPTDatabase(tdb, nil).WithSnapshot(snaps))
if err != nil { if err != nil {
panic(err) panic(err)
} }

View file

@ -1276,7 +1276,7 @@ func TestDeleteStorage(t *testing.T) {
disk = rawdb.NewMemoryDatabase() disk = rawdb.NewMemoryDatabase()
tdb = triedb.NewDatabase(disk, nil) tdb = triedb.NewDatabase(disk, nil)
snaps, _ = snapshot.New(snapshot.Config{CacheSize: 10}, disk, tdb, types.EmptyRootHash) snaps, _ = snapshot.New(snapshot.Config{CacheSize: 10}, disk, tdb, types.EmptyRootHash)
db = NewDatabase(tdb, nil).WithSnapshot(snaps) db = NewMPTDatabase(tdb, nil).WithSnapshot(snaps)
state, _ = New(types.EmptyRootHash, db) state, _ = New(types.EmptyRootHash, db)
addr = common.HexToAddress("0x1") addr = common.HexToAddress("0x1")
) )
@ -1290,8 +1290,8 @@ func TestDeleteStorage(t *testing.T) {
} }
root, _ := state.Commit(0, true, false) root, _ := state.Commit(0, true, false)
// Init phase done, create two states, one with snap and one without // Init phase done, create two states, one with snap and one without
fastState, _ := New(root, NewDatabase(tdb, nil).WithSnapshot(snaps)) fastState, _ := New(root, NewMPTDatabase(tdb, nil).WithSnapshot(snaps))
slowState, _ := New(root, NewDatabase(tdb, nil)) slowState, _ := New(root, NewMPTDatabase(tdb, nil))
obj := fastState.getOrNewStateObject(addr) obj := fastState.getOrNewStateObject(addr)
storageRoot := obj.data.Root storageRoot := obj.data.Root

View file

@ -40,7 +40,7 @@ var (
// //
// Note, the prefetcher's API is not thread safe. // Note, the prefetcher's API is not thread safe.
type triePrefetcher struct { type triePrefetcher struct {
verkle bool // Flag whether the prefetcher is in verkle mode isUBT bool // Flag whether the prefetcher is in UBT mode
db Database // Database to fetch trie nodes through db Database // Database to fetch trie nodes through
root common.Hash // Root hash of the account trie for metrics root common.Hash // Root hash of the account trie for metrics
fetchers map[string]*subfetcher // Subfetchers for each trie fetchers map[string]*subfetcher // Subfetchers for each trie
@ -67,7 +67,7 @@ type triePrefetcher struct {
func newTriePrefetcher(db Database, root common.Hash, namespace string, noreads bool) *triePrefetcher { func newTriePrefetcher(db Database, root common.Hash, namespace string, noreads bool) *triePrefetcher {
prefix := triePrefetchMetricsPrefix + namespace prefix := triePrefetchMetricsPrefix + namespace
return &triePrefetcher{ return &triePrefetcher{
verkle: db.TrieDB().IsUBT(), isUBT: db.Type().Is(TypeUBT),
db: db, db: db,
root: root, root: root,
fetchers: make(map[string]*subfetcher), // Active prefetchers use the fetchers map fetchers: make(map[string]*subfetcher), // Active prefetchers use the fetchers map
@ -206,8 +206,8 @@ func (p *triePrefetcher) used(owner common.Hash, root common.Hash, usedAddr []co
// trieID returns an unique trie identifier consists the trie owner and root hash. // trieID returns an unique trie identifier consists the trie owner and root hash.
func (p *triePrefetcher) trieID(owner common.Hash, root common.Hash) string { func (p *triePrefetcher) trieID(owner common.Hash, root common.Hash) string {
// The trie in verkle is only identified by state root // The trie in ubt is only identified by state root
if p.verkle { if p.isUBT {
return p.root.Hex() return p.root.Hex()
} }
// The trie in merkle is either identified by state root (account trie), // The trie in merkle is either identified by state root (account trie),
@ -340,12 +340,12 @@ func (sf *subfetcher) terminate(async bool) {
// openTrie resolves the target trie from database for prefetching. // openTrie resolves the target trie from database for prefetching.
func (sf *subfetcher) openTrie() error { func (sf *subfetcher) openTrie() error {
// Open the verkle tree if the sub-fetcher is in verkle mode. Note, there is // Open the ubt tree if the sub-fetcher is in ubt mode. Note, there is
// only a single fetcher for verkle. // only a single fetcher for ubt.
if sf.db.TrieDB().IsUBT() { if sf.db.Type().Is(TypeUBT) {
tr, err := sf.db.OpenTrie(sf.state) tr, err := sf.db.OpenTrie(sf.state)
if err != nil { if err != nil {
log.Warn("Trie prefetcher failed opening verkle trie", "root", sf.root, "err", err) log.Warn("Trie prefetcher failed opening UBT trie", "root", sf.root, "err", err)
return err return err
} }
sf.trie = tr sf.trie = tr

View file

@ -182,7 +182,7 @@ func ApplyTransactionWithEVM(msg *Message, gp *GasPool, statedb *state.StateDB,
} }
// Merge the tx-local access event into the "block-local" one, in order to collect // Merge the tx-local access event into the "block-local" one, in order to collect
// all values, so that the witness can be built. // all values, so that the witness can be built.
if statedb.Database().TrieDB().IsUBT() { if statedb.Database().Type().Is(state.TypeUBT) {
statedb.AccessEvents().Merge(evm.AccessEvents) statedb.AccessEvents().Merge(evm.AccessEvents)
} }
return MakeReceipt(evm, result, statedb, blockNumber, blockHash, blockTime, tx, gp.CumulativeUsed(), root), nil return MakeReceipt(evm, result, statedb, blockNumber, blockHash, blockTime, tx, gp.CumulativeUsed(), root), nil

View file

@ -544,7 +544,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bo
} }
snaps, _ = snapshot.New(snapconfig, db, triedb, root) snaps, _ = snapshot.New(snapconfig, db, triedb, root)
} }
sdb = state.NewDatabase(triedb, nil).WithSnapshot(snaps) sdb = state.NewMPTDatabase(triedb, nil).WithSnapshot(snaps)
statedb, _ = state.New(root, sdb) statedb, _ = state.New(root, sdb)
return StateTestState{statedb, triedb, snaps} return StateTestState{statedb, triedb, snaps}
} }

View file

@ -55,9 +55,9 @@ func TestLayerCap(t *testing.T) {
layers: 2, layers: 2,
base: common.Hash{0x2}, base: common.Hash{0x2},
snapshot: map[common.Hash]struct{}{ snapshot: map[common.Hash]struct{}{
common.Hash{0x2}: {}, {0x2}: {},
common.Hash{0x3}: {}, {0x3}: {},
common.Hash{0x4}: {}, {0x4}: {},
}, },
}, },
{ {
@ -76,8 +76,8 @@ func TestLayerCap(t *testing.T) {
layers: 1, layers: 1,
base: common.Hash{0x3}, base: common.Hash{0x3},
snapshot: map[common.Hash]struct{}{ snapshot: map[common.Hash]struct{}{
common.Hash{0x3}: {}, {0x3}: {},
common.Hash{0x4}: {}, {0x4}: {},
}, },
}, },
{ {
@ -96,7 +96,7 @@ func TestLayerCap(t *testing.T) {
layers: 0, layers: 0,
base: common.Hash{0x4}, base: common.Hash{0x4},
snapshot: map[common.Hash]struct{}{ snapshot: map[common.Hash]struct{}{
common.Hash{0x4}: {}, {0x4}: {},
}, },
}, },
{ {
@ -119,9 +119,9 @@ func TestLayerCap(t *testing.T) {
layers: 2, layers: 2,
base: common.Hash{0x2a}, base: common.Hash{0x2a},
snapshot: map[common.Hash]struct{}{ snapshot: map[common.Hash]struct{}{
common.Hash{0x4a}: {}, {0x4a}: {},
common.Hash{0x3a}: {}, {0x3a}: {},
common.Hash{0x2a}: {}, {0x2a}: {},
}, },
}, },
{ {
@ -144,8 +144,8 @@ func TestLayerCap(t *testing.T) {
layers: 1, layers: 1,
base: common.Hash{0x3a}, base: common.Hash{0x3a},
snapshot: map[common.Hash]struct{}{ snapshot: map[common.Hash]struct{}{
common.Hash{0x4a}: {}, {0x4a}: {},
common.Hash{0x3a}: {}, {0x3a}: {},
}, },
}, },
{ {
@ -168,11 +168,11 @@ func TestLayerCap(t *testing.T) {
layers: 2, layers: 2,
base: common.Hash{0x2}, base: common.Hash{0x2},
snapshot: map[common.Hash]struct{}{ snapshot: map[common.Hash]struct{}{
common.Hash{0x4a}: {}, {0x4a}: {},
common.Hash{0x3a}: {}, {0x3a}: {},
common.Hash{0x4b}: {}, {0x4b}: {},
common.Hash{0x3b}: {}, {0x3b}: {},
common.Hash{0x2}: {}, {0x2}: {},
}, },
}, },
} }
@ -261,7 +261,7 @@ func TestDescendant(t *testing.T) {
return tr return tr
}, },
snapshotA: map[common.Hash]map[common.Hash]struct{}{ snapshotA: map[common.Hash]map[common.Hash]struct{}{
common.Hash{0x1}: { {0x1}: {
common.Hash{0x2}: {}, common.Hash{0x2}: {},
}, },
}, },
@ -271,11 +271,11 @@ func TestDescendant(t *testing.T) {
tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false))
}, },
snapshotB: map[common.Hash]map[common.Hash]struct{}{ snapshotB: map[common.Hash]map[common.Hash]struct{}{
common.Hash{0x1}: { {0x1}: {
common.Hash{0x2}: {}, common.Hash{0x2}: {},
common.Hash{0x3}: {}, common.Hash{0x3}: {},
}, },
common.Hash{0x2}: { {0x2}: {
common.Hash{0x3}: {}, common.Hash{0x3}: {},
}, },
}, },
@ -291,16 +291,16 @@ func TestDescendant(t *testing.T) {
return tr return tr
}, },
snapshotA: map[common.Hash]map[common.Hash]struct{}{ snapshotA: map[common.Hash]map[common.Hash]struct{}{
common.Hash{0x1}: { {0x1}: {
common.Hash{0x2}: {}, common.Hash{0x2}: {},
common.Hash{0x3}: {}, common.Hash{0x3}: {},
common.Hash{0x4}: {}, common.Hash{0x4}: {},
}, },
common.Hash{0x2}: { {0x2}: {
common.Hash{0x3}: {}, common.Hash{0x3}: {},
common.Hash{0x4}: {}, common.Hash{0x4}: {},
}, },
common.Hash{0x3}: { {0x3}: {
common.Hash{0x4}: {}, common.Hash{0x4}: {},
}, },
}, },
@ -310,11 +310,11 @@ func TestDescendant(t *testing.T) {
tr.cap(common.Hash{0x4}, 2) tr.cap(common.Hash{0x4}, 2)
}, },
snapshotB: map[common.Hash]map[common.Hash]struct{}{ snapshotB: map[common.Hash]map[common.Hash]struct{}{
common.Hash{0x2}: { {0x2}: {
common.Hash{0x3}: {}, common.Hash{0x3}: {},
common.Hash{0x4}: {}, common.Hash{0x4}: {},
}, },
common.Hash{0x3}: { {0x3}: {
common.Hash{0x4}: {}, common.Hash{0x4}: {},
}, },
}, },
@ -330,16 +330,16 @@ func TestDescendant(t *testing.T) {
return tr return tr
}, },
snapshotA: map[common.Hash]map[common.Hash]struct{}{ snapshotA: map[common.Hash]map[common.Hash]struct{}{
common.Hash{0x1}: { {0x1}: {
common.Hash{0x2}: {}, common.Hash{0x2}: {},
common.Hash{0x3}: {}, common.Hash{0x3}: {},
common.Hash{0x4}: {}, common.Hash{0x4}: {},
}, },
common.Hash{0x2}: { {0x2}: {
common.Hash{0x3}: {}, common.Hash{0x3}: {},
common.Hash{0x4}: {}, common.Hash{0x4}: {},
}, },
common.Hash{0x3}: { {0x3}: {
common.Hash{0x4}: {}, common.Hash{0x4}: {},
}, },
}, },
@ -349,7 +349,7 @@ func TestDescendant(t *testing.T) {
tr.cap(common.Hash{0x4}, 1) tr.cap(common.Hash{0x4}, 1)
}, },
snapshotB: map[common.Hash]map[common.Hash]struct{}{ snapshotB: map[common.Hash]map[common.Hash]struct{}{
common.Hash{0x3}: { {0x3}: {
common.Hash{0x4}: {}, common.Hash{0x4}: {},
}, },
}, },
@ -365,16 +365,16 @@ func TestDescendant(t *testing.T) {
return tr return tr
}, },
snapshotA: map[common.Hash]map[common.Hash]struct{}{ snapshotA: map[common.Hash]map[common.Hash]struct{}{
common.Hash{0x1}: { {0x1}: {
common.Hash{0x2}: {}, common.Hash{0x2}: {},
common.Hash{0x3}: {}, common.Hash{0x3}: {},
common.Hash{0x4}: {}, common.Hash{0x4}: {},
}, },
common.Hash{0x2}: { {0x2}: {
common.Hash{0x3}: {}, common.Hash{0x3}: {},
common.Hash{0x4}: {}, common.Hash{0x4}: {},
}, },
common.Hash{0x3}: { {0x3}: {
common.Hash{0x4}: {}, common.Hash{0x4}: {},
}, },
}, },
@ -400,7 +400,7 @@ func TestDescendant(t *testing.T) {
return tr return tr
}, },
snapshotA: map[common.Hash]map[common.Hash]struct{}{ snapshotA: map[common.Hash]map[common.Hash]struct{}{
common.Hash{0x1}: { {0x1}: {
common.Hash{0x2a}: {}, common.Hash{0x2a}: {},
common.Hash{0x3a}: {}, common.Hash{0x3a}: {},
common.Hash{0x4a}: {}, common.Hash{0x4a}: {},
@ -408,18 +408,18 @@ func TestDescendant(t *testing.T) {
common.Hash{0x3b}: {}, common.Hash{0x3b}: {},
common.Hash{0x4b}: {}, common.Hash{0x4b}: {},
}, },
common.Hash{0x2a}: { {0x2a}: {
common.Hash{0x3a}: {}, common.Hash{0x3a}: {},
common.Hash{0x4a}: {}, common.Hash{0x4a}: {},
}, },
common.Hash{0x3a}: { {0x3a}: {
common.Hash{0x4a}: {}, common.Hash{0x4a}: {},
}, },
common.Hash{0x2b}: { {0x2b}: {
common.Hash{0x3b}: {}, common.Hash{0x3b}: {},
common.Hash{0x4b}: {}, common.Hash{0x4b}: {},
}, },
common.Hash{0x3b}: { {0x3b}: {
common.Hash{0x4b}: {}, common.Hash{0x4b}: {},
}, },
}, },
@ -429,11 +429,11 @@ func TestDescendant(t *testing.T) {
tr.cap(common.Hash{0x4a}, 2) tr.cap(common.Hash{0x4a}, 2)
}, },
snapshotB: map[common.Hash]map[common.Hash]struct{}{ snapshotB: map[common.Hash]map[common.Hash]struct{}{
common.Hash{0x2a}: { {0x2a}: {
common.Hash{0x3a}: {}, common.Hash{0x3a}: {},
common.Hash{0x4a}: {}, common.Hash{0x4a}: {},
}, },
common.Hash{0x3a}: { {0x3a}: {
common.Hash{0x4a}: {}, common.Hash{0x4a}: {},
}, },
}, },
@ -453,7 +453,7 @@ func TestDescendant(t *testing.T) {
return tr return tr
}, },
snapshotA: map[common.Hash]map[common.Hash]struct{}{ snapshotA: map[common.Hash]map[common.Hash]struct{}{
common.Hash{0x1}: { {0x1}: {
common.Hash{0x2a}: {}, common.Hash{0x2a}: {},
common.Hash{0x3a}: {}, common.Hash{0x3a}: {},
common.Hash{0x4a}: {}, common.Hash{0x4a}: {},
@ -461,18 +461,18 @@ func TestDescendant(t *testing.T) {
common.Hash{0x3b}: {}, common.Hash{0x3b}: {},
common.Hash{0x4b}: {}, common.Hash{0x4b}: {},
}, },
common.Hash{0x2a}: { {0x2a}: {
common.Hash{0x3a}: {}, common.Hash{0x3a}: {},
common.Hash{0x4a}: {}, common.Hash{0x4a}: {},
}, },
common.Hash{0x3a}: { {0x3a}: {
common.Hash{0x4a}: {}, common.Hash{0x4a}: {},
}, },
common.Hash{0x2b}: { {0x2b}: {
common.Hash{0x3b}: {}, common.Hash{0x3b}: {},
common.Hash{0x4b}: {}, common.Hash{0x4b}: {},
}, },
common.Hash{0x3b}: { {0x3b}: {
common.Hash{0x4b}: {}, common.Hash{0x4b}: {},
}, },
}, },
@ -482,7 +482,7 @@ func TestDescendant(t *testing.T) {
tr.cap(common.Hash{0x4a}, 1) tr.cap(common.Hash{0x4a}, 1)
}, },
snapshotB: map[common.Hash]map[common.Hash]struct{}{ snapshotB: map[common.Hash]map[common.Hash]struct{}{
common.Hash{0x3a}: { {0x3a}: {
common.Hash{0x4a}: {}, common.Hash{0x4a}: {},
}, },
}, },
@ -501,23 +501,23 @@ func TestDescendant(t *testing.T) {
return tr return tr
}, },
snapshotA: map[common.Hash]map[common.Hash]struct{}{ snapshotA: map[common.Hash]map[common.Hash]struct{}{
common.Hash{0x1}: { {0x1}: {
common.Hash{0x2}: {}, common.Hash{0x2}: {},
common.Hash{0x3a}: {}, common.Hash{0x3a}: {},
common.Hash{0x4a}: {}, common.Hash{0x4a}: {},
common.Hash{0x3b}: {}, common.Hash{0x3b}: {},
common.Hash{0x4b}: {}, common.Hash{0x4b}: {},
}, },
common.Hash{0x2}: { {0x2}: {
common.Hash{0x3a}: {}, common.Hash{0x3a}: {},
common.Hash{0x4a}: {}, common.Hash{0x4a}: {},
common.Hash{0x3b}: {}, common.Hash{0x3b}: {},
common.Hash{0x4b}: {}, common.Hash{0x4b}: {},
}, },
common.Hash{0x3a}: { {0x3a}: {
common.Hash{0x4a}: {}, common.Hash{0x4a}: {},
}, },
common.Hash{0x3b}: { {0x3b}: {
common.Hash{0x4b}: {}, common.Hash{0x4b}: {},
}, },
}, },
@ -528,16 +528,16 @@ func TestDescendant(t *testing.T) {
tr.cap(common.Hash{0x4a}, 2) tr.cap(common.Hash{0x4a}, 2)
}, },
snapshotB: map[common.Hash]map[common.Hash]struct{}{ snapshotB: map[common.Hash]map[common.Hash]struct{}{
common.Hash{0x2}: { {0x2}: {
common.Hash{0x3a}: {}, common.Hash{0x3a}: {},
common.Hash{0x4a}: {}, common.Hash{0x4a}: {},
common.Hash{0x3b}: {}, common.Hash{0x3b}: {},
common.Hash{0x4b}: {}, common.Hash{0x4b}: {},
}, },
common.Hash{0x3a}: { {0x3a}: {
common.Hash{0x4a}: {}, common.Hash{0x4a}: {},
}, },
common.Hash{0x3b}: { {0x3b}: {
common.Hash{0x4b}: {}, common.Hash{0x4b}: {},
}, },
}, },