diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 7de1eb6949..d5dafc6b19 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -416,7 +416,8 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB { tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true}) - sdb := state.NewDatabase(tdb, nil) + vdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true}) + sdb := state.NewDatabase(tdb, vdb, nil) statedb, _ := state.New(types.EmptyRootHash, sdb) for addr, a := range accounts { statedb.SetCode(addr, a.Code) diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index b2cf28353b..93c2f9e3cf 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -221,13 +221,14 @@ func runCmd(ctx *cli.Context) error { } db := rawdb.NewMemoryDatabase() + verkledb := triedb.NewDatabase(db, triedb.VerkleDefaults) triedb := triedb.NewDatabase(db, &triedb.Config{ Preimages: preimages, HashDB: hashdb.Defaults, }) defer triedb.Close() - genesis := genesisConfig.MustCommit(db, triedb) - sdb := state.NewDatabase(triedb, nil) + genesis := genesisConfig.MustCommit(db, triedb, verkledb) + sdb := state.NewDatabase(triedb, verkledb, nil) prestate, _ = state.New(genesis.Root(), sdb) chainConfig = genesisConfig.Config diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index 2279509542..7cf7a02a5d 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -243,10 +243,11 @@ func initGenesis(ctx *cli.Context) error { } defer chaindb.Close() - triedb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle()) + triedb, verkledb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle()) defer triedb.Close() + defer verkledb.Close() - _, hash, _, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides) + _, hash, _, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, verkledb, genesis, &overrides) if err != nil { utils.Fatalf("Failed to write genesis block: %v", err) } @@ -594,10 +595,11 @@ func dump(ctx *cli.Context) error { if err != nil { return err } - triedb := utils.MakeTrieDatabase(ctx, db, true, true, false) // always enable preimage lookup + triedb, verkledb := utils.MakeTrieDatabase(ctx, db, true, true, false) // always enable preimage lookup defer triedb.Close() + defer verkledb.Close() - state, err := state.New(root, state.NewDatabase(triedb, nil)) + state, err := state.New(root, state.NewDatabase(triedb, verkledb, nil)) if err != nil { return err } diff --git a/cmd/geth/dbcmd.go b/cmd/geth/dbcmd.go index 44a52521f0..a31edc3830 100644 --- a/cmd/geth/dbcmd.go +++ b/cmd/geth/dbcmd.go @@ -524,8 +524,9 @@ func dbDumpTrie(ctx *cli.Context) error { db := utils.MakeChainDatabase(ctx, stack, true) defer db.Close() - triedb := utils.MakeTrieDatabase(ctx, db, false, true, false) + triedb, verkledb := utils.MakeTrieDatabase(ctx, db, false, true, false) defer triedb.Close() + defer verkledb.Close() var ( state []byte @@ -859,8 +860,9 @@ func inspectHistory(ctx *cli.Context) error { db := utils.MakeChainDatabase(ctx, stack, true) defer db.Close() - triedb := utils.MakeTrieDatabase(ctx, db, false, false, false) + triedb, verkledb := utils.MakeTrieDatabase(ctx, db, false, false, false) defer triedb.Close() + defer verkledb.Close() var ( err error diff --git a/cmd/geth/snapshot.go b/cmd/geth/snapshot.go index f0be52a0df..ea145bb001 100644 --- a/cmd/geth/snapshot.go +++ b/cmd/geth/snapshot.go @@ -217,8 +217,9 @@ func verifyState(ctx *cli.Context) error { log.Error("Failed to load head block") return errors.New("no head block") } - triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false) + triedb, verkledb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false) defer triedb.Close() + defer verkledb.Close() snapConfig := snapshot.Config{ CacheSize: 256, @@ -272,8 +273,9 @@ func traverseState(ctx *cli.Context) error { chaindb := utils.MakeChainDatabase(ctx, stack, true) defer chaindb.Close() - triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false) + triedb, verkledb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false) defer triedb.Close() + defer verkledb.Close() headBlock := rawdb.ReadHeadBlock(chaindb) if headBlock == nil { @@ -381,8 +383,9 @@ func traverseRawState(ctx *cli.Context) error { chaindb := utils.MakeChainDatabase(ctx, stack, true) defer chaindb.Close() - triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false) + triedb, verkledb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false) defer triedb.Close() + defer verkledb.Close() headBlock := rawdb.ReadHeadBlock(chaindb) if headBlock == nil { @@ -548,8 +551,9 @@ func dumpState(ctx *cli.Context) error { if err != nil { return err } - triedb := utils.MakeTrieDatabase(ctx, db, false, true, false) + triedb, verkledb := utils.MakeTrieDatabase(ctx, db, false, true, false) defer triedb.Close() + defer verkledb.Close() snapConfig := snapshot.Config{ CacheSize: 256, @@ -630,8 +634,9 @@ func snapshotExportPreimages(ctx *cli.Context) error { chaindb := utils.MakeChainDatabase(ctx, stack, true) defer chaindb.Close() - triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false) + triedb, verkledb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false) defer triedb.Close() + defer verkledb.Close() var root common.Hash if ctx.NArg() > 1 { diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index f5fc94cebc..509c10769e 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2262,7 +2262,7 @@ func MakeConsolePreloads(ctx *cli.Context) []string { } // MakeTrieDatabase constructs a trie database based on the configured scheme. -func MakeTrieDatabase(ctx *cli.Context, disk ethdb.Database, preimage bool, readOnly bool, isVerkle bool) *triedb.Database { +func MakeTrieDatabase(ctx *cli.Context, disk ethdb.Database, preimage bool, readOnly bool, isVerkle bool) (*triedb.Database, *triedb.Database) { config := &triedb.Config{ Preimages: preimage, IsVerkle: isVerkle, @@ -2276,12 +2276,12 @@ func MakeTrieDatabase(ctx *cli.Context, disk ethdb.Database, preimage bool, read // ignore the parameter silently. TODO(rjl493456442) // please config it if read mode is implemented. config.HashDB = hashdb.Defaults - return triedb.NewDatabase(disk, config) + return triedb.NewDatabase(disk, config), triedb.NewDatabase(disk, triedb.VerkleDefaults) } if readOnly { config.PathDB = pathdb.ReadOnly } else { config.PathDB = pathdb.Defaults } - return triedb.NewDatabase(disk, config) + return triedb.NewDatabase(disk, config), triedb.NewDatabase(disk, triedb.VerkleDefaults) } diff --git a/cmd/utils/history_test.go b/cmd/utils/history_test.go index d3c6bda1c5..1e6244cdc6 100644 --- a/cmd/utils/history_test.go +++ b/cmd/utils/history_test.go @@ -166,7 +166,7 @@ func TestHistoryImportAndExport(t *testing.T) { db2.Close() }) - genesis.MustCommit(db2, triedb.NewDatabase(db2, triedb.HashDefaults)) + genesis.MustCommit(db2, triedb.NewDatabase(db2, triedb.HashDefaults), triedb.NewDatabase(db2, triedb.VerkleDefaults)) imported, err := core.NewBlockChain(db2, nil, genesis, nil, ethash.NewFaker(), vm.Config{}, nil) if err != nil { t.Fatalf("unable to initialize chain: %v", err) diff --git a/core/blockchain.go b/core/blockchain.go index c08b05e7f4..608857193d 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -234,6 +234,7 @@ type BlockChain struct { lastWrite uint64 // Last block when the state was flushed flushInterval atomic.Int64 // Time interval (processing time) after which to flush a state triedb *triedb.Database // The database handler for maintaining trie nodes. + verkledb *triedb.Database // The database handler for maintaining verkle trie nodes. statedb *state.CachingDB // State database to reuse between imports (contains state cache) txIndexer *txIndexer // Transaction indexer, might be nil if not enabled @@ -283,13 +284,14 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis if cacheConfig == nil { cacheConfig = defaultCacheConfig } + verkledb := triedb.NewDatabase(db, triedb.VerkleDefaults) triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(genesis.IsVerkle())) // Write the supplied genesis to the database if it has not been initialized // yet. The corresponding chain config will be returned, either from the // provided genesis or from the locally stored configuration if the genesis // has already been initialized. - chainConfig, genesisHash, compatErr, err := SetupGenesisBlockWithOverride(db, triedb, genesis, overrides) + chainConfig, genesisHash, compatErr, err := SetupGenesisBlockWithOverride(db, triedb, verkledb, genesis, overrides) if err != nil { return nil, err } @@ -306,6 +308,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis cacheConfig: cacheConfig, db: db, triedb: triedb, + verkledb: verkledb, triegc: prque.New[int64, common.Hash](nil), quit: make(chan struct{}), chainmu: syncx.NewClosableMutex(), @@ -323,7 +326,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis return nil, err } bc.flushInterval.Store(int64(cacheConfig.TrieTimeLimit)) - bc.statedb = state.NewDatabase(bc.triedb, nil) + bc.statedb = state.NewDatabase(bc.triedb, bc.verkledb, nil) bc.validator = NewBlockValidator(chainConfig, bc) bc.prefetcher = newStatePrefetcher(chainConfig, bc.hc) bc.processor = NewStateProcessor(chainConfig, bc.hc) @@ -464,7 +467,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis bc.snaps, _ = snapshot.New(snapconfig, bc.db, bc.triedb, head.Root) // Re-initialize the state database with snapshot - bc.statedb = state.NewDatabase(bc.triedb, bc.snaps) + bc.statedb = state.NewDatabase(bc.triedb, bc.verkledb, bc.snaps) } // Rewind the chain in case of an incompatible config upgrade. @@ -1168,6 +1171,9 @@ func (bc *BlockChain) Stop() { if err := bc.triedb.Close(); err != nil { log.Error("Failed to close trie database", "err", err) } + if err := bc.verkledb.Close(); err != nil { + log.Error("Failed to close the verkle trie database", "err", err) + } log.Info("Blockchain stopped") } diff --git a/core/blockchain_repair_test.go b/core/blockchain_repair_test.go index 3ff1d77fc8..57b9cf75af 100644 --- a/core/blockchain_repair_test.go +++ b/core/blockchain_repair_test.go @@ -1846,6 +1846,7 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s } // Pull the plug on the database, simulating a hard crash chain.triedb.Close() + chain.verkledb.Close() db.Close() chain.stopWithoutSaving() @@ -1969,6 +1970,7 @@ func testIssue23496(t *testing.T, scheme string) { // Pull the plug on the database, simulating a hard crash chain.triedb.Close() + chain.verkledb.Close() db.Close() chain.stopWithoutSaving() diff --git a/core/blockchain_sethead_test.go b/core/blockchain_sethead_test.go index e998b510df..5d6283139d 100644 --- a/core/blockchain_sethead_test.go +++ b/core/blockchain_sethead_test.go @@ -2034,6 +2034,7 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme } // Reopen the trie database without persisting in-memory dirty nodes. chain.triedb.Close() + chain.verkledb.Close() dbconfig := &triedb.Config{} if scheme == rawdb.PathScheme { dbconfig.PathDB = pathdb.Defaults @@ -2041,7 +2042,8 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme dbconfig.HashDB = hashdb.Defaults } chain.triedb = triedb.NewDatabase(chain.db, dbconfig) - chain.statedb = state.NewDatabase(chain.triedb, chain.snaps) + chain.verkledb = triedb.NewDatabase(chain.db, triedb.VerkleDefaults) + chain.statedb = state.NewDatabase(chain.triedb, chain.verkledb, chain.snaps) // Force run a freeze cycle type freezer interface { diff --git a/core/blockchain_snapshot_test.go b/core/blockchain_snapshot_test.go index 23effea15e..2dee521db2 100644 --- a/core/blockchain_snapshot_test.go +++ b/core/blockchain_snapshot_test.go @@ -255,6 +255,7 @@ func (snaptest *crashSnapshotTest) test(t *testing.T) { db.Close() chain.stopWithoutSaving() chain.triedb.Close() + chain.verkledb.Close() // Start a new blockchain back up and see where the repair leads us pdb, err := pebble.New(snaptest.datadir, 0, 0, "", false, true) @@ -410,6 +411,7 @@ func (snaptest *wipeCrashSnapshotTest) test(t *testing.T) { // Simulate the blockchain crash. tmp.triedb.Close() + tmp.verkledb.Close() tmp.stopWithoutSaving() newchain, err = NewBlockChain(snaptest.db, DefaultCacheConfigWithScheme(snaptest.scheme), snaptest.gspec, nil, snaptest.engine, vm.Config{}, nil) diff --git a/core/chain_makers.go b/core/chain_makers.go index a3825137c6..0c43e91a88 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -422,12 +422,15 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse return block, b.receipts } + verkledb := triedb.NewDatabase(db, triedb.VerkleDefaults) + defer verkledb.Close() + // Forcibly use hash-based state scheme for retaining all nodes in disk. triedb := triedb.NewDatabase(db, triedb.HashDefaults) defer triedb.Close() for i := 0; i < n; i++ { - statedb, err := state.New(parent.Root(), state.NewDatabase(triedb, nil)) + statedb, err := state.New(parent.Root(), state.NewDatabase(triedb, verkledb, nil)) if err != nil { panic(err) } @@ -468,9 +471,11 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse // then generate chain on top. func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, gen func(int, *BlockGen)) (ethdb.Database, []*types.Block, []types.Receipts) { db := rawdb.NewMemoryDatabase() + verkledb := triedb.NewDatabase(db, triedb.VerkleDefaults) + defer verkledb.Close() triedb := triedb.NewDatabase(db, triedb.HashDefaults) defer triedb.Close() - _, err := genesis.Commit(db, triedb) + _, err := genesis.Commit(db, triedb, verkledb) if err != nil { panic(err) } @@ -478,7 +483,7 @@ func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, return db, blocks, receipts } -func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, db ethdb.Database, trdb *triedb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts, []*verkle.VerkleProof, []verkle.StateDiff) { +func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, db ethdb.Database, trdb, vdb *triedb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts, []*verkle.VerkleProof, []verkle.StateDiff) { if config == nil { config = params.TestChainConfig } @@ -536,7 +541,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine return block, b.receipts } - sdb := state.NewDatabase(trdb, nil) + sdb := state.NewDatabase(trdb, vdb, nil) for i := 0; i < n; i++ { statedb, err := state.New(parent.Root(), sdb) @@ -580,13 +585,14 @@ func GenerateVerkleChainWithGenesis(genesis *Genesis, engine consensus.Engine, n saveVerkleTransitionStatusAtVerlkeGenesis(db) cacheConfig := DefaultCacheConfigWithScheme(rawdb.PathScheme) cacheConfig.SnapshotLimit = 0 - triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true)) + verkledb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true)) + triedb := triedb.NewDatabase(db, triedb.VerkleDefaults) defer triedb.Close() - genesisBlock, err := genesis.Commit(db, triedb) + genesisBlock, err := genesis.Commit(db, triedb, verkledb) if err != nil { panic(err) } - blocks, receipts, proofs, keyvals := GenerateVerkleChain(genesis.Config, genesisBlock, engine, db, triedb, n, gen) + blocks, receipts, proofs, keyvals := GenerateVerkleChain(genesis.Config, genesisBlock, engine, db, triedb, verkledb, n, gen) return genesisBlock.Hash(), db, blocks, receipts, proofs, keyvals } diff --git a/core/chain_makers_test.go b/core/chain_makers_test.go index d81a52e915..9ff1cc15e9 100644 --- a/core/chain_makers_test.go +++ b/core/chain_makers_test.go @@ -75,7 +75,7 @@ func TestGeneratePOSChain(t *testing.T) { Storage: storage, Code: common.Hex2Bytes("600154600354"), } - genesis := gspec.MustCommit(gendb, triedb.NewDatabase(gendb, triedb.HashDefaults)) + genesis := gspec.MustCommit(gendb, triedb.NewDatabase(gendb, triedb.HashDefaults), triedb.NewDatabase(gendb, triedb.VerkleDefaults)) engine := beacon.New(ethash.NewFaker()) genchain, genreceipts := GenerateChain(gspec.Config, genesis, engine, gendb, 4, func(i int, gen *BlockGen) { @@ -199,7 +199,7 @@ func ExampleGenerateChain() { Config: ¶ms.ChainConfig{HomesteadBlock: new(big.Int)}, Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(1000000)}}, } - genesis := gspec.MustCommit(genDb, triedb.NewDatabase(genDb, triedb.HashDefaults)) + genesis := gspec.MustCommit(genDb, triedb.NewDatabase(genDb, triedb.HashDefaults), triedb.NewDatabase(genDb, triedb.VerkleDefaults)) // This call generates a chain of 5 blocks. The function runs for // each block and adds different features to gen based on the diff --git a/core/genesis.go b/core/genesis.go index da01a420c4..09a4035751 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -39,7 +39,6 @@ import ( "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/triedb" - "github.com/ethereum/go-ethereum/triedb/pathdb" "github.com/holiman/uint256" ) @@ -129,16 +128,7 @@ 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) { - // 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 { - config = &triedb.Config{ - PathDB: pathdb.Defaults, - IsVerkle: true, - } - } + // Create an ephemeral in-memory database for computing hash, // all the derived states will be discarded to not pollute disk. emptyRoot := types.EmptyRootHash @@ -149,7 +139,7 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) { if isVerkle { saveVerkleTransitionStatusAtVerlkeGenesis(db) } - statedb, err := state.New(emptyRoot, state.NewDatabase(triedb.NewDatabase(db, config), nil)) + statedb, err := state.New(emptyRoot, state.NewDatabase(triedb.NewDatabase(db, nil), triedb.NewDatabase(db, triedb.VerkleDefaults), nil)) if err != nil { return common.Hash{}, err } @@ -168,12 +158,12 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) { // flushAlloc is very similar with hash, but the main difference is all the // generated states will be persisted into the given database. -func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, error) { +func flushAlloc(ga *types.GenesisAlloc, triedb, verkledb *triedb.Database) (common.Hash, error) { emptyRoot := types.EmptyRootHash if triedb.IsVerkle() { emptyRoot = types.EmptyVerkleHash } - statedb, err := state.New(emptyRoot, state.NewDatabase(triedb, nil)) + statedb, err := state.New(emptyRoot, state.NewDatabase(triedb, verkledb, nil)) if err != nil { return common.Hash{}, err } @@ -309,11 +299,11 @@ func saveVerkleTransitionStatus(db ethdb.Database, root common.Hash, ts *state.T // The stored chain configuration will be updated if it is compatible (i.e. does not // specify a fork block below the local head block). In case of a conflict, the // error is a *params.ConfigCompatError and the new, unwritten config is returned. -func SetupGenesisBlock(db ethdb.Database, triedb *triedb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { - return SetupGenesisBlockWithOverride(db, triedb, genesis, nil) +func SetupGenesisBlock(db ethdb.Database, triedb, verkledb *triedb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { + return SetupGenesisBlockWithOverride(db, triedb, verkledb, genesis, nil) } -func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, genesis *Genesis, overrides *ChainOverrides) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { +func SetupGenesisBlockWithOverride(db ethdb.Database, triedb, verkledb *triedb.Database, genesis *Genesis, overrides *ChainOverrides) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { // Copy the genesis, so we can operate on a copy. genesis = genesis.copy() // Sanitize the supplied genesis, ensuring it has the associated chain @@ -339,7 +329,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g return nil, common.Hash{}, nil, err } - block, err := genesis.Commit(db, triedb) + block, err := genesis.Commit(db, triedb, verkledb) if err != nil { return nil, common.Hash{}, nil, err } @@ -367,7 +357,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g if hash := genesis.ToBlock().Hash(); hash != ghash { return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash} } - block, err := genesis.Commit(db, triedb) + block, err := genesis.Commit(db, triedb, verkledb) if err != nil { return nil, common.Hash{}, nil, err } @@ -548,7 +538,7 @@ func (g *Genesis) toBlockWithRoot(root common.Hash) *types.Block { // Commit writes the block and state of a genesis specification to the database. // The block is committed as the canonical head block. -func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Block, error) { +func (g *Genesis) Commit(db ethdb.Database, triedb, verkledb *triedb.Database) (*types.Block, error) { if g.Number != 0 { return nil, errors.New("can't commit genesis block with number > 0") } @@ -563,7 +553,7 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo return nil, errors.New("can't start clique chain without signers") } // flush the data to disk and compute the state root - root, err := flushAlloc(&g.Alloc, triedb) + root, err := flushAlloc(&g.Alloc, triedb, verkledb) if err != nil { return nil, err } @@ -591,8 +581,8 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo // MustCommit writes the genesis block and state to db, panicking on error. // The block is committed as the canonical head block. -func (g *Genesis) MustCommit(db ethdb.Database, triedb *triedb.Database) *types.Block { - block, err := g.Commit(db, triedb) +func (g *Genesis) MustCommit(db ethdb.Database, triedb, verkledb *triedb.Database) *types.Block { + block, err := g.Commit(db, triedb, verkledb) if err != nil { panic(err) } diff --git a/core/genesis_test.go b/core/genesis_test.go index 837ec7cdd8..c5e7265493 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -64,14 +64,14 @@ func testSetupGenesis(t *testing.T, scheme string) { { name: "genesis without ChainConfig", fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { - return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), new(Genesis)) + return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), triedb.NewDatabase(db, triedb.VerkleDefaults), new(Genesis)) }, wantErr: errGenesisNoConfig, }, { name: "no block in DB, genesis == nil", fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { - return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), nil) + return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), triedb.NewDatabase(db, triedb.VerkleDefaults), nil) }, wantHash: params.MainnetGenesisHash, wantConfig: params.MainnetChainConfig, @@ -79,8 +79,8 @@ func testSetupGenesis(t *testing.T, scheme string) { { name: "mainnet block in DB, genesis == nil", fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { - DefaultGenesisBlock().MustCommit(db, triedb.NewDatabase(db, newDbConfig(scheme))) - return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), nil) + DefaultGenesisBlock().MustCommit(db, triedb.NewDatabase(db, newDbConfig(scheme)), triedb.NewDatabase(db, triedb.VerkleDefaults)) + return SetupGenesisBlock(db, triedb.NewDatabase(db, newDbConfig(scheme)), triedb.NewDatabase(db, triedb.VerkleDefaults), nil) }, wantHash: params.MainnetGenesisHash, wantConfig: params.MainnetChainConfig, @@ -88,9 +88,10 @@ func testSetupGenesis(t *testing.T, scheme string) { { name: "custom block in DB, genesis == nil", fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { + vdb := triedb.NewDatabase(db, triedb.VerkleDefaults) tdb := triedb.NewDatabase(db, newDbConfig(scheme)) - customg.Commit(db, tdb) - return SetupGenesisBlock(db, tdb, nil) + customg.Commit(db, tdb, vdb) + return SetupGenesisBlock(db, tdb, vdb, nil) }, wantHash: customghash, wantConfig: customg.Config, @@ -98,18 +99,20 @@ func testSetupGenesis(t *testing.T, scheme string) { { name: "custom block in DB, genesis == sepolia", fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { + vdb := triedb.NewDatabase(db, triedb.VerkleDefaults) tdb := triedb.NewDatabase(db, newDbConfig(scheme)) - customg.Commit(db, tdb) - return SetupGenesisBlock(db, tdb, DefaultSepoliaGenesisBlock()) + customg.Commit(db, tdb, vdb) + return SetupGenesisBlock(db, tdb, vdb, DefaultSepoliaGenesisBlock()) }, wantErr: &GenesisMismatchError{Stored: customghash, New: params.SepoliaGenesisHash}, }, { name: "custom block in DB, genesis == hoodi", fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { + vdb := triedb.NewDatabase(db, triedb.VerkleDefaults) tdb := triedb.NewDatabase(db, newDbConfig(scheme)) - customg.Commit(db, tdb) - return SetupGenesisBlock(db, tdb, DefaultHoodiGenesisBlock()) + customg.Commit(db, tdb, vdb) + return SetupGenesisBlock(db, tdb, vdb, DefaultHoodiGenesisBlock()) }, wantErr: &GenesisMismatchError{Stored: customghash, New: params.HoodiGenesisHash}, }, @@ -117,8 +120,9 @@ func testSetupGenesis(t *testing.T, scheme string) { name: "compatible config in DB", fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { tdb := triedb.NewDatabase(db, newDbConfig(scheme)) - oldcustomg.Commit(db, tdb) - return SetupGenesisBlock(db, tdb, &customg) + vdb := triedb.NewDatabase(db, triedb.VerkleDefaults) + oldcustomg.Commit(db, tdb, vdb) + return SetupGenesisBlock(db, tdb, vdb, &customg) }, wantHash: customghash, wantConfig: customg.Config, @@ -128,8 +132,9 @@ func testSetupGenesis(t *testing.T, scheme string) { fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { // Commit the 'old' genesis block with Homestead transition at #2. // Advance to block #4, past the homestead transition block of customg. + vdb := triedb.NewDatabase(db, triedb.VerkleDefaults) tdb := triedb.NewDatabase(db, newDbConfig(scheme)) - oldcustomg.Commit(db, tdb) + oldcustomg.Commit(db, tdb, vdb) bc, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(scheme), &oldcustomg, nil, ethash.NewFullFaker(), vm.Config{}, nil) defer bc.Stop() @@ -138,7 +143,7 @@ func testSetupGenesis(t *testing.T, scheme string) { bc.InsertChain(blocks) // This should return a compatibility error. - return SetupGenesisBlock(db, tdb, &customg) + return SetupGenesisBlock(db, tdb, vdb, &customg) }, wantHash: customghash, wantConfig: customg.Config, @@ -192,7 +197,7 @@ func TestGenesisHashes(t *testing.T) { } { // Test via MustCommit db := rawdb.NewMemoryDatabase() - if have := c.genesis.MustCommit(db, triedb.NewDatabase(db, triedb.HashDefaults)).Hash(); have != c.want { + if have := c.genesis.MustCommit(db, triedb.NewDatabase(db, triedb.HashDefaults), triedb.NewDatabase(db, triedb.VerkleDefaults)).Hash(); have != c.want { t.Errorf("case: %d a), want: %s, got: %s", i, c.want.Hex(), have.Hex()) } // Test via ToBlock @@ -210,7 +215,7 @@ func TestGenesisCommit(t *testing.T) { } db := rawdb.NewMemoryDatabase() - genesisBlock := genesis.MustCommit(db, triedb.NewDatabase(db, triedb.HashDefaults)) + genesisBlock := genesis.MustCommit(db, triedb.NewDatabase(db, triedb.HashDefaults), triedb.NewDatabase(db, triedb.VerkleDefaults)) if genesis.Difficulty != nil { t.Fatalf("assumption wrong") @@ -314,8 +319,9 @@ func TestVerkleGenesisCommit(t *testing.T) { db := rawdb.NewMemoryDatabase() saveVerkleTransitionStatusAtVerlkeGenesis(db) + verkledb := triedb.NewDatabase(db, triedb.VerkleDefaults) triedb := triedb.NewDatabase(db, triedb.VerkleDefaults) - block := genesis.MustCommit(db, triedb) + block := genesis.MustCommit(db, triedb, verkledb) if !bytes.Equal(block.Root().Bytes(), expected) { t.Fatalf("invalid genesis state root, expected %x, got %x", expected, block.Root()) } diff --git a/core/headerchain_test.go b/core/headerchain_test.go index b51fb8f226..7f850c1359 100644 --- a/core/headerchain_test.go +++ b/core/headerchain_test.go @@ -69,7 +69,7 @@ func TestHeaderInsertion(t *testing.T) { db = rawdb.NewMemoryDatabase() gspec = &Genesis{BaseFee: big.NewInt(params.InitialBaseFee), Config: params.AllEthashProtocolChanges} ) - gspec.Commit(db, triedb.NewDatabase(db, nil)) + gspec.Commit(db, triedb.NewDatabase(db, nil), triedb.NewDatabase(db, triedb.VerkleDefaults)) hc, err := NewHeaderChain(db, gspec.Config, ethash.NewFaker(), func() bool { return false }) if err != nil { t.Fatal(err) diff --git a/core/state/database.go b/core/state/database.go index 082dbd8257..f4cdcc1542 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -201,6 +201,7 @@ func (ts *TransitionState) Copy() *TransitionState { type CachingDB struct { disk ethdb.KeyValueStore triedb *triedb.Database + verkledb *triedb.Database snap *snapshot.Tree codeCache *lru.SizeConstrainedCache[common.Hash, []byte] codeSizeCache *lru.Cache[common.Hash, int] @@ -211,10 +212,11 @@ type CachingDB struct { } // NewDatabase creates a state database with the provided data sources. -func NewDatabase(triedb *triedb.Database, snap *snapshot.Tree) *CachingDB { +func NewDatabase(triedb, verkledb *triedb.Database, snap *snapshot.Tree) *CachingDB { return &CachingDB{ disk: triedb.Disk(), triedb: triedb, + verkledb: verkledb, snap: snap, codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize), codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize), @@ -226,7 +228,8 @@ func NewDatabase(triedb *triedb.Database, snap *snapshot.Tree) *CachingDB { // 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 { - return NewDatabase(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil), nil) + memdb := rawdb.NewMemoryDatabase() + return NewDatabase(triedb.NewDatabase(memdb, nil), triedb.NewDatabase(memdb, triedb.VerkleDefaults), nil) } // Reader returns a state reader associated with the specified state root. @@ -274,7 +277,7 @@ func (db *CachingDB) OpenTrie(root common.Hash) (Trie, error) { panic("transition isn't supported yet") } if ts.Transitioned() { - return trie.NewVerkleTrie(root, db.triedb, db.pointCache) + return trie.NewVerkleTrie(root, db.verkledb, db.pointCache) } tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb) if err != nil { diff --git a/core/state/state_test.go b/core/state/state_test.go index b443411f1b..2eeb2986a0 100644 --- a/core/state/state_test.go +++ b/core/state/state_test.go @@ -40,8 +40,9 @@ func newStateEnv() *stateEnv { func TestDump(t *testing.T) { db := rawdb.NewMemoryDatabase() + verkledb := triedb.NewDatabase(db, triedb.VerkleDefaults) triedb := triedb.NewDatabase(db, &triedb.Config{Preimages: true}) - tdb := NewDatabase(triedb, nil) + tdb := NewDatabase(triedb, verkledb, nil) sdb, _ := New(types.EmptyRootHash, tdb) s := &stateEnv{state: sdb} @@ -98,8 +99,9 @@ func TestDump(t *testing.T) { func TestIterativeDump(t *testing.T) { db := rawdb.NewMemoryDatabase() + verkledb := triedb.NewDatabase(db, triedb.VerkleDefaults) triedb := triedb.NewDatabase(db, &triedb.Config{Preimages: true}) - tdb := NewDatabase(triedb, nil) + tdb := NewDatabase(triedb, verkledb, nil) sdb, _ := New(types.EmptyRootHash, tdb) s := &stateEnv{state: sdb} diff --git a/core/state/statedb.go b/core/state/statedb.go index 6d1ef45a7b..07f972af73 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -788,7 +788,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { start = time.Now() workers errgroup.Group ) - if s.db.TrieDB().IsVerkle() { + if s.GetTrie().IsVerkle() { // Whilst MPT storage tries are independent, Verkle has one single trie // for all the accounts and all the storage slots merged together. The // former can thus be simply parallelized, but updating the latter will @@ -802,7 +802,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { } obj := s.stateObjects[addr] // closure for the task runner below workers.Go(func() error { - if s.db.TrieDB().IsVerkle() { + if s.GetTrie().IsVerkle() { obj.updateTrie() } else { obj.updateRoot() @@ -819,7 +819,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { // If witness building is enabled, gather all the read-only accesses. // Skip witness collection in Verkle mode, they will be gathered // together at the end. - if s.witness != nil && !s.db.TrieDB().IsVerkle() { + if s.witness != nil && !s.GetTrie().IsVerkle() { // Pull in anything that has been accessed before destruction for _, obj := range s.stateObjectsDestruct { // Skip any objects that haven't touched their storage diff --git a/core/state/statedb_fuzz_test.go b/core/state/statedb_fuzz_test.go index 7dada63d45..f63673691d 100644 --- a/core/state/statedb_fuzz_test.go +++ b/core/state/statedb_fuzz_test.go @@ -189,6 +189,7 @@ func (test *stateTest) run() bool { storageOrigin = append(storageOrigin, maps.Clone(update.storagesOrigin)) } disk = rawdb.NewMemoryDatabase() + vdb = triedb.NewDatabase(disk, triedb.VerkleDefaults) tdb = triedb.NewDatabase(disk, &triedb.Config{PathDB: pathdb.Defaults}) byzantium = rand.Intn(2) == 0 ) @@ -209,7 +210,7 @@ func (test *stateTest) run() bool { if i != 0 { root = roots[len(roots)-1] } - state, err := New(root, NewDatabase(tdb, snaps)) + state, err := New(root, NewDatabase(tdb, vdb, snaps)) if err != nil { panic(err) } diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index e740c64faa..751cd180a0 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -52,7 +52,8 @@ func TestUpdateLeaks(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() tdb = triedb.NewDatabase(db, nil) - sdb = NewDatabase(tdb, nil) + vdb = triedb.NewDatabase(db, triedb.VerkleDefaults) + sdb = NewDatabase(tdb, vdb, nil) ) state, _ := New(types.EmptyRootHash, sdb) @@ -89,9 +90,11 @@ func TestIntermediateLeaks(t *testing.T) { transDb := rawdb.NewMemoryDatabase() finalDb := rawdb.NewMemoryDatabase() transNdb := triedb.NewDatabase(transDb, nil) + transVdb := triedb.NewDatabase(transDb, triedb.VerkleDefaults) finalNdb := triedb.NewDatabase(finalDb, nil) - transState, _ := New(types.EmptyRootHash, NewDatabase(transNdb, nil)) - finalState, _ := New(types.EmptyRootHash, NewDatabase(finalNdb, nil)) + finalVdb := triedb.NewDatabase(finalDb, triedb.VerkleDefaults) + transState, _ := New(types.EmptyRootHash, NewDatabase(transNdb, transVdb, nil)) + finalState, _ := New(types.EmptyRootHash, NewDatabase(finalNdb, finalVdb, nil)) modify := func(state *StateDB, addr common.Address, i, tweak byte) { state.SetBalance(addr, uint256.NewInt(uint64(11*i)+uint64(tweak)), tracing.BalanceChangeUnspecified) @@ -987,7 +990,8 @@ func testMissingTrieNodes(t *testing.T, scheme string) { CleanCacheSize: 0, }}) // disable caching } - db := NewDatabase(tdb, nil) + vdb := triedb.NewDatabase(memDb, triedb.VerkleDefaults) + db := NewDatabase(tdb, vdb, nil) var root common.Hash state, _ := New(types.EmptyRootHash, db) @@ -1204,7 +1208,8 @@ func TestFlushOrderDataLoss(t *testing.T) { var ( memdb = rawdb.NewMemoryDatabase() tdb = triedb.NewDatabase(memdb, triedb.HashDefaults) - statedb = NewDatabase(tdb, nil) + vdb = triedb.NewDatabase(memdb, triedb.VerkleDefaults) + statedb = NewDatabase(tdb, vdb, nil) state, _ = New(types.EmptyRootHash, statedb) ) for a := byte(0); a < 10; a++ { @@ -1225,7 +1230,7 @@ func TestFlushOrderDataLoss(t *testing.T) { t.Fatalf("failed to commit state trie: %v", err) } // Reopen the state trie from flushed disk and verify it - state, err = New(root, NewDatabase(triedb.NewDatabase(memdb, triedb.HashDefaults), nil)) + state, err = New(root, NewDatabase(triedb.NewDatabase(memdb, triedb.HashDefaults), triedb.NewDatabase(memdb, triedb.VerkleDefaults), nil)) if err != nil { t.Fatalf("failed to reopen state trie: %v", err) } @@ -1275,8 +1280,9 @@ func TestDeleteStorage(t *testing.T) { var ( disk = rawdb.NewMemoryDatabase() tdb = triedb.NewDatabase(disk, nil) + vdb = triedb.NewDatabase(disk, triedb.VerkleDefaults) snaps, _ = snapshot.New(snapshot.Config{CacheSize: 10}, disk, tdb, types.EmptyRootHash) - db = NewDatabase(tdb, snaps) + db = NewDatabase(tdb, vdb, snaps) state, _ = New(types.EmptyRootHash, db) addr = common.HexToAddress("0x1") ) @@ -1290,8 +1296,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, snaps)) - slowState, _ := New(root, NewDatabase(tdb, nil)) + fastState, _ := New(root, NewDatabase(tdb, vdb, snaps)) + slowState, _ := New(root, NewDatabase(tdb, vdb, nil)) obj := fastState.getOrNewStateObject(addr) storageRoot := obj.data.Root @@ -1329,7 +1335,8 @@ func TestStorageDirtiness(t *testing.T) { var ( disk = rawdb.NewMemoryDatabase() tdb = triedb.NewDatabase(disk, nil) - db = NewDatabase(tdb, nil) + vdb = triedb.NewDatabase(disk, triedb.VerkleDefaults) + db = NewDatabase(tdb, vdb, nil) state, _ = New(types.EmptyRootHash, db) addr = common.HexToAddress("0x1") checkDirty = func(key common.Hash, value common.Hash, dirty bool) { diff --git a/core/state/sync_test.go b/core/state/sync_test.go index 5c8b5a90f7..317d3eb22f 100644 --- a/core/state/sync_test.go +++ b/core/state/sync_test.go @@ -52,7 +52,8 @@ func makeTestState(scheme string) (ethdb.Database, Database, *triedb.Database, c } db := rawdb.NewMemoryDatabase() nodeDb := triedb.NewDatabase(db, config) - sdb := NewDatabase(nodeDb, nil) + verkleNodedb := triedb.NewDatabase(db, triedb.VerkleDefaults) + sdb := NewDatabase(nodeDb, verkleNodedb, nil) state, _ := New(types.EmptyRootHash, sdb) // Fill it with some arbitrary data @@ -93,7 +94,7 @@ func checkStateAccounts(t *testing.T, db ethdb.Database, scheme string, root com config.PathDB = pathdb.Defaults } // Check root availability and state contents - state, err := New(root, NewDatabase(triedb.NewDatabase(db, &config), nil)) + state, err := New(root, NewDatabase(triedb.NewDatabase(db, &config), triedb.NewDatabase(db, triedb.VerkleDefaults), nil)) if err != nil { t.Fatalf("failed to create state trie at %x: %v", root, err) } @@ -119,7 +120,7 @@ func checkStateConsistency(db ethdb.Database, scheme string, root common.Hash) e if scheme == rawdb.PathScheme { config.PathDB = pathdb.Defaults } - state, err := New(root, NewDatabase(triedb.NewDatabase(db, config), nil)) + state, err := New(root, NewDatabase(triedb.NewDatabase(db, config), triedb.NewDatabase(db, triedb.VerkleDefaults), nil)) if err != nil { return err } diff --git a/core/state/trie_prefetcher_test.go b/core/state/trie_prefetcher_test.go index 4d1b627c4d..65a9fb752f 100644 --- a/core/state/trie_prefetcher_test.go +++ b/core/state/trie_prefetcher_test.go @@ -68,8 +68,9 @@ func TestUseAfterTerminate(t *testing.T) { func TestVerklePrefetcher(t *testing.T) { disk := rawdb.NewMemoryDatabase() - db := triedb.NewDatabase(disk, triedb.VerkleDefaults) - sdb := NewDatabase(db, nil) + tdb := triedb.NewDatabase(disk, nil) + vdb := triedb.NewDatabase(disk, triedb.VerkleDefaults) + sdb := NewDatabase(tdb, vdb, nil) state, err := New(types.EmptyRootHash, sdb) if err != nil { diff --git a/core/stateless.go b/core/stateless.go index d21a62b4a5..e0dcff9904 100644 --- a/core/stateless.go +++ b/core/stateless.go @@ -51,7 +51,7 @@ func ExecuteStateless(config *params.ChainConfig, vmconfig vm.Config, block *typ } // Create and populate the state database to serve as the stateless backend memdb := witness.MakeHashDB() - db, err := state.New(witness.Root(), state.NewDatabase(triedb.NewDatabase(memdb, triedb.HashDefaults), nil)) + db, err := state.New(witness.Root(), state.NewDatabase(triedb.NewDatabase(memdb, triedb.HashDefaults), triedb.NewDatabase(memdb, triedb.VerkleDefaults), nil)) if err != nil { return common.Hash{}, common.Hash{}, err } diff --git a/core/verkle_witness_test.go b/core/verkle_witness_test.go index 353c431015..5770c7c432 100644 --- a/core/verkle_witness_test.go +++ b/core/verkle_witness_test.go @@ -259,8 +259,9 @@ func TestProcessParentBlockHash(t *testing.T) { db := rawdb.NewMemoryDatabase() cacheConfig := DefaultCacheConfigWithScheme(rawdb.PathScheme) cacheConfig.SnapshotLimit = 0 + verkledb := triedb.NewDatabase(db, triedb.VerkleDefaults) triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true)) - statedb, _ := state.New(types.EmptyVerkleHash, state.NewDatabase(triedb, nil)) + statedb, _ := state.New(types.EmptyVerkleHash, state.NewDatabase(triedb, verkledb, nil)) checkBlockHashes(statedb, true) }) } diff --git a/eth/api_debug_test.go b/eth/api_debug_test.go index 02b85f69fd..2c1e4167b7 100644 --- a/eth/api_debug_test.go +++ b/eth/api_debug_test.go @@ -65,7 +65,7 @@ func TestAccountRange(t *testing.T) { var ( mdb = rawdb.NewMemoryDatabase() - statedb = state.NewDatabase(triedb.NewDatabase(mdb, &triedb.Config{Preimages: true}), nil) + statedb = state.NewDatabase(triedb.NewDatabase(mdb, &triedb.Config{Preimages: true}), triedb.NewDatabase(mdb, triedb.VerkleDefaults), nil) sdb, _ = state.New(types.EmptyRootHash, statedb) addrs = [AccountRangeMaxResults * 2]common.Address{} m = map[common.Address]bool{} @@ -164,7 +164,8 @@ func TestStorageRangeAt(t *testing.T) { var ( mdb = rawdb.NewMemoryDatabase() tdb = triedb.NewDatabase(mdb, &triedb.Config{Preimages: true}) - db = state.NewDatabase(tdb, nil) + vdb = triedb.NewDatabase(mdb, triedb.VerkleDefaults) + db = state.NewDatabase(tdb, vdb, nil) sdb, _ = state.New(types.EmptyRootHash, db) addr = common.Address{0x01} keys = []common.Hash{ // hashes of Keys of storage diff --git a/eth/downloader/testchain_test.go b/eth/downloader/testchain_test.go index 8fa2e83413..157f3c86f5 100644 --- a/eth/downloader/testchain_test.go +++ b/eth/downloader/testchain_test.go @@ -44,7 +44,7 @@ var ( Alloc: types.GenesisAlloc{testAddress: {Balance: big.NewInt(1000000000000000)}}, BaseFee: big.NewInt(params.InitialBaseFee), } - testGenesis = testGspec.MustCommit(testDB, triedb.NewDatabase(testDB, triedb.HashDefaults)) + testGenesis = testGspec.MustCommit(testDB, triedb.NewDatabase(testDB, triedb.HashDefaults), triedb.NewDatabase(testDB, triedb.VerkleDefaults)) ) // The common prefix of all test chains: diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go index 4026c03e89..c12ae2dec5 100644 --- a/eth/filters/filter_test.go +++ b/eth/filters/filter_test.go @@ -99,7 +99,7 @@ func benchmarkFilters(b *testing.B, history uint64, noHistory bool) { // The test txs are not properly signed, can't simply create a chain // and then import blocks. TODO(rjl493456442) try to get rid of the // manual database writes. - gspec.MustCommit(db, triedb.NewDatabase(db, triedb.HashDefaults)) + gspec.MustCommit(db, triedb.NewDatabase(db, triedb.HashDefaults), triedb.NewDatabase(db, triedb.VerkleDefaults)) for i, block := range chain { rawdb.WriteBlock(db, block) @@ -209,7 +209,7 @@ func testFilters(t *testing.T, history uint64, noHistory bool) { // Hack: GenerateChainWithGenesis creates a new db. // Commit the genesis manually and use GenerateChain. - _, err = gspec.Commit(db, triedb.NewDatabase(db, nil)) + _, err = gspec.Commit(db, triedb.NewDatabase(db, nil), triedb.NewDatabase(db, triedb.VerkleDefaults)) if err != nil { t.Fatal(err) } @@ -429,7 +429,7 @@ func TestRangeLogs(t *testing.T) { BaseFee: big.NewInt(params.InitialBaseFee), } ) - _, err := gspec.Commit(db, triedb.NewDatabase(db, nil)) + _, err := gspec.Commit(db, triedb.NewDatabase(db, nil), triedb.NewDatabase(db, triedb.VerkleDefaults)) if err != nil { t.Fatal(err) } diff --git a/eth/state_accessor.go b/eth/state_accessor.go index 99ed28d96a..cd2390d46d 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -68,8 +68,9 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u // the internal junks created by tracing will be persisted into the disk. // TODO(rjl493456442), clean cache is disabled to prevent memory leak, // please re-enable it for better performance. + vdb := triedb.NewDatabase(eth.chainDb, triedb.VerkleDefaults) tdb := triedb.NewDatabase(eth.chainDb, triedb.HashDefaults) - database = state.NewDatabase(tdb, nil) + database = state.NewDatabase(tdb, vdb, nil) if statedb, err = state.New(block.Root(), database); err == nil { log.Info("Found disk backend for state trie", "root", block.Root(), "number", block.Number()) return statedb, noopReleaser, nil @@ -86,8 +87,9 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u // the internal junks created by tracing will be persisted into the disk. // TODO(rjl493456442), clean cache is disabled to prevent memory leak, // please re-enable it for better performance. + vdb := triedb.NewDatabase(eth.chainDb, triedb.VerkleDefaults) tdb = triedb.NewDatabase(eth.chainDb, triedb.HashDefaults) - database = state.NewDatabase(tdb, nil) + database = state.NewDatabase(tdb, vdb, nil) // If we didn't check the live database, do check state over ephemeral database, // otherwise we would rewind past a persisted block (specific corner case is diff --git a/internal/ethapi/override/override_test.go b/internal/ethapi/override/override_test.go index 02a17c1331..df70e276db 100644 --- a/internal/ethapi/override/override_test.go +++ b/internal/ethapi/override/override_test.go @@ -36,7 +36,8 @@ func (p *precompileContract) RequiredGas(input []byte) uint64 { return 0 } func (p *precompileContract) Run(input []byte) ([]byte, error) { return nil, nil } func TestStateOverrideMovePrecompile(t *testing.T) { - db := state.NewDatabase(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil), nil) + memdb := rawdb.NewMemoryDatabase() + db := state.NewDatabase(triedb.NewDatabase(memdb, nil), triedb.NewDatabase(memdb, triedb.VerkleDefaults), nil) statedb, err := state.New(types.EmptyRootHash, db) if err != nil { t.Fatalf("failed to create statedb: %v", err) diff --git a/miner/miner_test.go b/miner/miner_test.go index 04d84e2e1d..45e6d2b5e7 100644 --- a/miner/miner_test.go +++ b/miner/miner_test.go @@ -143,9 +143,10 @@ func createMiner(t *testing.T) *Miner { } // Create chainConfig chainDB := rawdb.NewMemoryDatabase() + verkledb := triedb.NewDatabase(chainDB, triedb.VerkleDefaults) triedb := triedb.NewDatabase(chainDB, nil) genesis := minerTestGenesisBlock(15, 11_500_000, common.HexToAddress("12345")) - chainConfig, _, _, err := core.SetupGenesisBlock(chainDB, triedb, genesis) + chainConfig, _, _, err := core.SetupGenesisBlock(chainDB, triedb, verkledb, genesis) if err != nil { t.Fatalf("can't create new chain config: %v", err) } diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 77bf945e40..c860f69f5e 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -135,8 +135,9 @@ func (t *BlockTest) Run(snapshotter bool, scheme string, witness bool, tracer *t if gspec.Config.TerminalTotalDifficulty == nil { gspec.Config.TerminalTotalDifficulty = big.NewInt(stdmath.MaxInt64) } + verkledb := triedb.NewDatabase(db, triedb.VerkleDefaults) triedb := triedb.NewDatabase(db, tconf) - gblock, err := gspec.Commit(db, triedb) + gblock, err := gspec.Commit(db, triedb, verkledb) if err != nil { return err } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index a22e470ad8..ad1255289b 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -496,6 +496,7 @@ func vmTestBlockHash(n uint64) common.Hash { type StateTestState struct { StateDB *state.StateDB TrieDB *triedb.Database + VerkleDB *triedb.Database Snapshots *snapshot.Tree } @@ -507,8 +508,9 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bo } else { tconf.PathDB = pathdb.Defaults } + verkledb := triedb.NewDatabase(db, triedb.VerkleDefaults) triedb := triedb.NewDatabase(db, tconf) - sdb := state.NewDatabase(triedb, nil) + sdb := state.NewDatabase(triedb, verkledb, nil) statedb, _ := state.New(types.EmptyRootHash, sdb) for addr, a := range accounts { statedb.SetCode(addr, a.Code) @@ -532,9 +534,9 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bo } snaps, _ = snapshot.New(snapconfig, db, triedb, root) } - sdb = state.NewDatabase(triedb, snaps) + sdb = state.NewDatabase(triedb, verkledb, snaps) statedb, _ = state.New(root, sdb) - return StateTestState{statedb, triedb, snaps} + return StateTestState{statedb, triedb, verkledb, snaps} } // Close should be called when the state is no longer needed, ie. after running the test.