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
if bc.chainConfig.IsUBT(block.Number(), block.Time()) {
sdb = state.NewUBTDB(bc.triedb, bc.codedb)
sdb = state.NewUBTDatabase(bc.triedb, bc.codedb)
} 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
// 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.
func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
// 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.

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
// 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.txs = append(b.txs, tx)

View file

@ -21,7 +21,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"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/ethdb"
"github.com/ethereum/go-ethereum/trie"
@ -30,8 +29,27 @@ import (
"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.
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(root common.Hash) (Reader, error)
@ -52,9 +70,6 @@ type Database interface {
// committing the changes to the underlying storage. It returns an error
// if the commit fails.
Commit(update *stateUpdate) error
// Snapshot returns the underlying state snapshot.
Snapshot() *snapshot.Tree
}
// Trie is a Ethereum Merkle Patricia trie.
@ -144,12 +159,12 @@ type Trie interface {
// 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 {
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

View file

@ -22,7 +22,6 @@ import (
"sync"
"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/crypto"
"github.com/ethereum/go-ethereum/rlp"
@ -224,6 +223,12 @@ type HistoricDB struct {
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.
func NewHistoricDatabase(triedb *triedb.Database, codedb *CodeDB) *HistoricDB {
return &HistoricDB{
@ -301,18 +306,3 @@ func (db *HistoricDB) Commit(update *stateUpdate) error {
func (db *HistoricDB) Iteratee(root common.Hash) (Iteratee, error) {
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"
)
// 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
// access. It's meant to be a long-live object and has a few caches inside for
// sharing between blocks.
type MerkleDB struct {
// access.
type MPTDatabase struct {
triedb *triedb.Database
codedb *CodeDB
snap *snapshot.Tree
}
// NewMerkleDB creates a state database with the Merkle Patricia Trie manner.
func NewMerkleDB(tdb *triedb.Database, codedb *CodeDB) *MerkleDB {
// Type returns Merkle, indicating this database is backed by a Merkle Patricia Trie.
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 {
codedb = NewCodeDB(tdb.Disk())
}
return &MerkleDB{
return &MPTDatabase{
triedb: tdb,
codedb: codedb,
}
}
// WithSnapshot configures the provided contract code cache. Note that this
// registration must be performed before the MerkleDB is used.
func (db *MerkleDB) WithSnapshot(snapshot *snapshot.Tree) Database {
// WithSnapshot configures the provided state snapshot. Note that this
// registration must be performed before the MPTDatabase is used.
func (db *MPTDatabase) WithSnapshot(snapshot *snapshot.Tree) Database {
db.snap = snapshot
return db
}
// 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
// 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
// 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)
if err != nil {
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
// underlying state reader and internal state cache, while maintaining separate
// 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)
if err != nil {
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.
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)
if err != nil {
return nil, err
@ -122,7 +124,7 @@ func (db *MerkleDB) OpenTrie(root common.Hash) (Trie, error) {
}
// 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)
if err != nil {
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.
func (db *MerkleDB) TrieDB() *triedb.Database {
func (db *MPTDatabase) TrieDB() *triedb.Database {
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,
// committing the changes to the underlying storage. It returns an error
// if the commit fails.
func (db *MerkleDB) Commit(update *stateUpdate) error {
func (db *MPTDatabase) Commit(update *stateUpdate) error {
// Short circuit if nothing to commit
if update.empty() {
return nil
@ -176,6 +173,6 @@ func (db *MerkleDB) Commit(update *stateUpdate) error {
// Iteratee returns a state iteratee associated with the specified state root,
// 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)
}

View file

@ -19,41 +19,34 @@ package state
import (
"github.com/ethereum/go-ethereum/common"
"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/triedb"
)
// UBTDB is an implementation of Database interface for Universal Binary Tries.
// It provides the same functionality as MerkleDB but uses binary tries for state
// storage instead of Merkle Patricia Tries.
type UBTDB struct {
// UBTDatabase is an implementation of Database interface for Unified Binary Trie.
// It provides the same functionality as MPTDatabase but uses unified binary
// trie for state hashing instead of Merkle Patricia Tries.
type UBTDatabase struct {
triedb *triedb.Database
codedb *CodeDB
snap *snapshot.Tree
}
// NewUBTDB creates a state database with the Unified binary trie manner.
func NewUBTDB(triedb *triedb.Database, codedb *CodeDB) *UBTDB {
// Type returns Binary, indicating this database is backed by a Universal Binary Trie.
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 {
codedb = NewCodeDB(triedb.Disk())
}
return &UBTDB{
return &UBTDatabase{
triedb: triedb,
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.
func (db *UBTDB) StateReader(stateRoot common.Hash) (StateReader, error) {
func (db *UBTDatabase) StateReader(stateRoot common.Hash) (StateReader, error) {
var readers []StateReader
// 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
// 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)
if err != nil {
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
// underlying state reader and internal state cache, while maintaining separate
// 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)
if err != nil {
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.
func (db *UBTDB) OpenTrie(root common.Hash) (Trie, error) {
func (db *UBTDatabase) OpenTrie(root common.Hash) (Trie, error) {
return bintrie.NewBinaryTrie(root, db.triedb)
}
// 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.
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
}
// TrieDB retrieves any intermediate trie-node caching layer.
func (db *UBTDB) TrieDB() *triedb.Database {
func (db *UBTDatabase) TrieDB() *triedb.Database {
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,
// committing the changes to the underlying storage. It returns an error
// if the commit fails.
func (db *UBTDB) Commit(update *stateUpdate) error {
func (db *UBTDatabase) Commit(update *stateUpdate) error {
// Short circuit if nothing to commit
if update.empty() {
return nil
@ -140,24 +128,11 @@ func (db *UBTDB) Commit(update *stateUpdate) error {
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())
}
// Iteratee returns a state iteratee associated with the specified state root,
// through which the account iterator and storage iterator can be created.
func (db *UBTDB) Iteratee(root common.Hash) (Iteratee, error) {
return newStateIteratee(false, root, db.triedb, db.snap)
func (db *UBTDatabase) Iteratee(root common.Hash) (Iteratee, error) {
return newStateIteratee(false, root, db.triedb, nil)
}

View file

@ -154,7 +154,7 @@ func (s *stateObject) getTrie() (Trie, error) {
func (s *stateObject) getPrefetchedTrie() Trie {
// If there's nothing to meaningfully return, let the user figure it out by
// 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
}
// 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(),
transientStorage: newTransientStorage(),
}
if db.TrieDB().IsUBT() {
if db.Type().Is(TypeUBT) {
sdb.accessEvents = NewAccessEvents()
}
return sdb, nil
@ -858,7 +858,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
start = time.Now()
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
// there is only one unified trie (OpenStorageTrie returns self), so the
// 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.
// Skip witness collection in Verkle mode, they will be gathered
// together at the end.
if s.witness != nil && !s.db.TrieDB().IsUBT() {
// Skip witness collection in Unified-binary-trie mode, they will be
// gathered together at the end.
if s.witness != nil && s.db.Type().Is(TypeMPT) {
// Pull in anything that has been accessed before destruction
for _, obj := range s.stateObjectsDestruct {
// 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
// here could result in losing uncommitted changes from storage.
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 {
log.Error("Failed to retrieve account pre-fetcher trie")
} else {
@ -1126,7 +1126,7 @@ func (s *StateDB) handleDestruction(noStorageWiping bool) (map[common.Hash]*acco
deletes[addrHash] = op
// 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
}
if noStorageWiping {

View file

@ -209,7 +209,7 @@ func (test *stateTest) run() bool {
if i != 0 {
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 {
panic(err)
}

View file

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

View file

@ -40,7 +40,7 @@ var (
//
// Note, the prefetcher's API is not thread safe.
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
root common.Hash // Root hash of the account trie for metrics
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 {
prefix := triePrefetchMetricsPrefix + namespace
return &triePrefetcher{
verkle: db.TrieDB().IsUBT(),
isUBT: db.Type().Is(TypeUBT),
db: db,
root: root,
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.
func (p *triePrefetcher) trieID(owner common.Hash, root common.Hash) string {
// The trie in verkle is only identified by state root
if p.verkle {
// The trie in ubt is only identified by state root
if p.isUBT {
return p.root.Hex()
}
// 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.
func (sf *subfetcher) openTrie() error {
// Open the verkle tree if the sub-fetcher is in verkle mode. Note, there is
// only a single fetcher for verkle.
if sf.db.TrieDB().IsUBT() {
// Open the ubt tree if the sub-fetcher is in ubt mode. Note, there is
// only a single fetcher for ubt.
if sf.db.Type().Is(TypeUBT) {
tr, err := sf.db.OpenTrie(sf.state)
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
}
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
// 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)
}
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)
}
sdb = state.NewDatabase(triedb, nil).WithSnapshot(snaps)
sdb = state.NewMPTDatabase(triedb, nil).WithSnapshot(snaps)
statedb, _ = state.New(root, sdb)
return StateTestState{statedb, triedb, snaps}
}

View file

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