diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index efe22d36f5..f17829ec53 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -146,7 +146,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, return h } var ( - isEIP4762 = chainConfig.IsVerkle(big.NewInt(int64(pre.Env.Number)), pre.Env.Timestamp) + isEIP4762 = chainConfig.IsUBT(big.NewInt(int64(pre.Env.Number)), pre.Env.Timestamp) statedb = MakePreState(rawdb.NewMemoryDatabase(), pre.Pre, isEIP4762) signer = types.MakeSigner(chainConfig, new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp) gaspool = core.NewGasPool(pre.Env.GasLimit) @@ -378,7 +378,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, } func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, isBintrie bool) *state.StateDB { - tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true, IsVerkle: isBintrie}) + tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true, IsUBT: isBintrie}) sdb := state.NewDatabase(tdb, nil) root := types.EmptyRootHash diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index d7cdc98e74..6a23e9dc70 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -228,7 +228,7 @@ func Transition(ctx *cli.Context) error { collector = make(Alloc) btleaves map[common.Hash]hexutil.Bytes ) - isBinary := chainConfig.IsVerkle(big.NewInt(int64(prestate.Env.Number)), prestate.Env.Timestamp) + isBinary := chainConfig.IsUBT(big.NewInt(int64(prestate.Env.Number)), prestate.Env.Timestamp) if !isBinary { s.DumpToCollector(collector, nil) } else { @@ -452,7 +452,7 @@ func BinKeys(ctx *cli.Context) error { return err } } - db := triedb.NewDatabase(rawdb.NewMemoryDatabase(), triedb.VerkleDefaults) + db := triedb.NewDatabase(rawdb.NewMemoryDatabase(), triedb.UBTDefaults) defer db.Close() bt, err := genBinTrieFromAlloc(alloc, db) @@ -496,7 +496,7 @@ func BinTrieRoot(ctx *cli.Context) error { return err } } - db := triedb.NewDatabase(rawdb.NewMemoryDatabase(), triedb.VerkleDefaults) + db := triedb.NewDatabase(rawdb.NewMemoryDatabase(), triedb.UBTDefaults) defer db.Close() bt, err := genBinTrieFromAlloc(alloc, db) diff --git a/cmd/geth/bintrie_convert.go b/cmd/geth/bintrie_convert.go index 3730768697..43d2e629ac 100644 --- a/cmd/geth/bintrie_convert.go +++ b/cmd/geth/bintrie_convert.go @@ -144,7 +144,7 @@ func convertToBinaryTrie(ctx *cli.Context) error { defer srcTriedb.Close() destTriedb := triedb.NewDatabase(chaindb, &triedb.Config{ - IsVerkle: true, + IsUBT: true, PathDB: &pathdb.Config{ JournalDirectory: stack.ResolvePath("triedb-bintrie"), }, diff --git a/cmd/geth/bintrie_convert_test.go b/cmd/geth/bintrie_convert_test.go index 9b95f6a70f..5a5fa495fa 100644 --- a/cmd/geth/bintrie_convert_test.go +++ b/cmd/geth/bintrie_convert_test.go @@ -82,7 +82,7 @@ func TestBintrieConvert(t *testing.T) { defer srcTriedb2.Close() destTriedb := triedb.NewDatabase(chaindb, &triedb.Config{ - IsVerkle: true, + IsUBT: true, PathDB: pathdb.Defaults, }) defer destTriedb.Close() @@ -190,7 +190,7 @@ func TestBintrieConvertDeleteSource(t *testing.T) { }) destTriedb := triedb.NewDatabase(chaindb, &triedb.Config{ - IsVerkle: true, + IsUBT: true, PathDB: pathdb.Defaults, }) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index 1084100f39..0aacb0878a 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -64,7 +64,7 @@ var ( utils.OverrideOsaka, utils.OverrideBPO1, utils.OverrideBPO2, - utils.OverrideVerkle, + utils.OverrideUBT, }, utils.DatabaseFlags), Description: ` The init command initializes a new genesis block and definition for the network. @@ -297,15 +297,15 @@ func initGenesis(ctx *cli.Context) error { v := ctx.Uint64(utils.OverrideBPO2.Name) overrides.OverrideBPO2 = &v } - if ctx.IsSet(utils.OverrideVerkle.Name) { - v := ctx.Uint64(utils.OverrideVerkle.Name) - overrides.OverrideVerkle = &v + if ctx.IsSet(utils.OverrideUBT.Name) { + v := ctx.Uint64(utils.OverrideUBT.Name) + overrides.OverrideUBT = &v } chaindb := utils.MakeChainDatabase(ctx, stack, false) defer chaindb.Close() - triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle()) + triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsUBT()) defer triedb.Close() _, hash, compatErr, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides, nil) diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 720d1ef9fc..8e2db32d76 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -235,9 +235,9 @@ func makeFullNode(ctx *cli.Context) *node.Node { v := ctx.Uint64(utils.OverrideBPO2.Name) cfg.Eth.OverrideBPO2 = &v } - if ctx.IsSet(utils.OverrideVerkle.Name) { - v := ctx.Uint64(utils.OverrideVerkle.Name) - cfg.Eth.OverrideVerkle = &v + if ctx.IsSet(utils.OverrideUBT.Name) { + v := ctx.Uint64(utils.OverrideUBT.Name) + cfg.Eth.OverrideUBT = &v } // Start metrics export if enabled. diff --git a/cmd/geth/main.go b/cmd/geth/main.go index e196ac8688..ae869ec970 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -64,7 +64,7 @@ var ( utils.OverrideOsaka, utils.OverrideBPO1, utils.OverrideBPO2, - utils.OverrideVerkle, + utils.OverrideUBT, utils.OverrideGenesisFlag, utils.EnablePersonal, // deprecated utils.TxPoolLocalsFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index c1284044eb..8089819140 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -264,9 +264,9 @@ var ( Usage: "Manually specify the bpo2 fork timestamp, overriding the bundled setting", Category: flags.EthCategory, } - OverrideVerkle = &cli.Uint64Flag{ - Name: "override.verkle", - Usage: "Manually specify the Verkle fork timestamp, overriding the bundled setting", + OverrideUBT = &cli.Uint64Flag{ + Name: "override.ubt", + Usage: "Manually specify the UBT fork timestamp, overriding the bundled setting", Category: flags.EthCategory, } OverrideGenesisFlag = &cli.StringFlag{ @@ -2516,10 +2516,10 @@ func MakeConsolePreloads(ctx *cli.Context) []string { } // MakeTrieDatabase constructs a trie database based on the configured scheme. -func MakeTrieDatabase(ctx *cli.Context, stack *node.Node, disk ethdb.Database, preimage bool, readOnly bool, isVerkle bool) *triedb.Database { +func MakeTrieDatabase(ctx *cli.Context, stack *node.Node, disk ethdb.Database, preimage bool, readOnly bool, isUBT bool) *triedb.Database { config := &triedb.Config{ Preimages: preimage, - IsVerkle: isVerkle, + IsUBT: isUBT, } scheme, err := rawdb.ParseStateScheme(ctx.String(StateSchemeFlag.Name), disk) if err != nil { diff --git a/core/bintrie_witness_test.go b/core/bintrie_witness_test.go index 7704ba41fb..492fbdb833 100644 --- a/core/bintrie_witness_test.go +++ b/core/bintrie_witness_test.go @@ -51,9 +51,9 @@ var ( LondonBlock: big.NewInt(0), Ethash: new(params.EthashConfig), ShanghaiTime: u64(0), - VerkleTime: u64(0), + UBTTime: u64(0), TerminalTotalDifficulty: common.Big0, - EnableVerkleAtGenesis: true, + EnableUBTAtGenesis: true, BlobScheduleConfig: ¶ms.BlobScheduleConfig{ Verkle: params.DefaultPragueBlobConfig, }, @@ -188,7 +188,7 @@ func TestProcessParentBlockHash(t *testing.T) { // block 1 parent hash is 0x0100.... // block 2 parent hash is 0x0200.... // etc - checkBlockHashes := func(statedb *state.StateDB, isVerkle bool) { + checkBlockHashes := func(statedb *state.StateDB, isUBT bool) { statedb.SetNonce(params.HistoryStorageAddress, 1, tracing.NonceChangeUnspecified) statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode, tracing.CodeChangeUnspecified) // Process n blocks, from 1 .. num @@ -196,7 +196,7 @@ func TestProcessParentBlockHash(t *testing.T) { for i := 1; i <= num; i++ { header := &types.Header{ParentHash: common.Hash{byte(i)}, Number: big.NewInt(int64(i)), Difficulty: new(big.Int)} chainConfig := params.MergedTestChainConfig - if isVerkle { + if isUBT { chainConfig = testVerkleChainConfig } vmContext := NewEVMBlockContext(header, nil, new(common.Address)) @@ -205,9 +205,9 @@ func TestProcessParentBlockHash(t *testing.T) { } // Read block hashes for block 0 .. num-1 for i := 0; i < num; i++ { - have, want := getContractStoredBlockHash(statedb, uint64(i), isVerkle), common.Hash{byte(i + 1)} + have, want := getContractStoredBlockHash(statedb, uint64(i), isUBT), common.Hash{byte(i + 1)} if have != want { - t.Errorf("block %d, verkle=%v, have parent hash %v, want %v", i, isVerkle, have, want) + t.Errorf("block %d, verkle=%v, have parent hash %v, want %v", i, isUBT, have, want) } } } @@ -226,11 +226,11 @@ func TestProcessParentBlockHash(t *testing.T) { } // getContractStoredBlockHash is a utility method which reads the stored parent blockhash for block 'number' -func getContractStoredBlockHash(statedb *state.StateDB, number uint64, isVerkle bool) common.Hash { +func getContractStoredBlockHash(statedb *state.StateDB, number uint64, isUBT bool) common.Hash { ringIndex := number % params.HistoryServeWindow var key common.Hash binary.BigEndian.PutUint64(key[24:], ringIndex) - if isVerkle { + if isUBT { return statedb.GetState(params.HistoryStorageAddress, key) } return statedb.GetState(params.HistoryStorageAddress, key) diff --git a/core/blockchain.go b/core/blockchain.go index 35b2d35dc7..e448bb3f3d 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -258,10 +258,10 @@ func (cfg BlockChainConfig) WithNoAsyncFlush(on bool) *BlockChainConfig { } // triedbConfig derives the configures for trie database. -func (cfg *BlockChainConfig) triedbConfig(isVerkle bool) *triedb.Config { +func (cfg *BlockChainConfig) triedbConfig(isUBT bool) *triedb.Config { config := &triedb.Config{ Preimages: cfg.Preimages, - IsVerkle: isVerkle, + IsUBT: isUBT, } if cfg.StateScheme == rawdb.HashScheme { config.HashDB = &hashdb.Config{ @@ -378,7 +378,7 @@ func NewBlockChain(db ethdb.Database, genesis *Genesis, engine consensus.Engine, } // Open trie database with provided config - enableVerkle, err := EnableVerkleAtGenesis(db, genesis) + enableVerkle, err := EnableUBTAtGenesis(db, genesis) if err != nil { return nil, err } diff --git a/core/chain_makers.go b/core/chain_makers.go index 8f6eed1697..4794c85871 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -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().IsVerkle() { + if b.statedb.Database().TrieDB().IsUBT() { b.statedb.AccessEvents().Merge(evm.AccessEvents) } b.txs = append(b.txs, tx) @@ -392,7 +392,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse misc.ApplyDAOHardFork(statedb) } - if config.IsPrague(b.header.Number, b.header.Time) || config.IsVerkle(b.header.Number, b.header.Time) { + if config.IsPrague(b.header.Number, b.header.Time) || config.IsUBT(b.header.Number, b.header.Time) { // EIP-2935 blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase) blockContext.Random = &common.Hash{} // enable post-merge instruction set @@ -430,8 +430,8 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse // Forcibly use hash-based state scheme for retaining all nodes in disk. var triedbConfig *triedb.Config = triedb.HashDefaults - if config.IsVerkle(config.ChainID, 0) { - triedbConfig = triedb.VerkleDefaults + if config.IsUBT(config.ChainID, 0) { + triedbConfig = triedb.UBTDefaults } triedb := triedb.NewDatabase(db, triedbConfig) defer triedb.Close() @@ -479,8 +479,8 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, gen func(int, *BlockGen)) (ethdb.Database, []*types.Block, []types.Receipts) { db := rawdb.NewMemoryDatabase() var triedbConfig *triedb.Config = triedb.HashDefaults - if genesis.Config != nil && genesis.Config.IsVerkle(genesis.Config.ChainID, 0) { - triedbConfig = triedb.VerkleDefaults + if genesis.Config != nil && genesis.Config.IsUBT(genesis.Config.ChainID, 0) { + triedbConfig = triedb.UBTDefaults } genesisTriedb := triedb.NewDatabase(db, triedbConfig) block, err := genesis.Commit(db, genesisTriedb, nil) diff --git a/core/genesis.go b/core/genesis.go index 6edc6e6779..8c20cf1e8f 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -129,21 +129,21 @@ func ReadGenesis(db ethdb.Database) (*Genesis, error) { } // hashAlloc computes the state root according to the genesis specification. -func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) { +func hashAlloc(ga *types.GenesisAlloc, isUBT bool) (common.Hash, error) { // If a genesis-time verkle trie is requested, create a trie config // with the verkle trie enabled so that the tree can be initialized // as such. var config *triedb.Config - if isVerkle { + if isUBT { config = &triedb.Config{ PathDB: pathdb.Defaults, - IsVerkle: true, + IsUBT: true, } } // Create an ephemeral in-memory database for computing hash, // all the derived states will be discarded to not pollute disk. emptyRoot := types.EmptyRootHash - if isVerkle { + if isUBT { emptyRoot = types.EmptyVerkleHash } db := rawdb.NewMemoryDatabase() @@ -168,7 +168,7 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) { // generated states will be persisted into the given database. func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database, tracer *tracing.Hooks) (common.Hash, error) { emptyRoot := types.EmptyRootHash - if triedb.IsVerkle() { + if triedb.IsUBT() { emptyRoot = types.EmptyVerkleHash } statedb, err := state.New(emptyRoot, state.NewDatabase(triedb, nil)) @@ -279,7 +279,7 @@ type ChainOverrides struct { OverrideOsaka *uint64 OverrideBPO1 *uint64 OverrideBPO2 *uint64 - OverrideVerkle *uint64 + OverrideUBT *uint64 } // apply applies the chain overrides on the supplied chain config. @@ -296,8 +296,8 @@ func (o *ChainOverrides) apply(cfg *params.ChainConfig) error { if o.OverrideBPO2 != nil { cfg.BPO2Time = o.OverrideBPO2 } - if o.OverrideVerkle != nil { - cfg.VerkleTime = o.OverrideVerkle + if o.OverrideUBT != nil { + cfg.UBTTime = o.OverrideUBT } return cfg.CheckConfigForkOrder() } @@ -469,15 +469,15 @@ func (g *Genesis) chainConfigOrDefault(ghash common.Hash, stored *params.ChainCo } } -// IsVerkle indicates whether the state is already stored in a verkle +// IsUBT indicates whether the state is already stored in a verkle // tree at genesis time. -func (g *Genesis) IsVerkle() bool { - return g.Config.IsVerkleGenesis() +func (g *Genesis) IsUBT() bool { + return g.Config.IsUBTGenesis() } // ToBlock returns the genesis block according to genesis specification. func (g *Genesis) ToBlock() *types.Block { - root, err := hashAlloc(&g.Alloc, g.IsVerkle()) + root, err := hashAlloc(&g.Alloc, g.IsUBT()) if err != nil { panic(err) } @@ -609,24 +609,24 @@ func (g *Genesis) MustCommit(db ethdb.Database, triedb *triedb.Database) *types. return block } -// EnableVerkleAtGenesis indicates whether the verkle fork should be activated +// EnableUBTAtGenesis indicates whether the verkle fork should be activated // at genesis. This is a temporary solution only for verkle devnet testing, where // verkle fork 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 EnableVerkleAtGenesis(db ethdb.Database, genesis *Genesis) (bool, error) { +func EnableUBTAtGenesis(db ethdb.Database, genesis *Genesis) (bool, error) { if genesis != nil { if genesis.Config == nil { return false, errGenesisNoConfig } - return genesis.Config.EnableVerkleAtGenesis, nil + return genesis.Config.EnableUBTAtGenesis, nil } if ghash := rawdb.ReadCanonicalHash(db, 0); ghash != (common.Hash{}) { chainCfg := rawdb.ReadChainConfig(db, ghash) if chainCfg != nil { - return chainCfg.EnableVerkleAtGenesis, nil + return chainCfg.EnableUBTAtGenesis, nil } } return false, nil diff --git a/core/genesis_test.go b/core/genesis_test.go index 2b08b36690..bb061b987b 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -285,9 +285,9 @@ func TestVerkleGenesisCommit(t *testing.T) { CancunTime: &verkleTime, PragueTime: &verkleTime, OsakaTime: &verkleTime, - VerkleTime: &verkleTime, + UBTTime: &verkleTime, TerminalTotalDifficulty: big.NewInt(0), - EnableVerkleAtGenesis: true, + EnableUBTAtGenesis: true, Ethash: nil, Clique: nil, BlobScheduleConfig: ¶ms.BlobScheduleConfig{ @@ -320,7 +320,7 @@ func TestVerkleGenesisCommit(t *testing.T) { config.NoAsyncFlush = true triedb := triedb.NewDatabase(db, &triedb.Config{ - IsVerkle: true, + IsUBT: true, PathDB: &config, }) block := genesis.MustCommit(db, triedb) @@ -329,7 +329,7 @@ func TestVerkleGenesisCommit(t *testing.T) { } // Test that the trie is verkle - if !triedb.IsVerkle() { + if !triedb.IsUBT() { t.Fatalf("expected trie to be verkle") } vdb := rawdb.NewTable(db, string(rawdb.VerklePrefix)) diff --git a/core/overlay/state_transition.go b/core/overlay/state_transition.go index a52d9139c9..afd2bab017 100644 --- a/core/overlay/state_transition.go +++ b/core/overlay/state_transition.go @@ -71,7 +71,7 @@ func (ts *TransitionState) Copy() *TransitionState { // 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 { +func LoadTransitionState(db ethdb.KeyValueReader, root common.Hash, isUBT bool) *TransitionState { var ts *TransitionState data, _ := rawdb.ReadVerkleTransitionState(db, root) @@ -97,10 +97,10 @@ func LoadTransitionState(db ethdb.KeyValueReader, root common.Hash, isVerkle boo // 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) + log.Debug("no transition state found, starting fresh", "verkle", isUBT) // Start with a fresh state - ts = &TransitionState{Ended: isVerkle} + ts = &TransitionState{Ended: isUBT} } return ts } diff --git a/core/state/database.go b/core/state/database.go index c603e3ad7a..99ea0b36c1 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -20,7 +20,6 @@ import ( "fmt" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/overlay" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state/snapshot" "github.com/ethereum/go-ethereum/core/types" @@ -28,7 +27,6 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/trie" - "github.com/ethereum/go-ethereum/trie/bintrie" "github.com/ethereum/go-ethereum/trie/transitiontrie" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/triedb" @@ -56,6 +54,21 @@ type Database interface { // committing the changes to the underlying storage. It returns an error // if the commit fails. Commit(update *stateUpdate) error + + // WithSnapshot configures the snapshot tree. This registration must be + // performed before the database is used. + WithSnapshot(snap *snapshot.Tree) Database + + // Snapshot returns the underlying state snapshot. + Snapshot() *snapshot.Tree + + // StateReader returns a state reader associated with the specified state root. + StateReader(stateRoot common.Hash) (StateReader, error) + + // ReadersWithCacheStats creates a pair of state readers that share the same + // underlying state reader and internal state cache, while maintaining separate + // statistics respectively. + ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reader, error) } // Trie is a Ethereum Merkle Patricia trie. @@ -139,46 +152,53 @@ type Trie interface { // with the node that proves the absence of the key. Prove(key []byte, proofDb ethdb.KeyValueWriter) error - // IsVerkle returns true if the trie is verkle-tree based - IsVerkle() bool + // IsUBT returns true if the trie is verkle-tree based + IsUBT() bool } -// CachingDB is an implementation of Database interface. 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 CachingDB struct { +// MPTDB 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 MPTDB struct { triedb *triedb.Database codedb *CodeDB snap *snapshot.Tree } // NewDatabase creates a state database with the provided data sources. -func NewDatabase(triedb *triedb.Database, codedb *CodeDB) *CachingDB { +func NewDatabase(tdb *triedb.Database, codedb *CodeDB) Database { if codedb == nil { - codedb = NewCodeDB(triedb.Disk()) + codedb = NewCodeDB(tdb.Disk()) } - return &CachingDB{ - triedb: triedb, + if tdb.IsUBT() { + return &UBTDB{ + triedb: tdb, + codedb: codedb, + } + } + return &MPTDB{ + triedb: tdb, codedb: codedb, } } // NewDatabaseForTesting is similar to NewDatabase, but it initializes the caching // db by using an ephemeral memory db with default config for testing. -func NewDatabaseForTesting() *CachingDB { +func NewDatabaseForTesting() Database { db := rawdb.NewMemoryDatabase() return NewDatabase(triedb.NewDatabase(db, nil), NewCodeDB(db)) } // WithSnapshot configures the provided contract code cache. Note that this -// registration must be performed before the cachingDB is used. -func (db *CachingDB) WithSnapshot(snapshot *snapshot.Tree) *CachingDB { +// registration must be performed before the MPTDB is used. +func (db *MPTDB) WithSnapshot(snapshot *snapshot.Tree) Database { db.snap = snapshot return db } // StateReader returns a state reader associated with the specified state root. -func (db *CachingDB) StateReader(stateRoot common.Hash) (StateReader, error) { +func (db *MPTDB) StateReader(stateRoot common.Hash) (StateReader, error) { var readers []StateReader // Configure the state reader using the standalone snapshot in hash mode. @@ -213,7 +233,7 @@ func (db *CachingDB) StateReader(stateRoot common.Hash) (StateReader, error) { // Reader implements Database, returning a reader associated with the specified // state root. -func (db *CachingDB) Reader(stateRoot common.Hash) (Reader, error) { +func (db *MPTDB) Reader(stateRoot common.Hash) (Reader, error) { sr, err := db.StateReader(stateRoot) if err != nil { return nil, err @@ -224,7 +244,7 @@ func (db *CachingDB) 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 *CachingDB) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reader, error) { +func (db *MPTDB) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reader, error) { r, err := db.StateReader(stateRoot) if err != nil { return nil, nil, err @@ -236,18 +256,7 @@ func (db *CachingDB) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reade } // 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 ts.Transitioned() { - // Use BinaryTrie instead of VerkleTrie when IsVerkle is set - // (IsVerkle actually means Binary Trie mode in this codebase) - return bintrie.NewBinaryTrie(root, db.triedb) - } - } +func (db *MPTDB) OpenTrie(root common.Hash) (Trie, error) { tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb) if err != nil { return nil, err @@ -256,10 +265,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() { - return self, nil - } +func (db *MPTDB) 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 @@ -268,19 +274,19 @@ func (db *CachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Addre } // TrieDB retrieves any intermediate trie-node caching layer. -func (db *CachingDB) TrieDB() *triedb.Database { +func (db *MPTDB) TrieDB() *triedb.Database { return db.triedb } // Snapshot returns the underlying state snapshot. -func (db *CachingDB) Snapshot() *snapshot.Tree { +func (db *MPTDB) 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 *CachingDB) Commit(update *stateUpdate) error { +func (db *MPTDB) Commit(update *stateUpdate) error { // Short circuit if nothing to commit if update.empty() { return nil @@ -313,8 +319,8 @@ func (db *CachingDB) 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 *CachingDB) Iteratee(root common.Hash) (Iteratee, error) { - return newStateIteratee(!db.triedb.IsVerkle(), root, db.triedb, db.snap) +func (db *MPTDB) Iteratee(root common.Hash) (Iteratee, error) { + return newStateIteratee(true, root, db.triedb, db.snap) } // mustCopyTrie returns a deep-copied trie. diff --git a/core/state/database_history.go b/core/state/database_history.go index 0dbb8cc546..f1b6c29226 100644 --- a/core/state/database_history.go +++ b/core/state/database_history.go @@ -22,6 +22,7 @@ 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" @@ -300,3 +301,23 @@ 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") +} + +// ReadersWithCacheStats is not supported by historic database. +func (db *HistoricDB) ReadersWithCacheStats(stateRoot common.Hash) (Reader, Reader, error) { + return nil, nil, errors.New("not implemented") +} diff --git a/core/state/database_ubt.go b/core/state/database_ubt.go new file mode 100644 index 0000000000..3b2926c062 --- /dev/null +++ b/core/state/database_ubt.go @@ -0,0 +1,152 @@ +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +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 MPTDB but uses binary tries for state +// storage instead of Merkle Patricia Tries. +type UBTDB struct { + triedb *triedb.Database + codedb *CodeDB + snap *snapshot.Tree +} + +// 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) { + var readers []StateReader + + // Configure the state reader using the path database in path mode. + // This reader offers improved performance but is optional and only + // partially useful if the snapshot data in path database is not + // fully generated. + if db.TrieDB().Scheme() == rawdb.PathScheme { + reader, err := db.triedb.StateReader(stateRoot) + if err == nil { + readers = append(readers, newFlatReader(reader)) + } + } + // Configure the trie reader, which is expected to be available as the + // gatekeeper unless the state is corrupted. + tr, err := newTrieReader(stateRoot, db.triedb) + if err != nil { + return nil, err + } + readers = append(readers, tr) + + return newMultiStateReader(readers...) +} + +// Reader implements Database, returning a reader associated with the specified +// state root. +func (db *UBTDB) Reader(stateRoot common.Hash) (Reader, error) { + sr, err := db.StateReader(stateRoot) + if err != nil { + return nil, err + } + return newReader(db.codedb.Reader(), sr), nil +} + +// 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) { + r, err := db.StateReader(stateRoot) + if err != nil { + return nil, nil, err + } + sr := newStateReaderWithCache(r) + ra := newReader(db.codedb.Reader(), newStateReaderWithStats(sr)) + rb := newReader(db.codedb.Reader(), newStateReaderWithStats(sr)) + return ra, rb, nil +} + +// OpenTrie opens the main account trie at a specific root hash. +func (db *UBTDB) 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) { + return self, nil +} + +// TrieDB retrieves any intermediate trie-node caching layer. +func (db *UBTDB) 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 { + // Short circuit if nothing to commit + if update.empty() { + return nil + } + // Commit dirty contract code if any exists + if len(update.codes) > 0 { + batch := db.codedb.NewBatchWithSize(len(update.codes)) + for _, code := range update.codes { + batch.Put(code.hash, code.blob) + } + if err := batch.Commit(); err != nil { + 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) +} diff --git a/core/state/reader.go b/core/state/reader.go index fe0ec71f2d..b837c6a0a1 100644 --- a/core/state/reader.go +++ b/core/state/reader.go @@ -172,10 +172,10 @@ func newTrieReader(root common.Hash, db *triedb.Database) (*trieReader, error) { tr Trie err error ) - if !db.IsVerkle() { + if !db.IsUBT() { tr, err = trie.NewStateTrie(trie.StateTrieID(root), db) } else { - // When IsVerkle() is true, create a BinaryTrie wrapped in TransitionTrie + // When IsUBT() is true, create a BinaryTrie wrapped in TransitionTrie binTrie, binErr := bintrie.NewBinaryTrie(root, db) if binErr != nil { return nil, binErr @@ -259,7 +259,7 @@ func (r *trieReader) Storage(addr common.Address, key common.Hash) (common.Hash, found bool value common.Hash ) - if r.db.IsVerkle() { + if r.db.IsUBT() { tr = r.mainTrie } else { tr, found = r.subTries[addr] diff --git a/core/state/state_object.go b/core/state/state_object.go index ec0c511737..8c1aacdec4 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -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().IsVerkle()) || s.db.prefetcher == nil { + if (s.data.Root == types.EmptyRootHash && !s.db.db.TrieDB().IsUBT()) || s.db.prefetcher == nil { return nil } // Attempt to retrieve the trie from the prefetcher @@ -478,7 +478,7 @@ func (s *stateObject) commit() (*accountUpdate, *trienode.NodeSet, error) { // The main account trie commit in stateDB.commit() already calls // CollectNodes on this trie, so calling Commit here again would // redundantly traverse and serialize the entire tree per dirty account. - if s.db.GetTrie().IsVerkle() { + if s.db.GetTrie().IsUBT() { s.origin = s.data.Copy() return op, nil, nil } diff --git a/core/state/statedb.go b/core/state/statedb.go index 8b09ea89f6..2ba87f738c 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -190,7 +190,7 @@ func NewWithReader(root common.Hash, db Database, reader Reader) (*StateDB, erro accessList: newAccessList(), transientStorage: newTransientStorage(), } - if db.TrieDB().IsVerkle() { + if db.TrieDB().IsUBT() { 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().IsVerkle() { + if s.db.TrieDB().IsUBT() { // 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, @@ -924,7 +924,7 @@ 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().IsVerkle() { + if s.witness != nil && !s.db.TrieDB().IsUBT() { // 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().IsVerkle() { + if s.prefetcher != nil && !s.db.TrieDB().IsUBT() { 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().IsVerkle() { + if prev.Root == types.EmptyRootHash || s.db.TrieDB().IsUBT() { continue } if noStorageWiping { diff --git a/core/state/trie_prefetcher.go b/core/state/trie_prefetcher.go index a9faddcdff..4b957d1597 100644 --- a/core/state/trie_prefetcher.go +++ b/core/state/trie_prefetcher.go @@ -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().IsVerkle(), + verkle: db.TrieDB().IsUBT(), db: db, root: root, fetchers: make(map[string]*subfetcher), // Active prefetchers use the fetchers map @@ -342,7 +342,7 @@ func (sf *subfetcher) terminate(async bool) { 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().IsVerkle() { + if sf.db.TrieDB().IsUBT() { tr, err := sf.db.OpenTrie(sf.state) if err != nil { log.Warn("Trie prefetcher failed opening verkle trie", "root", sf.root, "err", err) diff --git a/core/state/trie_prefetcher_test.go b/core/state/trie_prefetcher_test.go index 41349c0c0e..b328c72600 100644 --- a/core/state/trie_prefetcher_test.go +++ b/core/state/trie_prefetcher_test.go @@ -68,7 +68,7 @@ func TestUseAfterTerminate(t *testing.T) { func TestVerklePrefetcher(t *testing.T) { disk := rawdb.NewMemoryDatabase() - db := triedb.NewDatabase(disk, triedb.VerkleDefaults) + db := triedb.NewDatabase(disk, triedb.UBTDefaults) sdb := NewDatabase(db, nil) state, err := New(types.EmptyRootHash, sdb) diff --git a/core/state_processor.go b/core/state_processor.go index bbb1341299..a171b4b0af 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -90,7 +90,7 @@ func (p *StateProcessor) Process(ctx context.Context, block *types.Block, stated if beaconRoot := block.BeaconRoot(); beaconRoot != nil { ProcessBeaconBlockRoot(*beaconRoot, evm) } - if config.IsPrague(block.Number(), block.Time()) || config.IsVerkle(block.Number(), block.Time()) { + if config.IsPrague(block.Number(), block.Time()) || config.IsUBT(block.Number(), block.Time()) { ProcessParentBlockHash(block.ParentHash(), evm) } @@ -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().IsVerkle() { + if statedb.Database().TrieDB().IsUBT() { statedb.AccessEvents().Merge(evm.AccessEvents) } return MakeReceipt(evm, result, statedb, blockNumber, blockHash, blockTime, tx, gp.CumulativeUsed(), root), nil diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 010f477337..b4cddf0bca 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -213,7 +213,7 @@ func init() { func activePrecompiledContracts(rules params.Rules) PrecompiledContracts { switch { - case rules.IsVerkle: + case rules.IsUBT: return PrecompiledContractsVerkle case rules.IsOsaka: return PrecompiledContractsOsaka diff --git a/core/vm/evm.go b/core/vm/evm.go index 36494de2a8..6588ed6beb 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -149,7 +149,7 @@ func NewEVM(blockCtx BlockContext, statedb StateDB, chainConfig *params.ChainCon evm.table = &amsterdamInstructionSet case evm.chainRules.IsOsaka: evm.table = &osakaInstructionSet - case evm.chainRules.IsVerkle: + case evm.chainRules.IsUBT: // TODO replace with proper instruction set when fork is specified evm.table = &verkleInstructionSet case evm.chainRules.IsPrague: diff --git a/core/vm/jump_table_export.go b/core/vm/jump_table_export.go index fdf814d64c..a4a99ea498 100644 --- a/core/vm/jump_table_export.go +++ b/core/vm/jump_table_export.go @@ -26,7 +26,7 @@ import ( // the rules. func LookupInstructionSet(rules params.Rules) (JumpTable, error) { switch { - case rules.IsVerkle: + case rules.IsUBT: return newCancunInstructionSet(), errors.New("verkle-fork not defined yet") case rules.IsAmsterdam: return newAmsterdamInstructionSet(), nil diff --git a/eth/backend.go b/eth/backend.go index e9bea59734..08a3c70c9d 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -277,8 +277,8 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if config.OverrideBPO2 != nil { overrides.OverrideBPO2 = config.OverrideBPO2 } - if config.OverrideVerkle != nil { - overrides.OverrideVerkle = config.OverrideVerkle + if config.OverrideUBT != nil { + overrides.OverrideUBT = config.OverrideUBT } options.Overrides = &overrides diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 01aaaa751b..dd7436bf52 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -200,8 +200,8 @@ type Config struct { // OverrideBPO2 (TODO: remove after the fork) OverrideBPO2 *uint64 `toml:",omitempty"` - // OverrideVerkle (TODO: remove after the fork) - OverrideVerkle *uint64 `toml:",omitempty"` + // OverrideUBT (TODO: remove after the fork) + OverrideUBT *uint64 `toml:",omitempty"` // EIP-7966: eth_sendRawTransactionSync timeouts TxSyncDefaultTimeout time.Duration `toml:",omitempty"` diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index 6f94a409e5..68a479ae62 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -64,7 +64,7 @@ func (c Config) MarshalTOML() (interface{}, error) { OverrideOsaka *uint64 `toml:",omitempty"` OverrideBPO1 *uint64 `toml:",omitempty"` OverrideBPO2 *uint64 `toml:",omitempty"` - OverrideVerkle *uint64 `toml:",omitempty"` + OverrideUBT *uint64 `toml:",omitempty"` TxSyncDefaultTimeout time.Duration `toml:",omitempty"` TxSyncMaxTimeout time.Duration `toml:",omitempty"` RangeLimit uint64 `toml:",omitempty"` @@ -117,7 +117,7 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.OverrideOsaka = c.OverrideOsaka enc.OverrideBPO1 = c.OverrideBPO1 enc.OverrideBPO2 = c.OverrideBPO2 - enc.OverrideVerkle = c.OverrideVerkle + enc.OverrideUBT = c.OverrideUBT enc.TxSyncDefaultTimeout = c.TxSyncDefaultTimeout enc.TxSyncMaxTimeout = c.TxSyncMaxTimeout enc.RangeLimit = c.RangeLimit @@ -174,7 +174,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { OverrideOsaka *uint64 `toml:",omitempty"` OverrideBPO1 *uint64 `toml:",omitempty"` OverrideBPO2 *uint64 `toml:",omitempty"` - OverrideVerkle *uint64 `toml:",omitempty"` + OverrideUBT *uint64 `toml:",omitempty"` TxSyncDefaultTimeout *time.Duration `toml:",omitempty"` TxSyncMaxTimeout *time.Duration `toml:",omitempty"` RangeLimit *uint64 `toml:",omitempty"` @@ -324,8 +324,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.OverrideBPO2 != nil { c.OverrideBPO2 = dec.OverrideBPO2 } - if dec.OverrideVerkle != nil { - c.OverrideVerkle = dec.OverrideVerkle + if dec.OverrideUBT != nil { + c.OverrideUBT = dec.OverrideUBT } if dec.TxSyncDefaultTimeout != nil { c.TxSyncDefaultTimeout = *dec.TxSyncDefaultTimeout diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 53a09087e4..b5ddc78a10 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -1086,8 +1086,8 @@ func overrideConfig(original *params.ChainConfig, override *params.ChainConfig) copy.OsakaTime = timestamp canon = false } - if timestamp := override.VerkleTime; timestamp != nil { - copy.VerkleTime = timestamp + if timestamp := override.UBTTime; timestamp != nil { + copy.UBTTime = timestamp canon = false } diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index eacb296132..90e88e83ee 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -317,7 +317,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, if precompiles != nil { evm.SetPrecompiles(precompiles) } - if sim.chainConfig.IsPrague(header.Number, header.Time) || sim.chainConfig.IsVerkle(header.Number, header.Time) { + if sim.chainConfig.IsPrague(header.Number, header.Time) || sim.chainConfig.IsUBT(header.Number, header.Time) { core.ProcessParentBlockHash(header.ParentHash, evm) } if header.ParentBeaconRoot != nil { diff --git a/params/config.go b/params/config.go index 197ed56f8a..5eac6c7f57 100644 --- a/params/config.go +++ b/params/config.go @@ -207,7 +207,7 @@ var ( CancunTime: nil, PragueTime: nil, OsakaTime: nil, - VerkleTime: nil, + UBTTime: nil, Ethash: new(EthashConfig), Clique: nil, } @@ -263,7 +263,7 @@ var ( CancunTime: nil, PragueTime: nil, OsakaTime: nil, - VerkleTime: nil, + UBTTime: nil, TerminalTotalDifficulty: big.NewInt(math.MaxInt64), Ethash: nil, Clique: &CliqueConfig{Period: 0, Epoch: 30000}, @@ -293,7 +293,7 @@ var ( CancunTime: nil, PragueTime: nil, OsakaTime: nil, - VerkleTime: nil, + UBTTime: nil, TerminalTotalDifficulty: big.NewInt(math.MaxInt64), Ethash: new(EthashConfig), Clique: nil, @@ -323,7 +323,7 @@ var ( CancunTime: newUint64(0), PragueTime: newUint64(0), OsakaTime: newUint64(0), - VerkleTime: nil, + UBTTime: nil, TerminalTotalDifficulty: big.NewInt(0), Ethash: new(EthashConfig), Clique: nil, @@ -358,7 +358,7 @@ var ( CancunTime: nil, PragueTime: nil, OsakaTime: nil, - VerkleTime: nil, + UBTTime: nil, TerminalTotalDifficulty: big.NewInt(math.MaxInt64), Ethash: new(EthashConfig), Clique: nil, @@ -466,7 +466,7 @@ type ChainConfig struct { BPO4Time *uint64 `json:"bpo4Time,omitempty"` // BPO4 switch time (nil = no fork, 0 = already on bpo4) BPO5Time *uint64 `json:"bpo5Time,omitempty"` // BPO5 switch time (nil = no fork, 0 = already on bpo5) AmsterdamTime *uint64 `json:"amsterdamTime,omitempty"` // Amsterdam switch time (nil = no fork, 0 = already on amsterdam) - VerkleTime *uint64 `json:"verkleTime,omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle) + UBTTime *uint64 `json:"ubtTime,omitempty"` // UBT switch time (nil = no fork, 0 = already on UBT) // TerminalTotalDifficulty is the amount of total difficulty reached by // the network that triggers the consensus upgrade. @@ -474,7 +474,7 @@ type ChainConfig struct { DepositContractAddress common.Address `json:"depositContractAddress,omitempty"` - // EnableVerkleAtGenesis is a flag that specifies whether the network uses + // EnableUBTAtGenesis is a flag that specifies whether the network uses // the Verkle tree starting from the genesis block. If set to true, the // genesis state will be committed using the Verkle tree, eliminating the // need for any Verkle transition later. @@ -485,7 +485,7 @@ type ChainConfig struct { // In production networks (mainnet and public testnets), verkle activation // always occurs after the genesis block, making this flag irrelevant in // those cases. - EnableVerkleAtGenesis bool `json:"enableVerkleAtGenesis,omitempty"` + EnableUBTAtGenesis bool `json:"enableUBTAtGenesis,omitempty"` // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty"` @@ -595,8 +595,8 @@ func (c *ChainConfig) String() string { if c.AmsterdamTime != nil { result += fmt.Sprintf(", AmsterdamTime: %v", *c.AmsterdamTime) } - if c.VerkleTime != nil { - result += fmt.Sprintf(", VerkleTime: %v", *c.VerkleTime) + if c.UBTTime != nil { + result += fmt.Sprintf(", UBTTime: %v", *c.UBTTime) } result += "}" return result @@ -690,8 +690,8 @@ func (c *ChainConfig) Description() string { if c.AmsterdamTime != nil { banner += fmt.Sprintf(" - Amsterdam: @%-10v blob: (%s)\n", *c.AmsterdamTime, c.BlobScheduleConfig.Amsterdam) } - if c.VerkleTime != nil { - banner += fmt.Sprintf(" - Verkle: @%-10v blob: (%s)\n", *c.VerkleTime, c.BlobScheduleConfig.Verkle) + if c.UBTTime != nil { + banner += fmt.Sprintf(" - Verkle: @%-10v blob: (%s)\n", *c.UBTTime, c.BlobScheduleConfig.Verkle) } banner += fmt.Sprintf("\nAll fork specifications can be found at https://ethereum.github.io/execution-specs/src/ethereum/forks/\n") return banner @@ -866,12 +866,12 @@ func (c *ChainConfig) IsAmsterdam(num *big.Int, time uint64) bool { return c.IsLondon(num) && isTimestampForked(c.AmsterdamTime, time) } -// IsVerkle returns whether time is either equal to the Verkle fork time or greater. -func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool { - return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time) +// IsUBT returns whether time is either equal to the Verkle fork time or greater. +func (c *ChainConfig) IsUBT(num *big.Int, time uint64) bool { + return c.IsLondon(num) && isTimestampForked(c.UBTTime, time) } -// IsVerkleGenesis checks whether the verkle fork is activated at the genesis block. +// IsUBTGenesis checks whether the verkle 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. @@ -881,13 +881,13 @@ func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool { // 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) IsVerkleGenesis() bool { - return c.EnableVerkleAtGenesis +func (c *ChainConfig) IsUBTGenesis() bool { + return c.EnableUBTAtGenesis } // IsEIP4762 returns whether eip 4762 has been activated at given block. func (c *ChainConfig) IsEIP4762(num *big.Int, time uint64) bool { - return c.IsVerkle(num, time) + return c.IsUBT(num, time) } // CheckCompatible checks whether scheduled fork transitions have been imported @@ -945,7 +945,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error { {name: "cancunTime", timestamp: c.CancunTime, optional: true}, {name: "pragueTime", timestamp: c.PragueTime, optional: true}, {name: "osakaTime", timestamp: c.OsakaTime, optional: true}, - {name: "verkleTime", timestamp: c.VerkleTime, optional: true}, + {name: "ubtTime", timestamp: c.UBTTime, optional: true}, {name: "bpo1", timestamp: c.BPO1Time, optional: true}, {name: "bpo2", timestamp: c.BPO2Time, optional: true}, {name: "bpo3", timestamp: c.BPO3Time, optional: true}, @@ -1104,8 +1104,8 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int, if isForkTimestampIncompatible(c.OsakaTime, newcfg.OsakaTime, headTimestamp) { return newTimestampCompatError("Osaka fork timestamp", c.OsakaTime, newcfg.OsakaTime) } - if isForkTimestampIncompatible(c.VerkleTime, newcfg.VerkleTime, headTimestamp) { - return newTimestampCompatError("Verkle fork timestamp", c.VerkleTime, newcfg.VerkleTime) + if isForkTimestampIncompatible(c.UBTTime, newcfg.UBTTime, headTimestamp) { + return newTimestampCompatError("UBT fork timestamp", c.UBTTime, newcfg.UBTTime) } if isForkTimestampIncompatible(c.BPO1Time, newcfg.BPO1Time, headTimestamp) { return newTimestampCompatError("BPO1 fork timestamp", c.BPO1Time, newcfg.BPO1Time) @@ -1380,14 +1380,14 @@ type Rules struct { IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool IsBerlin, IsLondon bool IsMerge, IsShanghai, IsCancun, IsPrague, IsOsaka bool - IsAmsterdam, IsVerkle bool + IsAmsterdam, IsUBT bool } // Rules ensures c's ChainID is not nil. func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules { // disallow setting Merge out of order isMerge = isMerge && c.IsLondon(num) - isVerkle := isMerge && c.IsVerkle(num, timestamp) + isUBT := isMerge && c.IsUBT(num, timestamp) return Rules{ IsHomestead: c.IsHomestead(num), IsEIP150: c.IsEIP150(num), @@ -1398,7 +1398,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules IsPetersburg: c.IsPetersburg(num), IsIstanbul: c.IsIstanbul(num), IsBerlin: c.IsBerlin(num), - IsEIP2929: c.IsBerlin(num) && !isVerkle, + IsEIP2929: c.IsBerlin(num) && !isUBT, IsLondon: c.IsLondon(num), IsMerge: isMerge, IsShanghai: isMerge && c.IsShanghai(num, timestamp), @@ -1406,7 +1406,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules IsPrague: isMerge && c.IsPrague(num, timestamp), IsOsaka: isMerge && c.IsOsaka(num, timestamp), IsAmsterdam: isMerge && c.IsAmsterdam(num, timestamp), - IsVerkle: isVerkle, - IsEIP4762: isVerkle, + IsUBT: isUBT, + IsEIP4762: isUBT, } } diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 00411073e2..ee53aa60ed 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -126,10 +126,10 @@ func (t *BlockTest) Run(snapshotter bool, scheme string, witness bool, tracer *t db = rawdb.NewMemoryDatabase() tconf = &triedb.Config{ Preimages: true, - IsVerkle: gspec.Config.VerkleTime != nil && *gspec.Config.VerkleTime <= gspec.Timestamp, + IsUBT: gspec.Config.UBTTime != nil && *gspec.Config.UBTTime <= gspec.Timestamp, } ) - if scheme == rawdb.PathScheme || tconf.IsVerkle { + if scheme == rawdb.PathScheme || tconf.IsUBT { tconf.PathDB = pathdb.Defaults } else { tconf.HashDB = hashdb.Defaults diff --git a/tests/init.go b/tests/init.go index f115e427a5..dc155d90e2 100644 --- a/tests/init.go +++ b/tests/init.go @@ -774,7 +774,7 @@ var Forks = map[string]*params.ChainConfig{ MergeNetsplitBlock: big.NewInt(0), TerminalTotalDifficulty: big.NewInt(0), ShanghaiTime: u64(0), - VerkleTime: u64(0), + UBTTime: u64(0), }, } diff --git a/trie/bintrie/trie.go b/trie/bintrie/trie.go index 6c29239a87..af72132e7e 100644 --- a/trie/bintrie/trie.go +++ b/trie/bintrie/trie.go @@ -361,8 +361,8 @@ func (t *BinaryTrie) Copy() *BinaryTrie { } } -// IsVerkle returns true if the trie is a Verkle tree. -func (t *BinaryTrie) IsVerkle() bool { +// IsUBT returns true if the trie is a Verkle tree. +func (t *BinaryTrie) IsUBT() bool { // TODO @gballet This is technically NOT a verkle tree, but it has the same // behavior and basic structure, so for all intents and purposes, it can be // treated as such. Rename this when verkle gets removed. diff --git a/trie/secure_trie.go b/trie/secure_trie.go index 1f150ede8c..4d03ca45f0 100644 --- a/trie/secure_trie.go +++ b/trie/secure_trie.go @@ -324,6 +324,6 @@ func (t *StateTrie) MustNodeIterator(start []byte) NodeIterator { return t.trie.MustNodeIterator(start) } -func (t *StateTrie) IsVerkle() bool { +func (t *StateTrie) IsUBT() bool { return false } diff --git a/trie/transitiontrie/transition.go b/trie/transitiontrie/transition.go index 4c73022082..3e5511be9e 100644 --- a/trie/transitiontrie/transition.go +++ b/trie/transitiontrie/transition.go @@ -202,8 +202,8 @@ func (t *TransitionTrie) Prove(key []byte, proofDb ethdb.KeyValueWriter) error { panic("not implemented") // TODO: Implement } -// IsVerkle returns true if the trie is verkle-tree based -func (t *TransitionTrie) IsVerkle() bool { +// IsUBT returns true if the trie is verkle-tree based +func (t *TransitionTrie) IsUBT() bool { // For all intents and purposes, the calling code should treat this as a verkle trie return true } diff --git a/triedb/database.go b/triedb/database.go index c1abe93462..533097c9e3 100644 --- a/triedb/database.go +++ b/triedb/database.go @@ -32,7 +32,7 @@ import ( // Config defines all necessary options for database. type Config struct { Preimages bool // Flag whether the preimage of node key is recorded - IsVerkle bool // Flag whether the db is holding a verkle tree + IsUBT bool // Flag whether the db is holding a verkle tree HashDB *hashdb.Config // Configs for hash-based scheme PathDB *pathdb.Config // Configs for experimental path-based scheme } @@ -41,15 +41,15 @@ type Config struct { // default settings. var HashDefaults = &Config{ Preimages: false, - IsVerkle: false, + IsUBT: false, HashDB: hashdb.Defaults, } -// VerkleDefaults represents a config for holding verkle trie data +// UBTDefaults represents a config for holding verkle trie data // using path-based scheme with default settings. -var VerkleDefaults = &Config{ +var UBTDefaults = &Config{ Preimages: false, - IsVerkle: true, + IsUBT: true, PathDB: pathdb.Defaults, } @@ -109,7 +109,7 @@ func NewDatabase(diskdb ethdb.Database, config *Config) *Database { log.Crit("Both 'hash' and 'path' mode are configured") } if config.PathDB != nil { - db.backend = pathdb.New(diskdb, config.PathDB, config.IsVerkle) + db.backend = pathdb.New(diskdb, config.PathDB, config.IsUBT) } else { db.backend = hashdb.New(diskdb, config.HashDB) } @@ -375,9 +375,9 @@ func (db *Database) IndexProgress() (uint64, uint64, error) { return pdb.IndexProgress() } -// IsVerkle returns the indicator if the database is holding a verkle tree. -func (db *Database) IsVerkle() bool { - return db.config.IsVerkle +// IsUBT returns the indicator if the database is holding a verkle tree. +func (db *Database) IsUBT() bool { + return db.config.IsUBT } // Disk returns the underlying disk database. diff --git a/triedb/pathdb/database.go b/triedb/pathdb/database.go index a61d302b1d..ec6f101a35 100644 --- a/triedb/pathdb/database.go +++ b/triedb/pathdb/database.go @@ -127,7 +127,7 @@ type Database struct { // the shutdown to reject all following unexpected mutations. readOnly bool // Flag if database is opened in read only mode waitSync bool // Flag if database is deactivated due to initial state sync - isVerkle bool // Flag if database is used for verkle tree + isUBT bool // Flag if database is used for verkle tree hasher nodeHasher // Trie node hasher config *Config // Configuration for database @@ -146,7 +146,7 @@ type Database struct { // New attempts to load an already existing layer from a persistent key-value // store (with a number of memory layers from a journal). If the journal is not // matched with the base persistent layer, all the recorded diff layers are discarded. -func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database { +func New(diskdb ethdb.Database, config *Config, isUBT bool) *Database { if config == nil { config = Defaults } @@ -154,7 +154,7 @@ func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database { db := &Database{ readOnly: config.ReadOnly, - isVerkle: isVerkle, + isUBT: isUBT, config: config, diskdb: diskdb, hasher: merkleNodeHasher, @@ -164,7 +164,7 @@ func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database { // important to note that the introduction of a prefix won't lead to // substantial storage overhead, as the underlying database will efficiently // compress the shared key prefix. - if isVerkle { + if isUBT { db.diskdb = rawdb.NewTable(diskdb, string(rawdb.VerklePrefix)) db.hasher = binaryNodeHasher } @@ -174,7 +174,7 @@ func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database { // Repair the history, which might not be aligned with the persistent // state in the key-value store due to an unclean shutdown. - states, trienodes, err := repairHistory(db.diskdb, isVerkle, db.config.ReadOnly, db.tree.bottom().stateID(), db.config.TrienodeHistory >= 0) + states, trienodes, err := repairHistory(db.diskdb, isUBT, db.config.ReadOnly, db.tree.bottom().stateID(), db.config.TrienodeHistory >= 0) if err != nil { log.Crit("Failed to repair history", "err", err) } @@ -196,7 +196,7 @@ func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database { db.setHistoryIndexer() fields := config.fields() - if db.isVerkle { + if db.isUBT { fields = append(fields, "verkle", true) } log.Info("Initialized path database", fields...) @@ -265,7 +265,7 @@ func (db *Database) setStateGenerator() error { // - the database is opened in read only mode // - the snapshot build is explicitly disabled // - the database is opened in verkle tree mode - noBuild := db.readOnly || db.config.SnapshotNoBuild || db.isVerkle + noBuild := db.readOnly || db.config.SnapshotNoBuild || db.isUBT // Construct the generator and link it to the disk layer, ensuring that the // generation progress is resolved to prevent accessing uncovered states @@ -408,7 +408,7 @@ func (db *Database) Enable(root common.Hash) error { // Re-construct a new disk layer backed by persistent state // and schedule the state snapshot generation if it's permitted. - db.tree.init(generateSnapshot(db, root, db.isVerkle || db.config.SnapshotNoBuild)) + db.tree.init(generateSnapshot(db, root, db.isUBT || db.config.SnapshotNoBuild)) // After snap sync, the state of the database may have changed completely. // To ensure the history indexer always matches the current state, we must: @@ -586,7 +586,7 @@ func (db *Database) journalPath() string { return "" } var fname string - if db.isVerkle { + if db.isUBT { fname = fmt.Sprintf("verkle.journal") } else { fname = fmt.Sprintf("merkle.journal") diff --git a/triedb/pathdb/database_test.go b/triedb/pathdb/database_test.go index e70a3ec2a2..4416670dac 100644 --- a/triedb/pathdb/database_test.go +++ b/triedb/pathdb/database_test.go @@ -143,7 +143,7 @@ type testerConfig struct { layers int // Number of state transitions to generate for enableIndex bool // Enable state history indexing or not journalDir string // Directory path for persisting journal files - isVerkle bool // Enables Verkle trie mode if true + isUBT bool // Enables Verkle trie mode if true writeBuffer *int // Optional, the size of memory allocated for write buffer trieCache *int // Optional, the size of memory allocated for trie cache @@ -183,7 +183,7 @@ func newTester(t *testing.T, config *testerConfig) *tester { NoAsyncFlush: true, JournalDirectory: config.journalDir, NoHistoryIndexDelay: true, - }, config.isVerkle) + }, config.isUBT) obj = &tester{ db: db, diff --git a/triedb/pathdb/history.go b/triedb/pathdb/history.go index 0a9f7091fa..7f5b0e35ba 100644 --- a/triedb/pathdb/history.go +++ b/triedb/pathdb/history.go @@ -376,7 +376,7 @@ func syncHistory(stores ...ethdb.AncientWriter) error { // persistent state may appear if the trienode history was disabled during the // previous run. This process detects and resolves such gaps, preventing // unexpected panics. -func repairHistory(db ethdb.Database, isVerkle bool, readOnly bool, stateID uint64, enableTrienode bool) (ethdb.ResettableAncientStore, ethdb.ResettableAncientStore, error) { +func repairHistory(db ethdb.Database, isUBT bool, readOnly bool, stateID uint64, enableTrienode bool) (ethdb.ResettableAncientStore, ethdb.ResettableAncientStore, error) { ancient, err := db.AncientDatadir() if err != nil { // TODO error out if ancient store is disabled. A tons of unit tests @@ -386,7 +386,7 @@ func repairHistory(db ethdb.Database, isVerkle bool, readOnly bool, stateID uint } // State history is mandatory as it is the key component that ensures // resilience to deep reorgs. - states, err := rawdb.NewStateFreezer(ancient, isVerkle, readOnly) + states, err := rawdb.NewStateFreezer(ancient, isUBT, readOnly) if err != nil { log.Crit("Failed to open state history freezer", "err", err) } @@ -395,7 +395,7 @@ func repairHistory(db ethdb.Database, isVerkle bool, readOnly bool, stateID uint // node with state proofs. var trienodes ethdb.ResettableAncientStore if enableTrienode { - trienodes, err = rawdb.NewTrienodeFreezer(ancient, isVerkle, readOnly) + trienodes, err = rawdb.NewTrienodeFreezer(ancient, isUBT, readOnly) if err != nil { log.Crit("Failed to open trienode history freezer", "err", err) } diff --git a/triedb/pathdb/reader.go b/triedb/pathdb/reader.go index e3cfbcba8a..18ec5f2028 100644 --- a/triedb/pathdb/reader.go +++ b/triedb/pathdb/reader.go @@ -177,7 +177,7 @@ func (db *Database) NodeReader(root common.Hash) (database.NodeReader, error) { return &reader{ db: db, state: root, - noHashCheck: db.isVerkle, + noHashCheck: db.isUBT, layer: layer, }, nil }