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..50ae752358 100644
--- a/cmd/geth/bintrie_convert_test.go
+++ b/cmd/geth/bintrie_convert_test.go
@@ -82,8 +82,8 @@ func TestBintrieConvert(t *testing.T) {
defer srcTriedb2.Close()
destTriedb := triedb.NewDatabase(chaindb, &triedb.Config{
- IsVerkle: true,
- PathDB: pathdb.Defaults,
+ IsUBT: true,
+ PathDB: pathdb.Defaults,
})
defer destTriedb.Close()
@@ -190,8 +190,8 @@ func TestBintrieConvertDeleteSource(t *testing.T) {
})
destTriedb := triedb.NewDatabase(chaindb, &triedb.Config{
- IsVerkle: true,
- PathDB: pathdb.Defaults,
+ IsUBT: true,
+ PathDB: pathdb.Defaults,
})
bt, err := bintrie.NewBinaryTrie(types.EmptyBinaryHash, destTriedb)
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 b6f64bdc15..aff45087db 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..e4cb34cb56 100644
--- a/core/bintrie_witness_test.go
+++ b/core/bintrie_witness_test.go
@@ -36,7 +36,7 @@ import (
)
var (
- testVerkleChainConfig = ¶ms.ChainConfig{
+ testUBTChainConfig = ¶ms.ChainConfig{
ChainID: big.NewInt(1),
HomesteadBlock: big.NewInt(0),
EIP150Block: big.NewInt(0),
@@ -51,16 +51,16 @@ 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,
+ UBT: params.DefaultPragueBlobConfig,
},
}
)
-func TestProcessVerkle(t *testing.T) {
+func TestProcessUBT(t *testing.T) {
var (
code = common.FromHex(`6060604052600a8060106000396000f360606040526008565b00`)
intrinsicContractCreationGas, _ = IntrinsicGas(code, nil, nil, true, true, true, true)
@@ -69,12 +69,12 @@ func TestProcessVerkle(t *testing.T) {
// Source: https://gist.github.com/gballet/a23db1e1cb4ed105616b5920feb75985
codeWithExtCodeCopy = common.FromHex(`0x60806040526040516100109061017b565b604051809103906000f08015801561002c573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561007857600080fd5b5060008067ffffffffffffffff8111156100955761009461024a565b5b6040519080825280601f01601f1916602001820160405280156100c75781602001600182028036833780820191505090505b50905060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506020600083833c81610101906101e3565b60405161010d90610187565b61011791906101a3565b604051809103906000f080158015610133573d6000803e3d6000fd5b50600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505061029b565b60d58061046783390190565b6102068061053c83390190565b61019d816101d9565b82525050565b60006020820190506101b86000830184610194565b92915050565b6000819050602082019050919050565b600081519050919050565b6000819050919050565b60006101ee826101ce565b826101f8846101be565b905061020381610279565b925060208210156102435761023e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261028e565b831692505b5050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600061028582516101d9565b80915050919050565b600082821b905092915050565b6101bd806102aa6000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f566852414610030575b600080fd5b61003861004e565b6040516100459190610146565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166381ca91d36040518163ffffffff1660e01b815260040160206040518083038186803b1580156100b857600080fd5b505afa1580156100cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f0919061010a565b905090565b60008151905061010481610170565b92915050565b6000602082840312156101205761011f61016b565b5b600061012e848285016100f5565b91505092915050565b61014081610161565b82525050565b600060208201905061015b6000830184610137565b92915050565b6000819050919050565b600080fd5b61017981610161565b811461018457600080fd5b5056fea2646970667358221220a6a0e11af79f176f9c421b7b12f441356b25f6489b83d38cc828a701720b41f164736f6c63430008070033608060405234801561001057600080fd5b5060b68061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ab5ed15014602d575b600080fd5b60336047565b604051603e9190605d565b60405180910390f35b60006001905090565b6057816076565b82525050565b6000602082019050607060008301846050565b92915050565b600081905091905056fea26469706673582212203a14eb0d5cd07c277d3e24912f110ddda3e553245a99afc4eeefb2fbae5327aa64736f6c63430008070033608060405234801561001057600080fd5b5060405161020638038061020683398181016040528101906100329190610063565b60018160001c6100429190610090565b60008190555050610145565b60008151905061005d8161012e565b92915050565b60006020828403121561007957610078610129565b5b60006100878482850161004e565b91505092915050565b600061009b826100f0565b91506100a6836100f0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156100db576100da6100fa565b5b828201905092915050565b6000819050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b610137816100e6565b811461014257600080fd5b50565b60b3806101536000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806381ca91d314602d575b600080fd5b60336047565b604051603e9190605a565b60405180910390f35b60005481565b6054816073565b82525050565b6000602082019050606d6000830184604d565b92915050565b600081905091905056fea26469706673582212209bff7098a2f526de1ad499866f27d6d0d6f17b74a413036d6063ca6a0998ca4264736f6c63430008070033`)
intrinsicCodeWithExtCodeCopyGas, _ = IntrinsicGas(codeWithExtCodeCopy, nil, nil, true, true, true, true)
- signer = types.LatestSigner(testVerkleChainConfig)
+ signer = types.LatestSigner(testUBTChainConfig)
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
bcdb = rawdb.NewMemoryDatabase() // Database for the blockchain
coinbase = common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7")
gspec = &Genesis{
- Config: testVerkleChainConfig,
+ Config: testUBTChainConfig,
Alloc: GenesisAlloc{
coinbase: {
Balance: big.NewInt(1000000000000000000), // 1 ether
@@ -87,7 +87,7 @@ func TestProcessVerkle(t *testing.T) {
},
}
)
- // Verkle trees use the snapshot, which must be enabled before the
+ // UBTs use the snapshot, which must be enabled before the
// data is saved into the tree+database.
// genesis := gspec.MustCommit(bcdb, triedb)
options := DefaultConfig().WithStateScheme(rawdb.PathScheme)
@@ -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,8 +196,8 @@ 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 {
- chainConfig = testVerkleChainConfig
+ if isUBT {
+ chainConfig = testUBTChainConfig
}
vmContext := NewEVMBlockContext(header, nil, new(common.Address))
evm := vm.NewEVM(vmContext, statedb, chainConfig, vm.Config{})
@@ -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)
}
}
}
@@ -215,22 +215,22 @@ func TestProcessParentBlockHash(t *testing.T) {
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
checkBlockHashes(statedb, false)
})
- t.Run("Verkle", func(t *testing.T) {
+ t.Run("UBT", func(t *testing.T) {
db := rawdb.NewMemoryDatabase()
cacheConfig := DefaultConfig().WithStateScheme(rawdb.PathScheme)
cacheConfig.SnapshotLimit = 0
triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true))
- statedb, _ := state.New(types.EmptyVerkleHash, state.NewDatabase(triedb, nil))
+ statedb, _ := state.New(types.EmptyBinaryHash, state.NewDatabase(triedb, nil))
checkBlockHashes(statedb, true)
})
}
// 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..296ef6bc16 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
}
@@ -2116,11 +2116,29 @@ func (bc *BlockChain) ProcessBlock(ctx context.Context, parentRoot common.Hash,
startTime = time.Now()
statedb *state.StateDB
interrupt atomic.Bool
- sdb = state.NewDatabase(bc.triedb, bc.codedb).WithSnapshot(bc.snaps)
+ sdb state.Database
)
defer interrupt.Store(true) // terminate the prefetch at the end
- if bc.cfg.NoPrefetch {
+ if bc.chainConfig.IsUBT(block.Number(), block.Time()) {
+ sdb = state.NewUBTDatabase(bc.triedb, bc.codedb)
+ } else {
+ 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.
+ //
+ // Note: the main processor and prefetcher share the same reader with a local
+ // cache for mitigating the overhead of state access.
+ type prewarmReader interface {
+ // 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) (state.Reader, state.Reader, error)
+ }
+ warmer, ok := sdb.(prewarmReader)
+
+ if bc.cfg.NoPrefetch || !ok {
statedb, err = state.New(parentRoot, sdb)
if err != nil {
return nil, err
@@ -2131,7 +2149,7 @@ func (bc *BlockChain) ProcessBlock(ctx context.Context, parentRoot common.Hash,
//
// Note: the main processor and prefetcher share the same reader with a local
// cache for mitigating the overhead of state access.
- prefetch, process, err := sdb.ReadersWithCacheStats(parentRoot)
+ prefetch, process, err := warmer.ReadersWithCacheStats(parentRoot)
if err != nil {
return nil, err
}
diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go
index 3614702d1a..18afa9ce9d 100644
--- a/core/blockchain_reader.go
+++ b/core/blockchain_reader.go
@@ -416,19 +416,42 @@ func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) []byte {
// State returns a new mutable state based on the current HEAD block.
func (bc *BlockChain) State() (*state.StateDB, error) {
- return bc.StateAt(bc.CurrentBlock().Root)
+ return bc.StateAt(bc.CurrentBlock())
}
// StateAt returns a new mutable state based on a particular point in time.
-func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
- return state.New(root, state.NewDatabase(bc.triedb, bc.codedb).WithSnapshot(bc.snaps))
+func (bc *BlockChain) StateAt(header *types.Header) (*state.StateDB, error) {
+ if bc.chainConfig.IsUBT(header.Number, header.Time) {
+ return state.New(header.Root, state.NewUBTDatabase(bc.triedb, bc.codedb))
+ }
+ return state.New(header.Root, state.NewMPTDatabase(bc.triedb, bc.codedb).WithSnapshot(bc.snaps))
}
-// HistoricState returns a historic state specified by the given root.
+// StateAtForkBoundary returns a new mutable state based on the parent state
+// and the given header, handling the transition across the UBT fork.
+func (bc *BlockChain) StateAtForkBoundary(parent *types.Header, header *types.Header) (*state.StateDB, error) {
+ // The parent is already in the UBT fork.
+ if bc.chainConfig.IsUBT(parent.Number, parent.Time) {
+ return state.New(parent.Root, state.NewUBTDatabase(bc.triedb, bc.codedb))
+ }
+ // The current block is the first block in the UBT fork
+ // (i.e., the parent is the last MPT block).
+ if bc.chainConfig.IsUBT(header.Number, header.Time) {
+ // TODO(gballet): register chain context if needed
+ return state.New(parent.Root, state.NewUBTDatabase(bc.triedb, bc.codedb))
+ }
+ // Both the parent and current block are in the MPT fork.
+ return state.New(parent.Root, state.NewMPTDatabase(bc.triedb, bc.codedb).WithSnapshot(bc.snaps))
+}
+
+// HistoricState returns a historic state specified by the given header.
// Live states are not available and won't be served, please use `State`
// or `StateAt` instead.
-func (bc *BlockChain) HistoricState(root common.Hash) (*state.StateDB, error) {
- return state.New(root, state.NewHistoricDatabase(bc.triedb, bc.codedb))
+func (bc *BlockChain) HistoricState(header *types.Header) (*state.StateDB, error) {
+ if bc.chainConfig.IsUBT(header.Number, header.Time) {
+ return nil, errors.New("historical state over ubt is not yet supported")
+ }
+ return state.New(header.Root, state.NewHistoricDatabase(bc.triedb, bc.codedb))
}
// Config retrieves the chain's fork configuration.
diff --git a/core/blockchain_test.go b/core/blockchain_test.go
index d3ca21b2b3..1a2ee45291 100644
--- a/core/blockchain_test.go
+++ b/core/blockchain_test.go
@@ -3890,7 +3890,7 @@ func TestTransientStorageReset(t *testing.T) {
t.Fatalf("failed to insert into chain: %v", err)
}
// Check the storage
- state, err := chain.StateAt(chain.CurrentHeader().Root)
+ state, err := chain.StateAt(chain.CurrentHeader())
if err != nil {
t.Fatalf("Failed to load state %v", err)
}
diff --git a/core/chain_makers.go b/core/chain_makers.go
index 8f6eed1697..3bc7f6528b 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().Type().Is(state.TypeUBT) {
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..d77ea10d8c 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -129,22 +129,22 @@ 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,
+ PathDB: pathdb.Defaults,
+ 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 {
- emptyRoot = types.EmptyVerkleHash
+ if isUBT {
+ emptyRoot = types.EmptyBinaryHash
}
db := rawdb.NewMemoryDatabase()
statedb, err := state.New(emptyRoot, state.NewDatabase(triedb.NewDatabase(db, config), nil))
@@ -168,8 +168,8 @@ 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() {
- emptyRoot = types.EmptyVerkleHash
+ if triedb.IsUBT() {
+ emptyRoot = types.EmptyBinaryHash
}
statedb, err := state.New(emptyRoot, state.NewDatabase(triedb, nil))
if err != nil {
@@ -276,10 +276,10 @@ func (e *GenesisMismatchError) Error() string {
// ChainOverrides contains the changes to chain config.
type ChainOverrides struct {
- OverrideOsaka *uint64
- OverrideBPO1 *uint64
- OverrideBPO2 *uint64
- OverrideVerkle *uint64
+ OverrideOsaka *uint64
+ OverrideBPO1 *uint64
+ OverrideBPO2 *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 2ff64e8d21..e15ad00222 100644
--- a/core/genesis_test.go
+++ b/core/genesis_test.go
@@ -285,16 +285,16 @@ 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{
Cancun: params.DefaultCancunBlobConfig,
Prague: params.DefaultPragueBlobConfig,
Osaka: params.DefaultOsakaBlobConfig,
- Verkle: params.DefaultPragueBlobConfig,
+ UBT: params.DefaultPragueBlobConfig,
},
}
@@ -320,8 +320,8 @@ func TestVerkleGenesisCommit(t *testing.T) {
config.NoAsyncFlush = true
triedb := triedb.NewDatabase(db, &triedb.Config{
- IsVerkle: true,
- PathDB: &config,
+ IsUBT: true,
+ PathDB: &config,
})
block := genesis.MustCommit(db, triedb)
if !bytes.Equal(block.Root().Bytes(), expected) {
@@ -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..6de58af63b 100644
--- a/core/state/database.go
+++ b/core/state/database.go
@@ -20,22 +20,36 @@ 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"
- "github.com/ethereum/go-ethereum/crypto"
"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"
)
+// 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)
@@ -139,184 +153,27 @@ 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
-}
-
-// 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 {
- triedb *triedb.Database
- codedb *CodeDB
- snap *snapshot.Tree
+ // IsUBT returns true if the trie is unified binary trie based.
+ IsUBT() bool
}
// NewDatabase creates a state database with the provided data sources.
-func NewDatabase(triedb *triedb.Database, codedb *CodeDB) *CachingDB {
- if codedb == nil {
- codedb = NewCodeDB(triedb.Disk())
- }
- return &CachingDB{
- triedb: triedb,
- codedb: codedb,
+//
+// Deprecated, please use NewMPTDatabase or NewUBTDatabase directly.
+func NewDatabase(tdb *triedb.Database, codedb *CodeDB) Database {
+ if tdb.IsUBT() {
+ return NewUBTDatabase(tdb, codedb)
}
+ return NewMPTDatabase(tdb, 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 {
- 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) {
- var readers []StateReader
-
- // Configure the state reader using the standalone snapshot in hash mode.
- // This reader offers improved performance but is optional and only
- // partially useful if the snapshot is not fully generated.
- if db.TrieDB().Scheme() == rawdb.HashScheme && db.snap != nil {
- snap := db.snap.Snapshot(stateRoot)
- if snap != nil {
- readers = append(readers, newFlatReader(snap))
- }
- }
- // 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 *CachingDB) 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 *CachingDB) 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 *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)
- }
- }
- tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb)
- if err != nil {
- return nil, err
- }
- return tr, nil
-}
-
-// 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
- }
- tr, err := trie.NewStateTrie(trie.StorageTrieID(stateRoot, crypto.Keccak256Hash(address.Bytes()), root), db.triedb)
- if err != nil {
- return nil, err
- }
- return tr, nil
-}
-
-// TrieDB retrieves any intermediate trie-node caching layer.
-func (db *CachingDB) TrieDB() *triedb.Database {
- return db.triedb
-}
-
-// Snapshot returns the underlying state snapshot.
-func (db *CachingDB) 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 {
- // 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 *CachingDB) Iteratee(root common.Hash) (Iteratee, error) {
- return newStateIteratee(!db.triedb.IsVerkle(), root, db.triedb, db.snap)
-}
-
// mustCopyTrie returns a deep-copied trie.
func mustCopyTrie(t Trie) Trie {
switch t := t.(type) {
diff --git a/core/state/database_history.go b/core/state/database_history.go
index 0dbb8cc546..d1ed2fe194 100644
--- a/core/state/database_history.go
+++ b/core/state/database_history.go
@@ -223,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{
diff --git a/core/state/database_mpt.go b/core/state/database_mpt.go
new file mode 100644
index 0000000000..bf9c7c9fff
--- /dev/null
+++ b/core/state/database_mpt.go
@@ -0,0 +1,178 @@
+// Copyright 2026 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/crypto"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/trie"
+ "github.com/ethereum/go-ethereum/triedb"
+)
+
+// MPTDatabase is an implementation of Database interface for Merkle Patricia Tries.
+// It leverages both trie and state snapshot to provide functionalities for state
+// access.
+type MPTDatabase struct {
+ triedb *triedb.Database
+ codedb *CodeDB
+ snap *snapshot.Tree
+}
+
+// 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 &MPTDatabase{
+ triedb: tdb,
+ codedb: codedb,
+ }
+}
+
+// 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 *MPTDatabase) StateReader(stateRoot common.Hash) (StateReader, error) {
+ var readers []StateReader
+
+ // Configure the state reader using the standalone snapshot in hash mode.
+ // This reader offers improved performance but is optional and only
+ // partially useful if the snapshot is not fully generated.
+ if db.TrieDB().Scheme() == rawdb.HashScheme && db.snap != nil {
+ snap := db.snap.Snapshot(stateRoot)
+ if snap != nil {
+ readers = append(readers, newFlatReader(snap))
+ }
+ }
+ // 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 *MPTDatabase) 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 *MPTDatabase) 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 *MPTDatabase) OpenTrie(root common.Hash) (Trie, error) {
+ tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb)
+ if err != nil {
+ return nil, err
+ }
+ return tr, nil
+}
+
+// OpenStorageTrie opens the storage trie of an account.
+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
+ }
+ return tr, nil
+}
+
+// TrieDB retrieves any intermediate trie-node caching layer.
+func (db *MPTDatabase) TrieDB() *triedb.Database {
+ return db.triedb
+}
+
+// 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 *MPTDatabase) 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 *MPTDatabase) Iteratee(root common.Hash) (Iteratee, error) {
+ return newStateIteratee(true, root, db.triedb, db.snap)
+}
diff --git a/core/state/database_ubt.go b/core/state/database_ubt.go
new file mode 100644
index 0000000000..39aa64508b
--- /dev/null
+++ b/core/state/database_ubt.go
@@ -0,0 +1,138 @@
+// Copyright 2026 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/trie/bintrie"
+ "github.com/ethereum/go-ethereum/triedb"
+)
+
+// 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
+}
+
+// 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 &UBTDatabase{
+ triedb: triedb,
+ codedb: codedb,
+ }
+}
+
+// StateReader returns a state reader associated with the specified state root.
+func (db *UBTDatabase) 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 *UBTDatabase) 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 *UBTDatabase) 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 *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 *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 *UBTDatabase) TrieDB() *triedb.Database {
+ return db.triedb
+}
+
+// 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 *UBTDatabase) 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
+ }
+ }
+ 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 *UBTDatabase) Iteratee(root common.Hash) (Iteratee, error) {
+ return newStateIteratee(false, root, db.triedb, nil)
+}
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 a4a9f5121b..a812359368 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.Type().Is(TypeMPT)) || 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 fc2da59a05..956871472d 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.Type().Is(TypeUBT) {
sdb.accessEvents = NewAccessEvents()
}
return sdb, nil
@@ -861,7 +861,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
start = time.Now()
workers errgroup.Group
)
- if s.db.TrieDB().IsVerkle() {
+ 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,
@@ -925,9 +925,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().IsVerkle() {
+ // 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
@@ -968,7 +968,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.Type().Is(TypeMPT) {
if trie := s.prefetcher.trie(common.Hash{}, s.originalRoot); trie == nil {
log.Error("Failed to retrieve account pre-fetcher trie")
} else {
@@ -1129,7 +1129,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.Type().Is(TypeUBT) {
continue
}
if noStorageWiping {
diff --git a/core/state/statedb_fuzz_test.go b/core/state/statedb_fuzz_test.go
index 3582185344..a8017e5568 100644
--- a/core/state/statedb_fuzz_test.go
+++ b/core/state/statedb_fuzz_test.go
@@ -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)
}
diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go
index 6936372c50..601970ff20 100644
--- a/core/state/statedb_test.go
+++ b/core/state/statedb_test.go
@@ -1274,7 +1274,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")
)
@@ -1288,8 +1288,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
diff --git a/core/state/trie_prefetcher.go b/core/state/trie_prefetcher.go
index a9faddcdff..a0310eb3b3 100644
--- a/core/state/trie_prefetcher.go
+++ b/core/state/trie_prefetcher.go
@@ -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().IsVerkle(),
+ 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().IsVerkle() {
+ // 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
diff --git a/core/state/trie_prefetcher_test.go b/core/state/trie_prefetcher_test.go
index dad208d01a..8a03d93a08 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..0a324379f9 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().Type().Is(state.TypeUBT) {
statedb.AccessEvents().Merge(evm.AccessEvents)
}
return MakeReceipt(evm, result, statedb, blockNumber, blockHash, blockTime, tx, gp.CumulativeUsed(), root), nil
diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go
index 7155a67a9b..4030a0c339 100644
--- a/core/txpool/blobpool/blobpool.go
+++ b/core/txpool/blobpool/blobpool.go
@@ -441,9 +441,9 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserver txpool.Reser
// Initialize the state with head block, or fallback to empty one in
// case the head state is not available (might occur when node is not
// fully synced).
- state, err := p.chain.StateAt(head.Root)
+ state, err := p.chain.StateAt(head)
if err != nil {
- state, err = p.chain.StateAt(types.EmptyRootHash)
+ state, err = p.chain.StateAt(p.chain.Genesis().Header())
}
if err != nil {
return err
@@ -894,7 +894,7 @@ func (p *BlobPool) Reset(oldHead, newHead *types.Header) {
// Handle reorg buffer timeouts evicting old gapped transactions
p.evictGapped()
- statedb, err := p.chain.StateAt(newHead.Root)
+ statedb, err := p.chain.StateAt(newHead)
if err != nil {
log.Error("Failed to reset blobpool state", "err", err)
return
diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go
index ba96bea8ed..7c57755401 100644
--- a/core/txpool/blobpool/blobpool_test.go
+++ b/core/txpool/blobpool/blobpool_test.go
@@ -45,6 +45,7 @@ import (
"github.com/ethereum/go-ethereum/internal/testrand"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
+ "github.com/ethereum/go-ethereum/trie"
"github.com/holiman/billy"
"github.com/holiman/uint256"
)
@@ -180,10 +181,14 @@ func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block
return bc.blocks[number]
}
-func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) {
+func (bc *testBlockChain) StateAt(header *types.Header) (*state.StateDB, error) {
return bc.statedb, nil
}
+func (bc *testBlockChain) Genesis() *types.Block {
+ return types.NewBlock(bc.CurrentBlock(), nil, nil, trie.NewStackTrie(nil))
+}
+
// reserver is a utility struct to sanity check that accounts are
// properly reserved by the blobpool (no duplicate reserves or unreserves).
type reserver struct {
diff --git a/core/txpool/blobpool/interface.go b/core/txpool/blobpool/interface.go
index 6f296a54bd..d7beae9b25 100644
--- a/core/txpool/blobpool/interface.go
+++ b/core/txpool/blobpool/interface.go
@@ -32,6 +32,9 @@ type BlockChain interface {
// CurrentBlock returns the current head of the chain.
CurrentBlock() *types.Header
+ // Genesis returns the genesis block of the chain.
+ Genesis() *types.Block
+
// CurrentFinalBlock returns the current block below which blobs should not
// be maintained anymore for reorg purposes.
CurrentFinalBlock() *types.Header
@@ -39,6 +42,6 @@ type BlockChain interface {
// GetBlock retrieves a specific block, used during pool resets.
GetBlock(hash common.Hash, number uint64) *types.Block
- // StateAt returns a state database for a given root hash (generally the head).
- StateAt(root common.Hash) (*state.StateDB, error)
+ // StateAt returns a state database for a given chain header (generally the head).
+ StateAt(header *types.Header) (*state.StateDB, error)
}
diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go
index 93b3cb5be2..78a0161c41 100644
--- a/core/txpool/legacypool/legacypool.go
+++ b/core/txpool/legacypool/legacypool.go
@@ -129,11 +129,14 @@ type BlockChain interface {
// CurrentBlock returns the current head of the chain.
CurrentBlock() *types.Header
+ // Genesis returns the genesis block of the chain.
+ Genesis() *types.Block
+
// GetBlock retrieves a specific block, used during pool resets.
GetBlock(hash common.Hash, number uint64) *types.Block
- // StateAt returns a state database for a given root hash (generally the head).
- StateAt(root common.Hash) (*state.StateDB, error)
+ // StateAt returns a state database for a given chain header (generally the head).
+ StateAt(header *types.Header) (*state.StateDB, error)
}
// Config are the configuration parameters of the transaction pool.
@@ -317,9 +320,9 @@ func (pool *LegacyPool) Init(gasTip uint64, head *types.Header, reserver txpool.
// Initialize the state with head block, or fallback to empty one in
// case the head state is not available (might occur when node is not
// fully synced).
- statedb, err := pool.chain.StateAt(head.Root)
+ statedb, err := pool.chain.StateAt(head)
if err != nil {
- statedb, err = pool.chain.StateAt(types.EmptyRootHash)
+ statedb, err = pool.chain.StateAt(pool.chain.Genesis().Header())
}
if err != nil {
return err
@@ -1379,7 +1382,7 @@ func (pool *LegacyPool) reset(oldHead, newHead *types.Header) {
if newHead == nil {
newHead = pool.chain.CurrentBlock() // Special case during testing
}
- statedb, err := pool.chain.StateAt(newHead.Root)
+ statedb, err := pool.chain.StateAt(newHead)
if err != nil {
log.Error("Failed to reset txpool state", "err", err)
return
diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go
index fb994d8208..f8592ba001 100644
--- a/core/txpool/legacypool/legacypool_test.go
+++ b/core/txpool/legacypool/legacypool_test.go
@@ -91,10 +91,14 @@ func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block
return types.NewBlock(bc.CurrentBlock(), nil, nil, trie.NewStackTrie(nil))
}
-func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) {
+func (bc *testBlockChain) StateAt(header *types.Header) (*state.StateDB, error) {
return bc.statedb, nil
}
+func (bc *testBlockChain) Genesis() *types.Block {
+ return types.NewBlock(bc.CurrentBlock(), nil, nil, trie.NewStackTrie(nil))
+}
+
func (bc *testBlockChain) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription {
return bc.chainHeadFeed.Subscribe(ch)
}
diff --git a/core/txpool/locals/tx_tracker_test.go b/core/txpool/locals/tx_tracker_test.go
index dde8754605..34fb4d0b74 100644
--- a/core/txpool/locals/tx_tracker_test.go
+++ b/core/txpool/locals/tx_tracker_test.go
@@ -102,7 +102,7 @@ func (env *testEnv) setGasTip(gasTip uint64) {
func (env *testEnv) makeTx(nonce uint64, gasPrice *big.Int) *types.Transaction {
if nonce == 0 {
head := env.chain.CurrentHeader()
- state, _ := env.chain.StateAt(head.Root)
+ state, _ := env.chain.StateAt(head)
nonce = state.GetNonce(address)
}
if gasPrice == nil {
@@ -114,7 +114,7 @@ func (env *testEnv) makeTx(nonce uint64, gasPrice *big.Int) *types.Transaction {
func (env *testEnv) makeTxs(n int) []*types.Transaction {
head := env.chain.CurrentHeader()
- state, _ := env.chain.StateAt(head.Root)
+ state, _ := env.chain.StateAt(head)
nonce := state.GetNonce(address)
var txs []*types.Transaction
diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go
index 25647e0cce..9c78748422 100644
--- a/core/txpool/txpool.go
+++ b/core/txpool/txpool.go
@@ -50,11 +50,14 @@ type BlockChain interface {
// CurrentBlock returns the current head of the chain.
CurrentBlock() *types.Header
+ // Genesis returns the genesis block of the chain.
+ Genesis() *types.Block
+
// SubscribeChainHeadEvent subscribes to new blocks being added to the chain.
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
- // StateAt returns a state database for a given root hash (generally the head).
- StateAt(root common.Hash) (*state.StateDB, error)
+ // StateAt returns a state database for a given chain header (generally the head).
+ StateAt(header *types.Header) (*state.StateDB, error)
}
// TxPool is an aggregator for various transaction specific pools, collectively
@@ -87,9 +90,9 @@ func New(gasTip uint64, chain BlockChain, subpools []SubPool) (*TxPool, error) {
// Initialize the state with head block, or fallback to empty one in
// case the head state is not available (might occur when node is not
// fully synced).
- statedb, err := chain.StateAt(head.Root)
+ statedb, err := chain.StateAt(head)
if err != nil {
- statedb, err = chain.StateAt(types.EmptyRootHash)
+ statedb, err = chain.StateAt(chain.Genesis().Header())
}
if err != nil {
return nil, err
@@ -185,7 +188,7 @@ func (p *TxPool) loop(head *types.Header) {
case resetBusy <- struct{}{}:
// Updates the statedb with the new chain head. The head state may be
// unavailable if the initial state sync has not yet completed.
- if statedb, err := p.chain.StateAt(newHead.Root); err != nil {
+ if statedb, err := p.chain.StateAt(newHead); err != nil {
log.Error("Failed to reset txpool state", "err", err)
} else {
p.stateLock.Lock()
diff --git a/core/types/hashes.go b/core/types/hashes.go
index 22f1f946dc..db8912a66f 100644
--- a/core/types/hashes.go
+++ b/core/types/hashes.go
@@ -43,9 +43,6 @@ var (
// EmptyRequestsHash is the known hash of an empty request set, sha256("").
EmptyRequestsHash = common.HexToHash("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
- // EmptyVerkleHash is the known hash of an empty verkle trie.
- EmptyVerkleHash = common.Hash{}
-
// EmptyBinaryHash is the known hash of an empty binary trie.
EmptyBinaryHash = common.Hash{}
)
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 cfc837fb62..8f68478842 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/api_backend.go b/eth/api_backend.go
index a4e976b1b8..33fe4fe5d9 100644
--- a/eth/api_backend.go
+++ b/eth/api_backend.go
@@ -236,9 +236,9 @@ func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.B
if header == nil {
return nil, nil, errors.New("header not found")
}
- stateDb, err := b.eth.BlockChain().StateAt(header.Root)
+ stateDb, err := b.eth.BlockChain().StateAt(header)
if err != nil {
- stateDb, err = b.eth.BlockChain().HistoricState(header.Root)
+ stateDb, err = b.eth.BlockChain().HistoricState(header)
if err != nil {
return nil, nil, err
}
@@ -261,9 +261,9 @@ func (b *EthAPIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockN
if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash {
return nil, nil, errors.New("hash is not currently canonical")
}
- stateDb, err := b.eth.BlockChain().StateAt(header.Root)
+ stateDb, err := b.eth.BlockChain().StateAt(header)
if err != nil {
- stateDb, err = b.eth.BlockChain().HistoricState(header.Root)
+ stateDb, err = b.eth.BlockChain().HistoricState(header)
if err != nil {
return nil, nil, err
}
diff --git a/eth/api_debug.go b/eth/api_debug.go
index 5dd535e672..260e24c2ee 100644
--- a/eth/api_debug.go
+++ b/eth/api_debug.go
@@ -82,7 +82,7 @@ func (api *DebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) {
if header == nil {
return state.Dump{}, fmt.Errorf("block #%d not found", blockNr)
}
- stateDb, err := api.eth.BlockChain().StateAt(header.Root)
+ stateDb, err := api.eth.BlockChain().StateAt(header)
if err != nil {
return state.Dump{}, err
}
@@ -167,7 +167,7 @@ func (api *DebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, start hex
if header == nil {
return state.Dump{}, fmt.Errorf("block #%d not found", number)
}
- stateDb, err = api.eth.BlockChain().StateAt(header.Root)
+ stateDb, err = api.eth.BlockChain().StateAt(header)
if err != nil {
return state.Dump{}, err
}
@@ -177,7 +177,7 @@ func (api *DebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, start hex
if block == nil {
return state.Dump{}, fmt.Errorf("block %s not found", hash.Hex())
}
- stateDb, err = api.eth.BlockChain().StateAt(block.Root())
+ stateDb, err = api.eth.BlockChain().StateAt(block.Header())
if err != nil {
return state.Dump{}, err
}
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/catalyst/api_test.go b/eth/catalyst/api_test.go
index d126c362fe..1f38c4dd8a 100644
--- a/eth/catalyst/api_test.go
+++ b/eth/catalyst/api_test.go
@@ -299,7 +299,7 @@ func TestEth2NewBlock(t *testing.T) {
ethservice.BlockChain().SubscribeRemovedLogsEvent(rmLogsCh)
for i := 0; i < 10; i++ {
- statedb, _ := ethservice.BlockChain().StateAt(parent.Root())
+ statedb, _ := ethservice.BlockChain().StateAt(parent.Header())
nonce := statedb.GetNonce(testAddr)
tx, _ := types.SignTx(types.NewContractCreation(nonce, new(big.Int), 1000000, big.NewInt(2*params.InitialBaseFee), logCode), types.LatestSigner(ethservice.BlockChain().Config()), testKey)
ethservice.TxPool().Add([]*types.Transaction{tx}, true)
@@ -478,7 +478,7 @@ func TestFullAPI(t *testing.T) {
)
callback := func(parent *types.Header) {
- statedb, _ := ethservice.BlockChain().StateAt(parent.Root)
+ statedb, _ := ethservice.BlockChain().StateAt(parent)
nonce := statedb.GetNonce(testAddr)
tx, _ := types.SignTx(types.NewContractCreation(nonce, new(big.Int), 1000000, big.NewInt(2*params.InitialBaseFee), logCode), types.LatestSigner(ethservice.BlockChain().Config()), testKey)
ethservice.TxPool().Add([]*types.Transaction{tx}, false)
@@ -604,7 +604,7 @@ func TestNewPayloadOnInvalidChain(t *testing.T) {
logCode = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
)
for i := 0; i < 10; i++ {
- statedb, _ := ethservice.BlockChain().StateAt(parent.Root)
+ statedb, _ := ethservice.BlockChain().StateAt(parent)
tx := types.MustSignNewTx(testKey, signer, &types.LegacyTx{
Nonce: statedb.GetNonce(testAddr),
Value: new(big.Int),
@@ -1263,7 +1263,7 @@ func setupBodies(t *testing.T) (*node.Node, *eth.Ethereum, []*types.Block) {
// Each block, this callback will include two txs that generate body values like logs and requests.
callback := func(parent *types.Header) {
var (
- statedb, _ = ethservice.BlockChain().StateAt(parent.Root)
+ statedb, _ = ethservice.BlockChain().StateAt(parent)
// Create tx to trigger log generator.
tx1, _ = types.SignTx(types.NewContractCreation(statedb.GetNonce(testAddr), new(big.Int), 1000000, big.NewInt(2*params.InitialBaseFee), logCode), types.LatestSigner(ethservice.BlockChain().Config()), testKey)
// Create tx to trigger deposit generator.
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..ed85562f44 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/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go
index 02a25bc4d8..e57c6e11c5 100644
--- a/eth/gasprice/gasprice_test.go
+++ b/eth/gasprice/gasprice_test.go
@@ -104,7 +104,7 @@ func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.
func (b *testBackend) Pending() (*types.Block, types.Receipts, *state.StateDB) {
if b.pending {
block := b.chain.GetBlockByNumber(testHead + 1)
- state, _ := b.chain.StateAt(block.Root())
+ state, _ := b.chain.StateAt(block.Header())
return block, b.chain.GetReceiptsByHash(block.Hash()), state
}
return nil, nil, nil
diff --git a/eth/state_accessor.go b/eth/state_accessor.go
index 04aac321cb..7467e1e590 100644
--- a/eth/state_accessor.go
+++ b/eth/state_accessor.go
@@ -56,7 +56,7 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, base *st
// The state is available in live database, create a reference
// on top to prevent garbage collection and return a release
// function to deref it.
- if statedb, err = eth.blockchain.StateAt(block.Root()); err == nil {
+ if statedb, err = eth.blockchain.StateAt(block.Header()); err == nil {
eth.blockchain.TrieDB().Reference(block.Root(), common.Hash{})
return statedb, func() {
eth.blockchain.TrieDB().Dereference(block.Root())
@@ -182,11 +182,12 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, base *st
func (eth *Ethereum) pathState(block *types.Block) (*state.StateDB, func(), error) {
// Check if the requested state is available in the live chain.
- statedb, err := eth.blockchain.StateAt(block.Root())
+ header := block.Header()
+ statedb, err := eth.blockchain.StateAt(header)
if err == nil {
return statedb, noopReleaser, nil
}
- statedb, err = eth.blockchain.HistoricState(block.Root())
+ statedb, err = eth.blockchain.HistoricState(header)
if err == nil {
return statedb, noopReleaser, nil
}
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/eth/tracers/api_test.go b/eth/tracers/api_test.go
index ecf3c99c8f..0e62b9631d 100644
--- a/eth/tracers/api_test.go
+++ b/eth/tracers/api_test.go
@@ -152,7 +152,7 @@ func (b *testBackend) teardown() {
}
func (b *testBackend) StateAtBlock(ctx context.Context, block *types.Block, base *state.StateDB, readOnly bool, preferDisk bool) (*state.StateDB, StateReleaseFunc, error) {
- statedb, err := b.chain.StateAt(block.Root())
+ statedb, err := b.chain.StateAt(block.Header())
if err != nil {
return nil, nil, errStateNotFound
}
diff --git a/eth/tracers/internal/tracetest/selfdestruct_state_test.go b/eth/tracers/internal/tracetest/selfdestruct_state_test.go
index bb1a3d9f18..692c5eb775 100644
--- a/eth/tracers/internal/tracetest/selfdestruct_state_test.go
+++ b/eth/tracers/internal/tracetest/selfdestruct_state_test.go
@@ -162,7 +162,7 @@ func setupTestBlockchain(t *testing.T, genesis *core.Genesis, tx *types.Transact
if genesisBlock == nil {
t.Fatalf("failed to get genesis block")
}
- statedb, err := blockchain.StateAt(genesisBlock.Root())
+ statedb, err := blockchain.StateAt(genesisBlock.Header())
if err != nil {
t.Fatalf("failed to get state: %v", err)
}
diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go
index b010eeaa08..6cf52d636a 100644
--- a/internal/ethapi/api_test.go
+++ b/internal/ethapi/api_test.go
@@ -572,7 +572,7 @@ func (b testBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.Bloc
if header == nil {
return nil, nil, errors.New("header not found")
}
- stateDb, err := b.chain.StateAt(header.Root)
+ stateDb, err := b.chain.StateAt(header)
return stateDb, header, err
}
func (b testBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) {
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/miner/miner_test.go b/miner/miner_test.go
index 13475a19b6..5411418b13 100644
--- a/miner/miner_test.go
+++ b/miner/miner_test.go
@@ -80,10 +80,14 @@ func (bc *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block
return types.NewBlock(bc.CurrentBlock(), nil, nil, trie.NewStackTrie(nil))
}
-func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) {
+func (bc *testBlockChain) StateAt(header *types.Header) (*state.StateDB, error) {
return bc.statedb, nil
}
+func (bc *testBlockChain) Genesis() *types.Block {
+ return types.NewBlock(bc.CurrentBlock(), nil, nil, trie.NewStackTrie(nil))
+}
+
func (bc *testBlockChain) HasState(root common.Hash) bool {
return bc.root == root
}
diff --git a/miner/worker.go b/miner/worker.go
index 39a61de318..1d648f0ee1 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -324,7 +324,7 @@ func (miner *Miner) prepareWork(ctx context.Context, genParams *generateParams,
// makeEnv creates a new environment for the sealing block.
func (miner *Miner) makeEnv(parent *types.Header, header *types.Header, coinbase common.Address, witness bool) (*environment, error) {
// Retrieve the parent state to execute on top.
- state, err := miner.chain.StateAt(parent.Root)
+ state, err := miner.chain.StateAtForkBoundary(parent, header)
if err != nil {
return nil, err
}
diff --git a/params/config.go b/params/config.go
index 197ed56f8a..17508cbf27 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,18 +474,18 @@ 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.
+ // genesis state will be committed using the Binary tree, eliminating the
+ // need for any Binary transition later.
//
- // This is a temporary flag only for verkle devnet testing, where verkle is
+ // This is a temporary flag only for binary devnet testing, where binary is
// activated at genesis, and the configured activation date has already passed.
//
- // In production networks (mainnet and public testnets), verkle activation
+ // In production networks (mainnet and public testnets), binary 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(" - UBT: @%-10v blob: (%s)\n", *c.UBTTime, c.BlobScheduleConfig.UBT)
}
banner += fmt.Sprintf("\nAll fork specifications can be found at https://ethereum.github.io/execution-specs/src/ethereum/forks/\n")
return banner
@@ -717,13 +717,13 @@ type BlobScheduleConfig struct {
Cancun *BlobConfig `json:"cancun,omitempty"`
Prague *BlobConfig `json:"prague,omitempty"`
Osaka *BlobConfig `json:"osaka,omitempty"`
- Verkle *BlobConfig `json:"verkle,omitempty"`
BPO1 *BlobConfig `json:"bpo1,omitempty"`
BPO2 *BlobConfig `json:"bpo2,omitempty"`
BPO3 *BlobConfig `json:"bpo3,omitempty"`
BPO4 *BlobConfig `json:"bpo4,omitempty"`
BPO5 *BlobConfig `json:"bpo5,omitempty"`
Amsterdam *BlobConfig `json:"amsterdam,omitempty"`
+ UBT *BlobConfig `json:"ubt,omitempty"`
}
// IsHomestead returns whether num is either equal to the homestead block or greater.
@@ -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..bece8ae610 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..3db988a993 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/tests/state_test_util.go b/tests/state_test_util.go
index 1dd1bf6a04..569cc37913 100644
--- a/tests/state_test_util.go
+++ b/tests/state_test_util.go
@@ -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}
}
diff --git a/trie/bintrie/trie.go b/trie/bintrie/trie.go
index b1e3c991c0..23d014eb33 100644
--- a/trie/bintrie/trie.go
+++ b/trie/bintrie/trie.go
@@ -377,8 +377,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..04c76cfd53 100644
--- a/triedb/pathdb/database.go
+++ b/triedb/pathdb/database.go
@@ -100,7 +100,7 @@ func merkleNodeHasher(blob []byte) (common.Hash, error) {
// binaryNodeHasher computes the hash of the given verkle node.
func binaryNodeHasher(blob []byte) (common.Hash, error) {
if len(blob) == 0 {
- return types.EmptyVerkleHash, nil
+ return types.EmptyBinaryHash, nil
}
n, err := bintrie.DeserializeNode(blob, 0)
if err != nil {
@@ -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..8ceb22eaba 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/layertree_test.go b/triedb/pathdb/layertree_test.go
index 82eb182990..0dcfd7aae8 100644
--- a/triedb/pathdb/layertree_test.go
+++ b/triedb/pathdb/layertree_test.go
@@ -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}: {},
},
},
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
}