diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index 462fab8b4e..a4c96ff6d3 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -21,6 +21,7 @@ import ( "encoding/json" "fmt" "io" + "math/big" "os" goruntime "runtime" "runtime/pprof" @@ -81,12 +82,13 @@ func runCmd(ctx *cli.Context) error { } var ( - tracer *tracing.Hooks - debugLogger *logger.StructLogger - statedb *state.StateDB - chainConfig *params.ChainConfig - sender = common.StringToAddress("sender") - receiver = common.StringToAddress("receiver") + tracer *tracing.Hooks + debugLogger *logger.StructLogger + statedb *state.StateDB + chainConfig *params.ChainConfig + sender = common.StringToAddress("sender") + receiver = common.StringToAddress("receiver") + genesisConfig *core.Genesis ) if ctx.Bool(MachineFlag.Name) { tracer = logger.NewJSONLogger(logconfig, os.Stdout) @@ -99,6 +101,7 @@ func runCmd(ctx *cli.Context) error { if ctx.String(GenesisFlag.Name) != "" { gen := readGenesis(ctx.String(GenesisFlag.Name)) + genesisConfig = gen db := rawdb.NewMemoryDatabase() genesis := gen.ToBlock(db) statedb, _ = state.New(genesis.Root(), state.NewDatabase(db)) @@ -106,6 +109,7 @@ func runCmd(ctx *cli.Context) error { } else { db := rawdb.NewMemoryDatabase() statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(db)) + genesisConfig = new(core.Genesis) } if ctx.String(SenderFlag.Name) != "" { sender = common.HexToAddress(ctx.String(SenderFlag.Name)) @@ -156,12 +160,19 @@ func runCmd(ctx *cli.Context) error { } initialGas := ctx.Uint64(GasFlag.Name) + if genesisConfig.GasLimit != 0 { + initialGas = genesisConfig.GasLimit + } runtimeConfig := runtime.Config{ - Origin: sender, - State: statedb, - GasLimit: initialGas, - GasPrice: flags.GlobalBig(ctx, PriceFlag.Name), - Value: flags.GlobalBig(ctx, ValueFlag.Name), + Origin: sender, + State: statedb, + GasLimit: initialGas, + GasPrice: flags.GlobalBig(ctx, PriceFlag.Name), + Value: flags.GlobalBig(ctx, ValueFlag.Name), + Difficulty: genesisConfig.Difficulty, + Time: genesisConfig.Timestamp, + Coinbase: genesisConfig.Coinbase, + BlockNumber: new(big.Int).SetUint64(genesisConfig.Number), EVMConfig: vm.Config{ Tracer: tracer, }, @@ -197,7 +208,7 @@ func runCmd(ctx *cli.Context) error { execTime := time.Since(tstart) if ctx.Bool(DumpFlag.Name) { - statedb.IntermediateRoot(true) + statedb.Commit(genesisConfig.Number, true) fmt.Println(string(statedb.Dump(nil))) } diff --git a/core/blockchain.go b/core/blockchain.go index ce80ad56c0..afbdff53b6 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1231,7 +1231,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. log.Crit("Failed to write block into disk", "err", err) } // Commit all cached state changes into underlying memory database. - root, err := state.Commit(bc.chainConfig.IsEIP158(block.Number())) + root, err := state.Commit(block.NumberU64(), bc.chainConfig.IsEIP158(block.Number())) if err != nil { return NonStatTy, err } diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 8768281f93..6e814aa8cc 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -167,7 +167,7 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error { blockchain.chainmu.MustLock() rawdb.WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash()))) rawdb.WriteBlock(blockchain.db, block) - statedb.Commit(true) + statedb.Commit(block.NumberU64(), true) blockchain.chainmu.Unlock() } return nil diff --git a/core/chain_makers.go b/core/chain_makers.go index 07baa74176..2d8085c4bd 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -239,7 +239,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse // Finalize and seal the block block, _ := b.engine.Finalize(chainReader, b.header, statedb, statedb.Copy(), b.txs, b.uncles, b.receipts) // Write state changes to db - root, err := statedb.Commit(config.IsEIP158(b.header.Number)) + root, err := statedb.Commit(b.header.Number.Uint64(), config.IsEIP158(b.header.Number)) if err != nil { panic(fmt.Sprintf("state write error: %v", err)) } diff --git a/core/genesis.go b/core/genesis.go index c8531e7398..f2ec9865ea 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -258,7 +258,7 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block { } } - statedb.Commit(false) + statedb.Commit(0, false) statedb.Database().TrieDB().Commit(root, true) return types.NewBlock(head, nil, nil, trie.NewStackTrie(nil)) diff --git a/core/state/dump.go b/core/state/dump.go index d01888518b..edfc17fe89 100644 --- a/core/state/dump.go +++ b/core/state/dump.go @@ -168,11 +168,11 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey [] } obj := newObject(s, addr, data) if !conf.SkipCode { - account.Code = obj.Code(s.db) + account.Code = obj.Code() } if !conf.SkipStorage { account.Storage = make(map[common.Hash]string) - tr, err := obj.getTrie(s.db) + tr, err := obj.getTrie() if err != nil { log.Error("Failed to load storage trie", "err", err) continue diff --git a/core/state/state_object.go b/core/state/state_object.go index 99a0cb555b..b05ab3176a 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -138,9 +138,9 @@ func (s *stateObject) touch() { // getTrie returns the associated storage trie. The trie will be opened // if it's not loaded previously. An error will be returned if trie can't // be loaded. -func (s *stateObject) getTrie(db Database) (Trie, error) { +func (s *stateObject) getTrie() (Trie, error) { if s.trie == nil { - tr, err := db.OpenStorageTrie(s.db.originalRoot, s.addrHash, s.data.Root) + tr, err := s.db.db.OpenStorageTrie(s.db.originalRoot, s.addrHash, s.data.Root) if err != nil { return nil, err } @@ -150,17 +150,17 @@ func (s *stateObject) getTrie(db Database) (Trie, error) { } // GetState retrieves a value from the account storage trie. -func (s *stateObject) GetState(db Database, key common.Hash) common.Hash { +func (s *stateObject) GetState(key common.Hash) common.Hash { // If we have a dirty value for this state entry, return it value, dirty := s.dirtyStorage[key] if dirty { return value } // Otherwise return the entry's original value - return s.GetCommittedState(db, key) + return s.GetCommittedState(key) } -func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Hash { +func (s *stateObject) GetCommittedState(key common.Hash) common.Hash { // If we have a pending write or clean cached, return that if value, pending := s.pendingStorage[key]; pending { return value @@ -180,7 +180,7 @@ func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Has // Track the amount of time wasted on reading the storage trie start := time.Now() // Otherwise load the value from the database - tr, err := s.getTrie(db) + tr, err := s.getTrie() if err != nil { s.db.setError(err) return common.Hash{} @@ -204,10 +204,10 @@ func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Has } // SetState updates a value in account storage. -func (s *stateObject) SetState(db Database, key, value common.Hash) common.Hash { +func (s *stateObject) SetState(key, value common.Hash) common.Hash { // If the new value is the same as old, don't set. Otherwise, track only the // dirty changes, supporting reverting all of it back to no change. - prev := s.GetState(db, key) + prev := s.GetState(key) if prev == value { return prev } @@ -239,7 +239,7 @@ func (s *stateObject) finalise() { // updateTrie writes cached storage modifications into the object's storage trie. // It will return nil if the trie has not been loaded and no changes have been // made. An error will be returned if the trie can't be loaded/updated correctly. -func (s *stateObject) updateTrie(db Database) (Trie, error) { +func (s *stateObject) updateTrie() (Trie, error) { // Make sure all dirty slots are finalized into the pending storage area s.finalise() if len(s.pendingStorage) == 0 { @@ -247,7 +247,7 @@ func (s *stateObject) updateTrie(db Database) (Trie, error) { } // Track the amount of time wasted on updating the storage trie defer func(start time.Time) { s.db.StorageUpdates += time.Since(start) }(time.Now()) - tr, err := s.getTrie(db) + tr, err := s.getTrie() if err != nil { s.db.setError(err) return nil, err @@ -284,8 +284,8 @@ func (s *stateObject) updateTrie(db Database) (Trie, error) { // UpdateRoot sets the trie root to the current root hash of. An error // will be returned if trie root hash is not computed correctly. -func (s *stateObject) updateRoot(db Database) { - tr, err := s.updateTrie(db) +func (s *stateObject) updateRoot() { + tr, err := s.updateTrie() if err != nil { return } @@ -300,9 +300,9 @@ func (s *stateObject) updateRoot(db Database) { // CommitTrie the storage trie of the object to dwb. // This updates the trie root. -func (s *stateObject) commitTrie(db Database) (*trie.NodeSet, error) { +func (s *stateObject) commitTrie() (*trie.NodeSet, error) { // If nothing changed, don't bother with hashing anything - tr, err := s.updateTrie(db) + tr, err := s.updateTrie() if err != nil { return nil, err } @@ -372,14 +372,14 @@ func (s *stateObject) Address() common.Address { } // Code returns the contract code associated with this object, if any. -func (s *stateObject) Code(db Database) []byte { +func (s *stateObject) Code() []byte { if s.code != nil { return s.code } if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) { return nil } - code, err := db.ContractCode(s.addrHash, common.BytesToHash(s.CodeHash())) + code, err := s.db.db.ContractCode(s.addrHash, common.BytesToHash(s.CodeHash())) if err != nil { s.db.setError(fmt.Errorf("can't load code hash %x: %v", s.CodeHash(), err)) } @@ -390,14 +390,14 @@ func (s *stateObject) Code(db Database) []byte { // CodeSize returns the size of the contract code associated with this object, // or zero if none. This method is an almost mirror of Code, but uses a cache // inside the database to avoid loading codes seen recently. -func (s *stateObject) CodeSize(db Database) int { +func (s *stateObject) CodeSize() int { if s.code != nil { return len(s.code) } if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) { return 0 } - size, err := db.ContractCodeSize(s.addrHash, common.BytesToHash(s.CodeHash())) + size, err := s.db.db.ContractCodeSize(s.addrHash, common.BytesToHash(s.CodeHash())) if err != nil { s.db.setError(fmt.Errorf("can't load code size %x: %v", s.CodeHash(), err)) } diff --git a/core/state/state_test.go b/core/state/state_test.go index 7dcd1447a5..04846397d6 100644 --- a/core/state/state_test.go +++ b/core/state/state_test.go @@ -57,7 +57,7 @@ func TestDump(t *testing.T) { // write some of them to the trie s.state.updateStateObject(obj1) s.state.updateStateObject(obj2) - s.state.Commit(false) + s.state.Commit(0, false) // check that DumpToCollector contains the state objects that are in trie got := string(s.state.Dump(nil)) @@ -111,7 +111,7 @@ func TestIterativeDump(t *testing.T) { // write some of them to the trie s.state.updateStateObject(obj1) s.state.updateStateObject(obj2) - s.state.Commit(false) + s.state.Commit(0, false) b := &bytes.Buffer{} s.state.IterativeDump(nil, json.NewEncoder(b)) @@ -136,7 +136,7 @@ func TestNull(t *testing.T) { var value common.Hash s.state.SetState(address, common.Hash{}, value) - s.state.Commit(false) + s.state.Commit(0, false) if value := s.state.GetState(address, common.Hash{}); value != (common.Hash{}) { t.Errorf("expected empty current value, got %x", value) @@ -209,7 +209,7 @@ func TestSnapshot2(t *testing.T) { so0.deleted = false state.setStateObject(so0) - root, _ := state.Commit(false) + root, _ := state.Commit(0, false) state.Reset(root) // and one with deleted == true @@ -231,8 +231,8 @@ func TestSnapshot2(t *testing.T) { so0Restored := state.getStateObject(stateobjaddr0) // Update lazily-loaded values before comparing. - so0Restored.GetState(state.db, storageaddr) - so0Restored.Code(state.db) + so0Restored.GetState(storageaddr) + so0Restored.Code() // non-deleted is equal (restored) compareStateObjects(so0Restored, so0, t) diff --git a/core/state/statedb.go b/core/state/statedb.go index e0854edde9..a0a77d1351 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -283,7 +283,7 @@ func (s *StateDB) TxIndex() int { func (s *StateDB) GetCode(addr common.Address) []byte { stateObject := s.getStateObject(addr) if stateObject != nil { - return stateObject.Code(s.db) + return stateObject.Code() } return nil } @@ -291,7 +291,7 @@ func (s *StateDB) GetCode(addr common.Address) []byte { func (s *StateDB) GetCodeSize(addr common.Address) int { stateObject := s.getStateObject(addr) if stateObject != nil { - return stateObject.CodeSize(s.db) + return stateObject.CodeSize() } return 0 } @@ -334,7 +334,7 @@ func (s *StateDB) GetAccountInfo(addr common.Address) *AccountInfo { func (s *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash { stateObject := s.getStateObject(addr) if stateObject != nil { - return stateObject.GetState(s.db, hash) + return stateObject.GetState(hash) } return common.Hash{} } @@ -343,7 +343,7 @@ func (s *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash { func (s *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash { stateObject := s.getStateObject(addr) if stateObject != nil { - return stateObject.GetCommittedState(s.db, hash) + return stateObject.GetCommittedState(hash) } return common.Hash{} } @@ -362,10 +362,10 @@ func (s *StateDB) StorageTrie(addr common.Address) (Trie, error) { return nil, nil } cpy := stateObject.deepCopy(s) - if _, err := cpy.updateTrie(s.db); err != nil { + if _, err := cpy.updateTrie(); err != nil { return nil, err } - return cpy.getTrie(s.db) + return cpy.getTrie() } func (s *StateDB) HasSelfDestructed(addr common.Address) bool { @@ -426,7 +426,7 @@ func (s *StateDB) SetCode(addr common.Address, code []byte) []byte { func (s *StateDB) SetState(addr common.Address, key, value common.Hash) common.Hash { if stateObject := s.GetOrNewStateObject(addr); stateObject != nil { - return stateObject.SetState(s.db, key, value) + return stateObject.SetState(key, value) } return common.Hash{} } @@ -450,7 +450,7 @@ func (s *StateDB) SetStorage(addr common.Address, storage map[common.Hash]common } newObj, _ := s.createObject(addr) for k, v := range storage { - newObj.SetState(s.db, k, v) + newObj.SetState(k, v) } // Inherit the metadata of original object if it was existent if obj != nil { @@ -673,7 +673,7 @@ func (s *StateDB) ForEachStorage(addr common.Address, cb func(key, value common. if so == nil { return nil } - tr, err := so.getTrie(s.db) + tr, err := so.getTrie() if err != nil { return err } @@ -851,7 +851,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { s.deleteStateObject(obj) s.AccountDeleted += 1 } else { - obj.updateRoot(s.db) + obj.updateRoot() s.updateStateObject(obj) s.AccountUpdated += 1 } @@ -880,7 +880,14 @@ func (s *StateDB) clearJournalAndRefund() { } // Commit writes the state to the underlying in-memory trie database. -func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) { +// Once the state is committed, tries cached in stateDB (including account +// trie, storage tries) will no longer be functional. A new state instance +// must be created with new root and updated database for accessing post- +// commit states. +// +// The associated block number of the state transition is also provided +// for more chain context. +func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, error) { // Finalize any pending changes and merge everything into the tries s.IntermediateRoot(deleteEmptyObjects) @@ -904,7 +911,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) { obj.dirtyCode = false } // Write any storage changes in the state object to its storage trie - set, err := obj.commitTrie(s.db) + set, err := obj.commitTrie() if err != nil { return common.Hash{}, err } @@ -969,7 +976,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) { } if root != origin { start := time.Now() - if err := s.db.TrieDB().Update(nodes); err != nil { + if err := s.db.TrieDB().Update(block, nodes); err != nil { return common.Hash{}, err } s.originalRoot = root diff --git a/core/state/statedb_hooked_test.go b/core/state/statedb_hooked_test.go index a39670f67e..08b18b36ef 100644 --- a/core/state/statedb_hooked_test.go +++ b/core/state/statedb_hooked_test.go @@ -70,7 +70,7 @@ func TestBurn(t *testing.T) { hooked.AddBalance(addC, big.NewInt(200), tracing.BalanceChangeUnspecified) hooked.Finalise(true) - s.Commit(false) + s.Commit(0, false) if have, want := burned, big.NewInt(600); have.Cmp(want) != 0 { t.Fatalf("burn-count wrong, have %v want %v", have, want) } diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index e3a0d27842..f3e765bf61 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -103,7 +103,7 @@ func TestIntermediateLeaks(t *testing.T) { } // Commit and cross check the databases. - transRoot, err := transState.Commit(false) + transRoot, err := transState.Commit(0, false) if err != nil { t.Fatalf("failed to commit transition state: %v", err) } @@ -111,7 +111,7 @@ func TestIntermediateLeaks(t *testing.T) { t.Errorf("can not commit trie %v to persistent database", transRoot.Hex()) } - finalRoot, err := finalState.Commit(false) + finalRoot, err := finalState.Commit(0, false) if err != nil { t.Fatalf("failed to commit final state: %v", err) } @@ -499,7 +499,7 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error { func TestTouchDelete(t *testing.T) { s := newStateTest() s.state.GetOrNewStateObject(common.Address{}) - root, _ := s.state.Commit(false) + root, _ := s.state.Commit(0, false) s.state.Reset(root) snapshot := s.state.Snapshot() @@ -737,7 +737,7 @@ func TestDeleteCreateRevert(t *testing.T) { addr := common.BytesToAddress([]byte("so")) state.SetBalance(addr, big.NewInt(1), tracing.BalanceChangeUnspecified) - root, _ := state.Commit(false) + root, _ := state.Commit(0, false) state.Reset(root) // Simulate self-destructing in one transaction, then create-reverting in another @@ -749,7 +749,7 @@ func TestDeleteCreateRevert(t *testing.T) { state.RevertToSnapshot(id) // Commit the entire state and make sure we don't crash and have the correct state - root, _ = state.Commit(true) + root, _ = state.Commit(0, true) state.Reset(root) if state.getStateObject(addr) != nil { @@ -815,7 +815,7 @@ func TestCopyCommitCopy(t *testing.T) { t.Fatalf("first copy pre-commit committed storage slot mismatch: have %x, want %x", val, common.Hash{}) } - copyOne.Commit(false) + copyOne.Commit(0, false) if balance := copyOne.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 { t.Fatalf("first copy post-commit balance mismatch: have %v, want %v", balance, 42) } @@ -900,7 +900,7 @@ func TestCopyCopyCommitCopy(t *testing.T) { if val := copyTwo.GetCommittedState(addr, skey); val != (common.Hash{}) { t.Fatalf("second copy pre-commit committed storage slot mismatch: have %x, want %x", val, common.Hash{}) } - copyTwo.Commit(false) + copyTwo.Commit(0, false) if balance := copyTwo.GetBalance(addr); balance.Cmp(big.NewInt(42)) != 0 { t.Fatalf("second copy post-commit balance mismatch: have %v, want %v", balance, 42) } @@ -944,7 +944,7 @@ func TestFlushOrderDataLoss(t *testing.T) { state.SetState(common.Address{a}, common.Hash{a, s}, common.Hash{a, s}) } } - root, err := state.Commit(false) + root, err := state.Commit(0, false) if err != nil { t.Fatalf("failed to commit state trie: %v", err) } diff --git a/core/state/sync_test.go b/core/state/sync_test.go index 7cae6469da..b5da06068a 100644 --- a/core/state/sync_test.go +++ b/core/state/sync_test.go @@ -64,13 +64,13 @@ func makeTestState() (ethdb.Database, Database, common.Hash, []*testAccount) { if i%5 == 0 { for j := byte(0); j < 5; j++ { hash := crypto.Keccak256Hash([]byte{i, i, i, i, i, j, j}) - obj.SetState(sdb, hash, hash) + obj.SetState(hash, hash) } } state.updateStateObject(obj) accounts = append(accounts, acc) } - root, _ := state.Commit(false) + root, _ := state.Commit(0, false) // Return the generated state return db, sdb, root, accounts diff --git a/eth/api_debug_test.go b/eth/api_debug_test.go index 745ab7a0bb..2ffed6d5b6 100644 --- a/eth/api_debug_test.go +++ b/eth/api_debug_test.go @@ -80,7 +80,7 @@ func TestAccountRange(t *testing.T) { m[addr] = true } } - sdb.Commit(true) + sdb.Commit(0, true) root := sdb.IntermediateRoot(true) trie, err := statedb.OpenTrie(root) @@ -135,7 +135,7 @@ func TestEmptyAccountRange(t *testing.T) { statedb = state.NewDatabase(rawdb.NewMemoryDatabase()) st, _ = state.New(common.Hash{}, statedb) ) - st.Commit(true) + st.Commit(0, true) st.IntermediateRoot(true) results := st.IteratorDump(&state.DumpConfig{ SkipCode: true, diff --git a/eth/state_accessor.go b/eth/state_accessor.go index d0453d5a1e..34a9b2f7f6 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -165,7 +165,7 @@ func (eth *Ethereum) StateAtBlock(ctx context.Context, block *types.Block, reexe return nil, nil, fmt.Errorf("processing block %d failed: %v", current.NumberU64(), err) } // Finalize the state so any modifications are written to the trie - root, err := statedb.Commit(eth.blockchain.Config().IsEIP158(current.Number())) + root, err := statedb.Commit(current.NumberU64(), eth.blockchain.Config().IsEIP158(current.Number())) if err != nil { return nil, nil, fmt.Errorf("stateAtBlock commit failed, number %d root %v: %w", current.NumberU64(), current.Root().Hex(), err) diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 2c8eb413e2..b8bd732426 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -198,7 +198,7 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) (*state.StateD } // Commit block - root, _ := statedb.Commit(config.IsEIP158(block.Number())) + root, _ := statedb.Commit(block.NumberU64(), config.IsEIP158(block.Number())) if root != common.Hash(post.Root) { return statedb, fmt.Errorf("post state root mismatch: got %x, want %x", root, post.Root) } @@ -221,7 +221,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB } } // Commit and re-open to start with a clean state. - root, _ := statedb.Commit(false) + root, _ := statedb.Commit(0, false) statedb, _ = state.New(root, sdb) return statedb } diff --git a/trie/database.go b/trie/database.go index 79e5b5f370..725df30260 100644 --- a/trie/database.go +++ b/trie/database.go @@ -787,7 +787,7 @@ func (c *cleaner) Delete(key []byte) error { // Update inserts the dirty nodes in provided nodeset into database and // link the account trie with multiple storage tries if necessary. -func (db *Database) Update(nodes *MergedNodeSet) error { +func (db *Database) Update(block uint64, nodes *MergedNodeSet) error { db.lock.Lock() defer db.lock.Unlock() diff --git a/trie/iterator_test.go b/trie/iterator_test.go index 43dd6905d1..73f28761e3 100644 --- a/trie/iterator_test.go +++ b/trie/iterator_test.go @@ -61,7 +61,7 @@ func TestIterator(t *testing.T) { trie.MustUpdate([]byte(val.k), []byte(val.v)) } root, nodes := trie.Commit(false) - db.Update(NewWithNodeSet(nodes)) + db.Update(0, NewWithNodeSet(nodes)) trie, _ = New(TrieID(root), db) found := make(map[string]string) @@ -227,7 +227,7 @@ func TestDifferenceIterator(t *testing.T) { triea.MustUpdate([]byte(val.k), []byte(val.v)) } rootA, nodesA := triea.Commit(false) - dba.Update(NewWithNodeSet(nodesA)) + dba.Update(0, NewWithNodeSet(nodesA)) triea, _ = New(TrieID(rootA), dba) dbb := NewDatabase(rawdb.NewMemoryDatabase()) @@ -236,7 +236,7 @@ func TestDifferenceIterator(t *testing.T) { trieb.MustUpdate([]byte(val.k), []byte(val.v)) } rootB, nodesB := trieb.Commit(false) - dbb.Update(NewWithNodeSet(nodesB)) + dbb.Update(0, NewWithNodeSet(nodesB)) trieb, _ = New(TrieID(rootB), dbb) found := make(map[string]string) @@ -269,7 +269,7 @@ func TestUnionIterator(t *testing.T) { triea.MustUpdate([]byte(val.k), []byte(val.v)) } rootA, nodesA := triea.Commit(false) - dba.Update(NewWithNodeSet(nodesA)) + dba.Update(0, NewWithNodeSet(nodesA)) triea, _ = New(TrieID(rootA), dba) dbb := NewDatabase(rawdb.NewMemoryDatabase()) @@ -278,7 +278,7 @@ func TestUnionIterator(t *testing.T) { trieb.MustUpdate([]byte(val.k), []byte(val.v)) } rootB, nodesB := trieb.Commit(false) - dbb.Update(NewWithNodeSet(nodesB)) + dbb.Update(0, NewWithNodeSet(nodesB)) trieb, _ = New(TrieID(rootB), dbb) di, _ := NewUnionIterator([]NodeIterator{triea.NodeIterator(nil), trieb.NodeIterator(nil)}) @@ -336,7 +336,7 @@ func testIteratorContinueAfterError(t *testing.T, memonly bool) { tr.MustUpdate([]byte(val.k), []byte(val.v)) } _, nodes := tr.Commit(false) - triedb.Update(NewWithNodeSet(nodes)) + triedb.Update(0, NewWithNodeSet(nodes)) if !memonly { triedb.Commit(tr.Hash(), false) } @@ -428,7 +428,7 @@ func testIteratorContinueAfterSeekError(t *testing.T, memonly bool) { ctr.MustUpdate([]byte(val.k), []byte(val.v)) } root, nodes := ctr.Commit(false) - triedb.Update(NewWithNodeSet(nodes)) + triedb.Update(0, NewWithNodeSet(nodes)) if !memonly { triedb.Commit(root, false) } @@ -543,7 +543,7 @@ func makeLargeTestTrie() (*Database, *StateTrie, *loggingDb) { trie.MustUpdate(key, val) } _, nodes := trie.Commit(false) - triedb.Update(NewWithNodeSet(nodes)) + triedb.Update(0, NewWithNodeSet(nodes)) // Return the generated trie return triedb, trie, logDb } @@ -583,7 +583,7 @@ func TestIteratorNodeBlob(t *testing.T) { trie.MustUpdate([]byte(val.k), []byte(val.v)) } _, nodes := trie.Commit(false) - triedb.Update(NewWithNodeSet(nodes)) + triedb.Update(0, NewWithNodeSet(nodes)) triedb.Cap(0) found := make(map[common.Hash][]byte) diff --git a/trie/secure_trie_test.go b/trie/secure_trie_test.go index d533e0823a..f4f59a2bbd 100644 --- a/trie/secure_trie_test.go +++ b/trie/secure_trie_test.go @@ -59,7 +59,7 @@ func makeTestStateTrie() (*Database, *StateTrie, map[string][]byte) { } } root, nodes := trie.Commit(false) - if err := triedb.Update(NewWithNodeSet(nodes)); err != nil { + if err := triedb.Update(0, NewWithNodeSet(nodes)); err != nil { panic(fmt.Errorf("failed to commit db %v", err)) } // Re-create the trie based on the new state diff --git a/trie/sync_test.go b/trie/sync_test.go index d80f1fcb4a..c88f4d245e 100644 --- a/trie/sync_test.go +++ b/trie/sync_test.go @@ -54,7 +54,7 @@ func makeTestTrie() (*Database, *StateTrie, map[string][]byte) { } } root, nodes := trie.Commit(false) - if err := triedb.Update(NewWithNodeSet(nodes)); err != nil { + if err := triedb.Update(0, NewWithNodeSet(nodes)); err != nil { panic(fmt.Errorf("failed to commit db %v", err)) } // Re-create the trie based on the new state diff --git a/trie/tracer_test.go b/trie/tracer_test.go index c32e73ef6a..a43cf7e2f9 100644 --- a/trie/tracer_test.go +++ b/trie/tracer_test.go @@ -69,7 +69,7 @@ func testTrieTracer(t *testing.T, vals []struct{ k, v string }) { insertSet := copySet(trie.tracer.inserts) // copy before commit deleteSet := copySet(trie.tracer.deletes) // copy before commit root, nodes := trie.Commit(false) - db.Update(NewWithNodeSet(nodes)) + db.Update(0, NewWithNodeSet(nodes)) seen := setKeys(iterNodes(db, root)) if !compareSet(insertSet, seen) { @@ -135,7 +135,7 @@ func testAccessList(t *testing.T, vals []struct{ k, v string }) { trie.MustUpdate([]byte(val.k), []byte(val.v)) } root, nodes := trie.Commit(false) - db.Update(NewWithNodeSet(nodes)) + db.Update(0, NewWithNodeSet(nodes)) trie, _ = New(TrieID(root), db) if err := verifyAccessList(orig, trie, nodes); err != nil { @@ -149,7 +149,7 @@ func testAccessList(t *testing.T, vals []struct{ k, v string }) { trie.MustUpdate([]byte(val.k), randBytes(32)) } root, nodes = trie.Commit(false) - db.Update(NewWithNodeSet(nodes)) + db.Update(0, NewWithNodeSet(nodes)) trie, _ = New(TrieID(root), db) if err := verifyAccessList(orig, trie, nodes); err != nil { @@ -166,7 +166,7 @@ func testAccessList(t *testing.T, vals []struct{ k, v string }) { trie.MustUpdate(key, randBytes(32)) } root, nodes = trie.Commit(false) - db.Update(NewWithNodeSet(nodes)) + db.Update(0, NewWithNodeSet(nodes)) trie, _ = New(TrieID(root), db) if err := verifyAccessList(orig, trie, nodes); err != nil { @@ -180,7 +180,7 @@ func testAccessList(t *testing.T, vals []struct{ k, v string }) { trie.MustUpdate([]byte(key), nil) } root, nodes = trie.Commit(false) - db.Update(NewWithNodeSet(nodes)) + db.Update(0, NewWithNodeSet(nodes)) trie, _ = New(TrieID(root), db) if err := verifyAccessList(orig, trie, nodes); err != nil { @@ -194,7 +194,7 @@ func testAccessList(t *testing.T, vals []struct{ k, v string }) { trie.MustUpdate([]byte(val.k), nil) } root, nodes = trie.Commit(false) - db.Update(NewWithNodeSet(nodes)) + db.Update(0, NewWithNodeSet(nodes)) trie, _ = New(TrieID(root), db) if err := verifyAccessList(orig, trie, nodes); err != nil { @@ -213,7 +213,7 @@ func TestAccessListLeak(t *testing.T) { trie.MustUpdate([]byte(val.k), []byte(val.v)) } root, nodes := trie.Commit(false) - db.Update(NewWithNodeSet(nodes)) + db.Update(0, NewWithNodeSet(nodes)) var cases = []struct { op func(tr *Trie) @@ -263,7 +263,7 @@ func TestTinyTree(t *testing.T) { trie.MustUpdate([]byte(val.k), randBytes(32)) } root, set := trie.Commit(false) - db.Update(NewWithNodeSet(set)) + db.Update(0, NewWithNodeSet(set)) trie, _ = New(TrieID(root), db) orig := trie.Copy() @@ -271,7 +271,7 @@ func TestTinyTree(t *testing.T) { trie.MustUpdate([]byte(val.k), []byte(val.v)) } root, set = trie.Commit(false) - db.Update(NewWithNodeSet(set)) + db.Update(0, NewWithNodeSet(set)) trie, _ = New(TrieID(root), db) if err := verifyAccessList(orig, trie, set); err != nil { diff --git a/trie/trie.go b/trie/trie.go index c0fff4bdc9..75c973e0c6 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -81,7 +81,7 @@ func (t *Trie) UpdateDb(nodes *MergedNodeSet) error { if t.db == nil { return errors.New("database is nil in trie") } - return t.db.Update(nodes) + return t.db.Update(0, nodes) } // Copy returns a copy of Trie. diff --git a/trie/trie_test.go b/trie/trie_test.go index 9856e685ba..cf583a5903 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -85,7 +85,7 @@ func testMissingNode(t *testing.T, memonly bool) { updateString(trie, "120000", "qwerqwerqwerqwerqwerqwerqwerqwer") updateString(trie, "123456", "asdfasdfasdfasdfasdfasdfasdfasdf") root, nodes := trie.Commit(false) - triedb.Update(NewWithNodeSet(nodes)) + triedb.Update(0, NewWithNodeSet(nodes)) if !memonly { triedb.Commit(root, false) } @@ -193,7 +193,7 @@ func TestGet(t *testing.T) { return } root, nodes := trie.Commit(false) - db.Update(NewWithNodeSet(nodes)) + db.Update(0, NewWithNodeSet(nodes)) trie, _ = New(TrieID(root), db) } } @@ -265,7 +265,7 @@ func TestReplication(t *testing.T) { updateString(trie, val.k, val.v) } exp, nodes := trie.Commit(false) - triedb.Update(NewWithNodeSet(nodes)) + triedb.Update(0, NewWithNodeSet(nodes)) // create a new trie on top of the database and check that lookups work. trie2, err := New(TrieID(exp), triedb) @@ -284,7 +284,7 @@ func TestReplication(t *testing.T) { // recreate the trie after commit if nodes != nil { - triedb.Update(NewWithNodeSet(nodes)) + triedb.Update(0, NewWithNodeSet(nodes)) } trie2, err = New(TrieID(hash), triedb) if err != nil { @@ -509,7 +509,7 @@ func runRandTest(rt randTest) error { case opCommit: root, nodes := tr.Commit(true) if nodes != nil { - triedb.Update(NewWithNodeSet(nodes)) + triedb.Update(0, NewWithNodeSet(nodes)) } newtr, err := New(TrieID(root), triedb) if err != nil { @@ -842,7 +842,7 @@ func TestCommitSequence(t *testing.T) { } // Flush trie -> database root, nodes := trie.Commit(false) - db.Update(NewWithNodeSet(nodes)) + db.Update(0, NewWithNodeSet(nodes)) // Flush memdb -> disk (sponge) db.Commit(root, false) if got, exp := s.sponge.Sum(nil), tc.expWriteSeqHash; !bytes.Equal(got, exp) { @@ -883,7 +883,7 @@ func TestCommitSequenceRandomBlobs(t *testing.T) { } // Flush trie -> database root, nodes := trie.Commit(false) - db.Update(NewWithNodeSet(nodes)) + db.Update(0, NewWithNodeSet(nodes)) // Flush memdb -> disk (sponge) db.Commit(root, false) if got, exp := s.sponge.Sum(nil), tc.expWriteSeqHash; !bytes.Equal(got, exp) { @@ -923,7 +923,7 @@ func TestCommitSequenceStackTrie(t *testing.T) { // Flush trie -> database root, nodes := trie.Commit(false) // Flush memdb -> disk (sponge) - db.Update(NewWithNodeSet(nodes)) + db.Update(0, NewWithNodeSet(nodes)) db.Commit(root, false) // And flush stacktrie -> disk stRoot, err := stTrie.Commit() @@ -971,7 +971,7 @@ func TestCommitSequenceSmallRoot(t *testing.T) { // Flush trie -> database root, nodes := trie.Commit(false) // Flush memdb -> disk (sponge) - db.Update(NewWithNodeSet(nodes)) + db.Update(0, NewWithNodeSet(nodes)) db.Commit(root, false) // And flush stacktrie -> disk stRoot, err := stTrie.Commit() @@ -1142,7 +1142,7 @@ func benchmarkDerefRootFixedSize(b *testing.B, addresses [][20]byte, accounts [] } h := trie.Hash() _, nodes := trie.Commit(false) - triedb.Update(NewWithNodeSet(nodes)) + triedb.Update(0, NewWithNodeSet(nodes)) b.StartTimer() triedb.Dereference(h) b.StopTimer()