mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-13 07:23:46 +00:00
core/state: unset the block-level accessList in Finalise (#35498)
This PR explicitly clears the referenced block access list at the end of each transaction. This is essential because accounts are shadow-copied into the global block access list, and it prevents accidental mutations through stale references in StateDB.
This commit is contained in:
parent
7924511bf6
commit
35fe1bf69c
41 changed files with 196 additions and 168 deletions
|
|
@ -160,6 +160,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
|
||||
isEIP4762 = chainConfig.IsUBT(big.NewInt(int64(pre.Env.Number)), pre.Env.Timestamp)
|
||||
isAmsterdam = chainConfig.IsAmsterdam(big.NewInt(int64(pre.Env.Number)), pre.Env.Timestamp)
|
||||
rules = chainConfig.Rules(big.NewInt(int64(pre.Env.Number)), pre.Env.Random != nil, pre.Env.Timestamp)
|
||||
)
|
||||
if pre.AllocPath != "" {
|
||||
var err error
|
||||
|
|
@ -308,7 +309,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
receipts = append(receipts, receipt)
|
||||
blockAccessList.Merge(bal)
|
||||
}
|
||||
statedb.IntermediateRoot(chainConfig.IsEIP158(vmContext.BlockNumber))
|
||||
statedb.IntermediateRoot(rules)
|
||||
|
||||
// TODO(rjl493456442) call engine.Finalize() instead
|
||||
// Add mining reward? (-1 means rewards are disabled)
|
||||
|
|
@ -369,7 +370,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
blockAccessList.Merge(bal)
|
||||
|
||||
// Commit block
|
||||
root, err := statedb.Commit(vmContext.BlockNumber.Uint64(), chainConfig.IsEIP158(vmContext.BlockNumber), chainConfig.IsCancun(vmContext.BlockNumber, vmContext.Time))
|
||||
root, err := statedb.Commit(rules, vmContext.BlockNumber.Uint64())
|
||||
if err != nil {
|
||||
return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not commit state: %v", err))
|
||||
}
|
||||
|
|
@ -455,7 +456,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, isBintrie bool
|
|||
}
|
||||
}
|
||||
// Commit and re-open to start with a clean state.
|
||||
root, err = statedb.Commit(0, false, false)
|
||||
root, err = statedb.Commit(params.Rules{}, 0)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to commit initial state: %v", err))
|
||||
}
|
||||
|
|
@ -530,7 +531,7 @@ func MakePreStateStreaming(db ethdb.Database, allocPath string, isBintrie bool)
|
|||
return nil, NewError(ErrorJson, fmt.Errorf("failed reading alloc closing token: %v", err))
|
||||
}
|
||||
|
||||
root, err = statedb.Commit(0, false, false)
|
||||
root, err = statedb.Commit(params.Rules{}, 0)
|
||||
if err != nil {
|
||||
return nil, NewError(ErrorEVM, fmt.Errorf("failed to commit initial state: %v", err))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ func Transition(ctx *cli.Context) error {
|
|||
return NewError(ErrorEVM, errors.New("UBT alloc recorder was not enabled"))
|
||||
}
|
||||
collector = Alloc(rec.Alloc())
|
||||
if err := mergeUnmigratedBaseAlloc(udb, s.IntermediateRoot(false), collector); err != nil {
|
||||
if err := mergeUnmigratedBaseAlloc(udb, s.IntermediateRoot(params.Rules{}), collector); err != nil {
|
||||
return NewError(ErrorEVM, fmt.Errorf("failed to merge base MPT alloc: %v", err))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
||||
"github.com/ethereum/go-ethereum/internal/debug"
|
||||
"github.com/ethereum/go-ethereum/internal/flags"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
// Force-load the tracer engines to trigger registration
|
||||
|
|
@ -340,7 +341,8 @@ func collectFiles(path string) []string {
|
|||
|
||||
// dump returns a state dump for the most current trie.
|
||||
func dump(s *state.StateDB) *state.Dump {
|
||||
root := s.IntermediateRoot(false)
|
||||
// A dump is not a state transition: report accounts exactly as they are.
|
||||
root := s.IntermediateRoot(params.Rules{})
|
||||
cpy, _ := state.New(root, s.Database())
|
||||
dump := cpy.RawDump(nil)
|
||||
return &dump
|
||||
|
|
|
|||
|
|
@ -339,7 +339,7 @@ func runCmd(ctx *cli.Context) error {
|
|||
output, stats, err := timedExec(bench, execFunc)
|
||||
|
||||
if ctx.Bool(DumpFlag.Name) {
|
||||
root, err := runtimeConfig.State.Commit(genesisConfig.Number, true, false)
|
||||
root, err := runtimeConfig.State.Commit(params.Rules{IsEIP158: true}, genesisConfig.Number)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to commit changes %v\n", err)
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/internal/flags"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/tests"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
|
@ -132,7 +133,7 @@ func runStateTest(ctx *cli.Context, fname string) ([]testResult, error) {
|
|||
test.Run(st, cfg, false, rawdb.HashScheme, func(err error, state *tests.StateTestState) {
|
||||
var root common.Hash
|
||||
if state.StateDB != nil {
|
||||
root = state.StateDB.IntermediateRoot(false)
|
||||
root = state.StateDB.IntermediateRoot(params.Rules{})
|
||||
result.Root = &root
|
||||
fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root)
|
||||
// Dump any state to aid debugging.
|
||||
|
|
|
|||
|
|
@ -201,7 +201,8 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD
|
|||
}
|
||||
// Validate the state root against the received state root and throw
|
||||
// an error if they don't match.
|
||||
if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root {
|
||||
rules := v.config.Rules(header.Number, header.Difficulty.Sign() == 0, header.Time)
|
||||
if root := statedb.IntermediateRoot(rules); header.Root != root {
|
||||
return fmt.Errorf("invalid merkle root (remote: %x local: %x) dberr: %w", header.Root, root, statedb.Error())
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -1665,12 +1665,11 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
|||
var (
|
||||
err error
|
||||
root common.Hash
|
||||
isEIP158 = bc.chainConfig.IsEIP158(block.Number())
|
||||
isCancun = bc.chainConfig.IsCancun(block.Number(), block.Time())
|
||||
hasStateHook = bc.logger != nil && bc.logger.OnStateUpdate != nil
|
||||
rules = bc.chainConfig.Rules(block.Number(), block.Difficulty().Sign() == 0, block.Time())
|
||||
)
|
||||
if hasStateHook {
|
||||
r, update, err := statedb.CommitWithUpdate(block.NumberU64(), isEIP158, isCancun)
|
||||
r, update, err := statedb.CommitWithUpdate(rules, block.NumberU64())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -1681,7 +1680,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
|||
bc.logger.OnStateUpdate(trUpdate)
|
||||
root = r
|
||||
} else {
|
||||
root, err = statedb.Commit(block.NumberU64(), isEIP158, isCancun)
|
||||
root, err = statedb.Commit(rules, block.NumberU64())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
|
|||
|
||||
blockchain.chainmu.MustLock()
|
||||
rawdb.WriteBlock(blockchain.db, block)
|
||||
statedb.Commit(block.NumberU64(), false, false)
|
||||
statedb.Commit(params.Rules{}, block.NumberU64())
|
||||
blockchain.chainmu.Unlock()
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
|||
|
||||
genblock := func(i int, parent *types.Block, triedb *triedb.Database, statedb *state.StateDB) (*types.Block, types.Receipts) {
|
||||
b := &BlockGen{i: i, cm: cm, parent: parent, statedb: statedb, engine: engine}
|
||||
b.header = cm.makeHeader(parent, statedb, b.engine)
|
||||
b.header = cm.makeHeader(parent, b.engine)
|
||||
b.bal = bal.NewConstructionBlockAccessList()
|
||||
|
||||
// Set the difficulty for clique block. The chain maker doesn't have access
|
||||
|
|
@ -441,7 +441,8 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
|||
block := AssembleBlock(cm, b.header, statedb, &body, b.receipts, b.bal)
|
||||
|
||||
// Write state changes to db
|
||||
root, err := statedb.Commit(b.header.Number.Uint64(), config.IsEIP158(b.header.Number), config.IsCancun(b.header.Number, b.header.Time))
|
||||
rules := config.Rules(b.header.Number, b.header.Difficulty.Sign() == 0, b.header.Time)
|
||||
root, err := statedb.Commit(rules, b.header.Number.Uint64())
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("state write error: %v", err))
|
||||
}
|
||||
|
|
@ -452,7 +453,7 @@ 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
|
||||
var triedbConfig = triedb.HashDefaults
|
||||
if config.IsUBT(config.ChainID, 0) {
|
||||
triedbConfig = triedb.UBTDefaults
|
||||
}
|
||||
|
|
@ -516,11 +517,10 @@ func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int,
|
|||
return db, blocks, receipts
|
||||
}
|
||||
|
||||
func (cm *chainMaker) makeHeader(parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header {
|
||||
func (cm *chainMaker) makeHeader(parent *types.Block, engine consensus.Engine) *types.Header {
|
||||
time := parent.Time() + 10 // block time is fixed at 10 seconds
|
||||
parentHeader := parent.Header()
|
||||
header := &types.Header{
|
||||
Root: state.IntermediateRoot(cm.config.IsEIP158(parent.Number())),
|
||||
ParentHash: parent.Hash(),
|
||||
Coinbase: parent.Coinbase(),
|
||||
Difficulty: engine.CalcDifficulty(cm, time, parentHeader),
|
||||
|
|
@ -528,7 +528,6 @@ func (cm *chainMaker) makeHeader(parent *types.Block, state *state.StateDB, engi
|
|||
Number: new(big.Int).Add(parent.Number(), common.Big1),
|
||||
Time: time,
|
||||
}
|
||||
|
||||
if cm.config.IsLondon(header.Number) {
|
||||
header.BaseFee = eip1559.CalcBaseFee(cm.config, parentHeader)
|
||||
if !cm.config.IsLondon(parent.Number()) {
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ func assertParallelEquiv(t *testing.T, gspec *Genesis, engine consensus.Engine,
|
|||
if err != nil {
|
||||
t.Fatalf("parallel process: %v", err)
|
||||
}
|
||||
parRoot := parState.IntermediateRoot(gspec.Config.IsEIP158(block.Number()))
|
||||
parRoot := parState.IntermediateRoot(gspec.Config.Rules(block.Number(), block.Difficulty().Sign() == 0, block.Time()))
|
||||
|
||||
// Sequential path, forced explicitly via DisableParallelExecution.
|
||||
seqState, err := bc.State()
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ func mkState(alloc types.GenesisAlloc) *state.StateDB {
|
|||
sdb.SetState(addr, k, v)
|
||||
}
|
||||
}
|
||||
sdb.Finalise(true)
|
||||
sdb.Finalise(params.Rules{IsEIP158: true})
|
||||
return sdb
|
||||
}
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ func mkCommittedState(t *testing.T, alloc types.GenesisAlloc) *state.StateDB {
|
|||
sdb.SetState(addr, k, v)
|
||||
}
|
||||
}
|
||||
root, err := sdb.Commit(0, false, false)
|
||||
root, err := sdb.Commit(params.Rules{}, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("commit prestate: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ func hashAlloc(ga *types.GenesisAlloc, isUBT bool) (common.Hash, error) {
|
|||
emptyRoot = types.EmptyBinaryHash
|
||||
}
|
||||
db := rawdb.NewMemoryDatabase()
|
||||
|
||||
statedb, err := state.New(emptyRoot, state.NewDatabase(triedb.NewDatabase(db, config), nil))
|
||||
if err != nil {
|
||||
return common.Hash{}, err
|
||||
|
|
@ -162,7 +163,7 @@ func hashAlloc(ga *types.GenesisAlloc, isUBT bool) (common.Hash, error) {
|
|||
statedb.SetState(addr, key, value)
|
||||
}
|
||||
}
|
||||
return statedb.Commit(0, false, false)
|
||||
return statedb.Commit(params.Rules{}, 0)
|
||||
}
|
||||
|
||||
// flushAlloc is very similar with hash, but the main difference is all the
|
||||
|
|
@ -191,7 +192,7 @@ func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database, tracer *tracing
|
|||
|
||||
var root common.Hash
|
||||
if tracer != nil && tracer.OnStateUpdate != nil {
|
||||
r, update, err := statedb.CommitWithUpdate(0, false, false)
|
||||
r, update, err := statedb.CommitWithUpdate(params.Rules{}, 0)
|
||||
if err != nil {
|
||||
return common.Hash{}, err
|
||||
}
|
||||
|
|
@ -202,7 +203,7 @@ func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database, tracer *tracing
|
|||
tracer.OnStateUpdate(trUpdate)
|
||||
root = r
|
||||
} else {
|
||||
root, err = statedb.Commit(0, false, false)
|
||||
root, err = statedb.Commit(params.Rules{}, 0)
|
||||
if err != nil {
|
||||
return common.Hash{}, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/triedb"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
|
@ -54,7 +55,7 @@ func TestDump(t *testing.T) {
|
|||
obj3.SetBalance(uint256.NewInt(44))
|
||||
|
||||
// write some of them to the trie
|
||||
root, _ := s.state.Commit(0, false, false)
|
||||
root, _ := s.state.Commit(params.Rules{}, 0)
|
||||
|
||||
// check that DumpToCollector contains the state objects that are in trie
|
||||
s.state, _ = New(root, tdb)
|
||||
|
|
@ -112,7 +113,7 @@ func TestIterativeDump(t *testing.T) {
|
|||
obj4.AddBalance(uint256.NewInt(1337))
|
||||
|
||||
// write some of them to the trie
|
||||
root, _ := s.state.Commit(0, false, false)
|
||||
root, _ := s.state.Commit(params.Rules{}, 0)
|
||||
s.state, _ = New(root, tdb)
|
||||
|
||||
b := &bytes.Buffer{}
|
||||
|
|
@ -138,7 +139,7 @@ func TestNull(t *testing.T) {
|
|||
var value common.Hash
|
||||
|
||||
s.state.SetState(address, common.Hash{}, value)
|
||||
s.state.Commit(0, false, false)
|
||||
s.state.Commit(params.Rules{}, 0)
|
||||
|
||||
if value := s.state.GetState(address, common.Hash{}); value != (common.Hash{}) {
|
||||
t.Errorf("expected empty current value, got %x", value)
|
||||
|
|
|
|||
|
|
@ -776,9 +776,9 @@ func (s *StateDB) GetRefund() uint64 {
|
|||
// Finalise finalises the state by removing the destructed objects and clears
|
||||
// the journal as well as the refunds. Finalise, however, will not push any updates
|
||||
// into the tries just yet. Only IntermediateRoot or Commit will do that.
|
||||
func (s *StateDB) Finalise(deleteEmptyObjects bool) *bal.ConstructionBlockAccessList {
|
||||
if s.stateAccessList != nil {
|
||||
return s.finaliseAmsterdam(deleteEmptyObjects)
|
||||
func (s *StateDB) Finalise(rules params.Rules) *bal.ConstructionBlockAccessList {
|
||||
if rules.IsAmsterdam {
|
||||
return s.finaliseAmsterdam(rules)
|
||||
}
|
||||
addressesToPrefetch := make([]common.Address, 0, len(s.journal.mutations))
|
||||
for addr := range s.journal.mutations {
|
||||
|
|
@ -795,7 +795,7 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) *bal.ConstructionBlockAccess
|
|||
// finalise or delete, so ignore it here.
|
||||
continue
|
||||
}
|
||||
if obj.selfDestructed || (deleteEmptyObjects && obj.empty()) {
|
||||
if obj.selfDestructed || (rules.IsEIP158 && obj.empty()) {
|
||||
delete(s.stateObjects, obj.address)
|
||||
s.markDelete(addr)
|
||||
|
||||
|
|
@ -817,12 +817,17 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) *bal.ConstructionBlockAccess
|
|||
}
|
||||
}
|
||||
// Invalidate journal because reverting across transactions is not allowed.
|
||||
s.clearJournalAndRefund()
|
||||
s.clearInternal()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *StateDB) recordAccessListChanges(addr common.Address, state *journalMutationState) {
|
||||
// No list means we are outside a transaction scope (e.g, PostExecution
|
||||
// without a preceding Prepare), skip BAL recording.
|
||||
if s.stateAccessList == nil {
|
||||
return
|
||||
}
|
||||
var (
|
||||
balance = uint256.NewInt(0)
|
||||
nonce uint64
|
||||
|
|
@ -849,7 +854,7 @@ func (s *StateDB) recordAccessListChanges(addr common.Address, state *journalMut
|
|||
}
|
||||
|
||||
// finaliseAmsterdam is the Amsterdam-and-later variant of Finalise.
|
||||
func (s *StateDB) finaliseAmsterdam(deleteEmptyObjects bool) *bal.ConstructionBlockAccessList {
|
||||
func (s *StateDB) finaliseAmsterdam(rules params.Rules) *bal.ConstructionBlockAccessList {
|
||||
addressesToPrefetch := make([]common.Address, 0, len(s.journal.mutations))
|
||||
for addr, state := range s.journal.mutations {
|
||||
obj, exist := s.stateObjects[addr]
|
||||
|
|
@ -886,7 +891,7 @@ func (s *StateDB) finaliseAmsterdam(deleteEmptyObjects bool) *bal.ConstructionBl
|
|||
}
|
||||
}
|
||||
|
||||
case deleteEmptyObjects && obj.empty():
|
||||
case rules.IsEIP158 && obj.empty():
|
||||
// EIP-161: a touched, empty account is removed.
|
||||
delete(s.stateObjects, obj.address)
|
||||
s.markDelete(addr)
|
||||
|
|
@ -913,17 +918,17 @@ func (s *StateDB) finaliseAmsterdam(deleteEmptyObjects bool) *bal.ConstructionBl
|
|||
}
|
||||
}
|
||||
// Invalidate journal because reverting across transactions is not allowed.
|
||||
s.clearJournalAndRefund()
|
||||
|
||||
return s.stateAccessList
|
||||
bal := s.stateAccessList
|
||||
s.clearInternal()
|
||||
return bal
|
||||
}
|
||||
|
||||
// IntermediateRoot computes the current root hash of the state trie.
|
||||
// It is called in between transactions to get the root hash that
|
||||
// goes into transaction receipts.
|
||||
func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||
func (s *StateDB) IntermediateRoot(rules params.Rules) common.Hash {
|
||||
// Finalise all the dirty storage states and write them into the tries
|
||||
s.Finalise(deleteEmptyObjects)
|
||||
s.Finalise(rules)
|
||||
|
||||
// Initialize the trie if it's not constructed yet. If the prefetch
|
||||
// is enabled, the trie constructed below will be replaced by the
|
||||
|
|
@ -1134,9 +1139,17 @@ func (s *StateDB) SetTxContext(thash common.Hash, ti int, blockAccessIndex uint3
|
|||
s.blockAccessIndex = blockAccessIndex
|
||||
}
|
||||
|
||||
func (s *StateDB) clearJournalAndRefund() {
|
||||
func (s *StateDB) clearInternal() {
|
||||
s.journal.reset()
|
||||
s.refund = 0
|
||||
|
||||
// The access list built during this scope has been handed off to the caller,
|
||||
// which merges it into the block-level list by adopting the account objects
|
||||
// rather than copying them.
|
||||
//
|
||||
// Dereferencing the accessList explicitly, avoiding any following mutations
|
||||
// affecting the external BAL.
|
||||
s.stateAccessList = nil
|
||||
}
|
||||
|
||||
// deleteStorage is designed to delete the storage trie of a designated account.
|
||||
|
|
@ -1204,7 +1217,7 @@ func (s *StateDB) deleteStorage(addrHash common.Hash, root common.Hash) (map[com
|
|||
// with their values be tracked as original value.
|
||||
// In case (d), **original** account along with its storages should be deleted,
|
||||
// with their values be tracked as original value.
|
||||
func (s *StateDB) handleDestruction(noStorageWiping bool) (map[common.Hash]*AccountDelete, []*trienode.NodeSet, error) {
|
||||
func (s *StateDB) handleDestruction(rules params.Rules) (map[common.Hash]*AccountDelete, []*trienode.NodeSet, error) {
|
||||
var (
|
||||
nodes []*trienode.NodeSet
|
||||
deletes = make(map[common.Hash]*AccountDelete)
|
||||
|
|
@ -1232,7 +1245,7 @@ func (s *StateDB) handleDestruction(noStorageWiping bool) (map[common.Hash]*Acco
|
|||
if prev.Root == types.EmptyRootHash || s.db.Type().Is(TypeUBT) {
|
||||
continue
|
||||
}
|
||||
if noStorageWiping {
|
||||
if rules.IsCancun {
|
||||
return nil, nil, fmt.Errorf("unexpected storage wiping, %x", addr)
|
||||
}
|
||||
// Remove storage slots belonging to the account.
|
||||
|
|
@ -1256,13 +1269,13 @@ func (s *StateDB) GetTrie() Trie {
|
|||
|
||||
// commit gathers the state mutations accumulated along with the associated
|
||||
// trie changes, resetting all internal flags with the new state as the base.
|
||||
func (s *StateDB) commit(deleteEmptyObjects bool, noStorageWiping bool, blockNumber uint64) (*StateUpdate, error) {
|
||||
func (s *StateDB) commit(rules params.Rules, blockNumber uint64) (*StateUpdate, error) {
|
||||
// Short circuit in case any database failure occurred earlier.
|
||||
if s.dbErr != nil {
|
||||
return nil, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr)
|
||||
}
|
||||
// Finalize any pending changes and merge everything into the tries
|
||||
root := s.IntermediateRoot(deleteEmptyObjects)
|
||||
root := s.IntermediateRoot(rules)
|
||||
|
||||
// Short circuit if any error occurs within the IntermediateRoot.
|
||||
if s.dbErr != nil {
|
||||
|
|
@ -1310,7 +1323,7 @@ func (s *StateDB) commit(deleteEmptyObjects bool, noStorageWiping bool, blockNum
|
|||
// the same block, account deletions must be processed first. This ensures
|
||||
// that the storage trie nodes deleted during destruction and recreated
|
||||
// during subsequent resurrection can be combined correctly.
|
||||
deletes, delNodes, err := s.handleDestruction(noStorageWiping)
|
||||
deletes, delNodes, err := s.handleDestruction(rules)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1406,7 +1419,7 @@ func (s *StateDB) commit(deleteEmptyObjects bool, noStorageWiping bool, blockNum
|
|||
s.originalRoot = root
|
||||
|
||||
typ := StorageKeyHashed
|
||||
if noStorageWiping {
|
||||
if rules.IsCancun {
|
||||
typ = StorageKeyPlain
|
||||
}
|
||||
return NewStateUpdate(typ, origin, root, blockNumber, deletes, updates, nodes), nil
|
||||
|
|
@ -1414,8 +1427,8 @@ func (s *StateDB) commit(deleteEmptyObjects bool, noStorageWiping bool, blockNum
|
|||
|
||||
// commitAndFlush is a wrapper of commit which also commits the state mutations
|
||||
// to the configured data stores.
|
||||
func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool, noStorageWiping bool, deriveCodeFields bool) (*StateUpdate, error) {
|
||||
ret, err := s.commit(deleteEmptyObjects, noStorageWiping, block)
|
||||
func (s *StateDB) commitAndFlush(rules params.Rules, block uint64, deriveCodeFields bool) (*StateUpdate, error) {
|
||||
ret, err := s.commit(rules, block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1446,12 +1459,10 @@ func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool, noStorag
|
|||
// The associated block number of the state transition is also provided
|
||||
// for more chain context.
|
||||
//
|
||||
// noStorageWiping is a flag indicating whether storage wiping is permitted.
|
||||
// Since self-destruction was deprecated with the Cancun fork and there are
|
||||
// no empty accounts left that could be deleted by EIP-158, storage wiping
|
||||
// should not occur.
|
||||
func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool, noStorageWiping bool) (common.Hash, error) {
|
||||
ret, err := s.commitAndFlush(block, deleteEmptyObjects, noStorageWiping, false)
|
||||
// Whether empty accounts are deleted and whether storage wiping is permitted
|
||||
// both follow from the fork rules this state was created with.
|
||||
func (s *StateDB) Commit(rules params.Rules, block uint64) (common.Hash, error) {
|
||||
ret, err := s.commitAndFlush(rules, block, false)
|
||||
if err != nil {
|
||||
return common.Hash{}, err
|
||||
}
|
||||
|
|
@ -1459,9 +1470,9 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool, noStorageWiping
|
|||
}
|
||||
|
||||
// CommitWithUpdate writes the state mutations and returns the state update for
|
||||
// external processing (e.g., live tracing hooks).
|
||||
func (s *StateDB) CommitWithUpdate(block uint64, deleteEmptyObjects bool, noStorageWiping bool) (common.Hash, *StateUpdate, error) {
|
||||
ret, err := s.commitAndFlush(block, deleteEmptyObjects, noStorageWiping, true)
|
||||
// external processing (e.g., live tracing hooks or size tracker).
|
||||
func (s *StateDB) CommitWithUpdate(rules params.Rules, block uint64) (common.Hash, *StateUpdate, error) {
|
||||
ret, err := s.commitAndFlush(rules, block, true)
|
||||
if err != nil {
|
||||
return common.Hash{}, nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/types/bal"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
|
|
@ -49,7 +50,7 @@ func TestApplyBlockAccessListConcurrentPrefetch(t *testing.T) {
|
|||
base.SetCode(addr, code, tracing.CodeChangeUnspecified)
|
||||
base.SetState(addr, slot, common.HexToHash("0xaa"))
|
||||
}
|
||||
root0, err := base.Commit(0, false, false)
|
||||
root0, err := base.Commit(params.Rules{}, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("commit base: %v", err)
|
||||
}
|
||||
|
|
@ -63,7 +64,7 @@ func TestApplyBlockAccessListConcurrentPrefetch(t *testing.T) {
|
|||
}
|
||||
seq, _ := New(root0, db)
|
||||
mutate(seq)
|
||||
wantRoot := seq.IntermediateRoot(true)
|
||||
wantRoot := seq.IntermediateRoot(params.Rules{IsEIP158: true})
|
||||
|
||||
cb := bal.NewConstructionBlockAccessList()
|
||||
for i := range n {
|
||||
|
|
@ -77,7 +78,7 @@ func TestApplyBlockAccessListConcurrentPrefetch(t *testing.T) {
|
|||
balState.StopPrefetcher()
|
||||
t.Fatalf("apply block access list: %v", err)
|
||||
}
|
||||
gotRoot := balState.IntermediateRoot(true)
|
||||
gotRoot := balState.IntermediateRoot(params.Rules{IsEIP158: true})
|
||||
balState.StopPrefetcher()
|
||||
|
||||
if gotRoot != wantRoot {
|
||||
|
|
@ -113,7 +114,7 @@ func TestApplyBlockAccessListMatchesSequential(t *testing.T) {
|
|||
base.SetCode(contract, code, tracing.CodeChangeUnspecified)
|
||||
base.SetState(contract, slotA, common.HexToHash("0xaa"))
|
||||
base.SetState(contract, slotB, common.HexToHash("0xbb"))
|
||||
root0, err := base.Commit(0, false, false)
|
||||
root0, err := base.Commit(params.Rules{}, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("commit base: %v", err)
|
||||
}
|
||||
|
|
@ -131,7 +132,7 @@ func TestApplyBlockAccessListMatchesSequential(t *testing.T) {
|
|||
// Sequential reference root.
|
||||
seq, _ := New(root0, db)
|
||||
mutate(seq)
|
||||
wantRoot := seq.IntermediateRoot(true)
|
||||
wantRoot := seq.IntermediateRoot(params.Rules{IsEIP158: true})
|
||||
if wantRoot == root0 {
|
||||
t.Fatal("mutations did not change the state root")
|
||||
}
|
||||
|
|
@ -152,7 +153,7 @@ func TestApplyBlockAccessListMatchesSequential(t *testing.T) {
|
|||
balState.StopPrefetcher()
|
||||
t.Fatalf("apply block access list: %v", err)
|
||||
}
|
||||
gotRoot := balState.IntermediateRoot(true)
|
||||
gotRoot := balState.IntermediateRoot(params.Rules{IsEIP158: true})
|
||||
balState.StopPrefetcher()
|
||||
|
||||
if gotRoot != wantRoot {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
"github.com/ethereum/go-ethereum/triedb"
|
||||
|
|
@ -217,19 +218,19 @@ func (test *stateTest) run() bool {
|
|||
for i, action := range actions {
|
||||
if i%test.chunk == 0 && i != 0 {
|
||||
if byzantium {
|
||||
state.Finalise(true) // call finalise at the transaction boundary
|
||||
state.Finalise(params.Rules{IsEIP158: true}) // call finalise at the transaction boundary
|
||||
} else {
|
||||
state.IntermediateRoot(true) // call intermediateRoot at the transaction boundary
|
||||
state.IntermediateRoot(params.Rules{IsEIP158: true}) // call intermediateRoot at the transaction boundary
|
||||
}
|
||||
}
|
||||
action.fn(action, state)
|
||||
}
|
||||
if byzantium {
|
||||
state.Finalise(true) // call finalise at the transaction boundary
|
||||
state.Finalise(params.Rules{IsEIP158: true}) // call finalise at the transaction boundary
|
||||
} else {
|
||||
state.IntermediateRoot(true) // call intermediateRoot at the transaction boundary
|
||||
state.IntermediateRoot(params.Rules{IsEIP158: true}) // call intermediateRoot at the transaction boundary
|
||||
}
|
||||
ret, err := state.commitAndFlush(0, true, false, false) // call commit at the block boundary
|
||||
ret, err := state.commitAndFlush(params.Rules{IsEIP158: true}, 0, false) // call commit at the block boundary
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,10 +230,10 @@ func (s *hookedStateDB) AddLog(log *types.Log) {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *hookedStateDB) Finalise(deleteEmptyObjects bool) *bal.ConstructionBlockAccessList {
|
||||
func (s *hookedStateDB) Finalise(rules params.Rules) *bal.ConstructionBlockAccessList {
|
||||
if s.hooks.OnBalanceChange == nil && s.hooks.OnNonceChangeV2 == nil && s.hooks.OnNonceChange == nil && s.hooks.OnCodeChangeV2 == nil && s.hooks.OnCodeChange == nil {
|
||||
// Short circuit if no relevant hooks are set.
|
||||
return s.inner.Finalise(deleteEmptyObjects)
|
||||
return s.inner.Finalise(rules)
|
||||
}
|
||||
|
||||
// Collect all self-destructed addresses first, then sort them to ensure
|
||||
|
|
@ -255,7 +255,7 @@ func (s *hookedStateDB) Finalise(deleteEmptyObjects bool) *bal.ConstructionBlock
|
|||
// EIP-8246 (Amsterdam) removes the SELFDESTRUCT burn: a self-destructed
|
||||
// account that retains a non-zero balance is preserved as a balance-only
|
||||
// account rather than removed, so its balance is no longer burnt.
|
||||
burnsBalance := s.inner.stateAccessList == nil
|
||||
burnsBalance := !rules.IsAmsterdam
|
||||
|
||||
for _, addr := range selfDestructedAddrs {
|
||||
obj := s.inner.stateObjects[addr]
|
||||
|
|
@ -288,7 +288,7 @@ func (s *hookedStateDB) Finalise(deleteEmptyObjects bool) *bal.ConstructionBlock
|
|||
s.hooks.OnCodeChange(addr, prevCodeHash, s.inner.GetCode(addr), types.EmptyCodeHash, nil)
|
||||
}
|
||||
}
|
||||
return s.inner.Finalise(deleteEmptyObjects)
|
||||
return s.inner.Finalise(rules)
|
||||
}
|
||||
|
||||
func (s *hookedStateDB) SetTxContext(thash common.Hash, ti int, blockAccessIndex uint32) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
|
|
@ -66,14 +67,14 @@ func TestBurn(t *testing.T) {
|
|||
createAndDestroy(addB)
|
||||
hooked.AddBalance(addA, uint256.NewInt(200), tracing.BalanceChangeUnspecified)
|
||||
hooked.AddBalance(addB, uint256.NewInt(200), tracing.BalanceChangeUnspecified)
|
||||
hooked.Finalise(true)
|
||||
hooked.Finalise(params.Rules{IsEIP158: true})
|
||||
|
||||
// Tx 2: create and destroy address C, then commit
|
||||
createAndDestroy(addC)
|
||||
hooked.AddBalance(addC, uint256.NewInt(200), tracing.BalanceChangeUnspecified)
|
||||
hooked.Finalise(true)
|
||||
hooked.Finalise(params.Rules{IsEIP158: true})
|
||||
|
||||
s.Commit(0, false, false)
|
||||
s.Commit(params.Rules{}, 0)
|
||||
if have, want := burned, uint256.NewInt(600); !have.Eq(want) {
|
||||
t.Fatalf("burn-count wrong, have %v want %v", have, want)
|
||||
}
|
||||
|
|
@ -160,7 +161,7 @@ func TestHooks_OnCodeChangeV2(t *testing.T) {
|
|||
sdb.SetCode(common.Address{0xbb}, []byte{0x13, 38}, tracing.CodeChangeContractCreation)
|
||||
sdb.CreateContract(common.Address{0xbb})
|
||||
sdb.SelfDestruct(common.Address{0xbb})
|
||||
sdb.Finalise(true)
|
||||
sdb.Finalise(params.Rules{IsEIP158: true})
|
||||
|
||||
if len(result) != len(wants) {
|
||||
t.Fatalf("number of tracing events wrong, have %d want %d", len(result), len(wants))
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||
|
|
@ -70,7 +71,7 @@ func TestUpdateLeaks(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
root := state.IntermediateRoot(false)
|
||||
root := state.IntermediateRoot(params.Rules{})
|
||||
if err := tdb.Commit(root, false); err != nil {
|
||||
t.Errorf("can not commit trie %v to persistent database", root.Hex())
|
||||
}
|
||||
|
|
@ -111,7 +112,7 @@ func TestIntermediateLeaks(t *testing.T) {
|
|||
modify(transState, common.Address{i}, i, 0)
|
||||
}
|
||||
// Write modifications to trie.
|
||||
transState.IntermediateRoot(false)
|
||||
transState.IntermediateRoot(params.Rules{})
|
||||
|
||||
// Overwrite all the data with new values in the transient database.
|
||||
for i := byte(0); i < 255; i++ {
|
||||
|
|
@ -120,7 +121,7 @@ func TestIntermediateLeaks(t *testing.T) {
|
|||
}
|
||||
|
||||
// Commit and cross check the databases.
|
||||
transRoot, err := transState.Commit(0, false, false)
|
||||
transRoot, err := transState.Commit(params.Rules{}, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to commit transition state: %v", err)
|
||||
}
|
||||
|
|
@ -128,7 +129,7 @@ func TestIntermediateLeaks(t *testing.T) {
|
|||
t.Errorf("can not commit trie %v to persistent database", transRoot.Hex())
|
||||
}
|
||||
|
||||
finalRoot, err := finalState.Commit(0, false, false)
|
||||
finalRoot, err := finalState.Commit(params.Rules{}, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to commit final state: %v", err)
|
||||
}
|
||||
|
|
@ -173,7 +174,7 @@ func TestCopy(t *testing.T) {
|
|||
obj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i}))
|
||||
obj.AddBalance(uint256.NewInt(uint64(i)))
|
||||
}
|
||||
orig.Finalise(false)
|
||||
orig.Finalise(params.Rules{})
|
||||
|
||||
// Copy the state
|
||||
copy := orig.Copy()
|
||||
|
|
@ -195,7 +196,7 @@ func TestCopy(t *testing.T) {
|
|||
// Finalise the changes on all concurrently
|
||||
finalise := func(wg *sync.WaitGroup, db *StateDB) {
|
||||
defer wg.Done()
|
||||
db.Finalise(true)
|
||||
db.Finalise(params.Rules{IsEIP158: true})
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
|
@ -235,7 +236,7 @@ func TestCopyWithDirtyJournal(t *testing.T) {
|
|||
obj.AddBalance(uint256.NewInt(uint64(i)))
|
||||
obj.data.Root = common.HexToHash("0xdeadbeef")
|
||||
}
|
||||
root, _ := orig.Commit(0, true, false)
|
||||
root, _ := orig.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
orig, _ = New(root, db)
|
||||
|
||||
// modify all in memory without finalizing
|
||||
|
|
@ -246,21 +247,21 @@ func TestCopyWithDirtyJournal(t *testing.T) {
|
|||
}
|
||||
cpy := orig.Copy()
|
||||
|
||||
orig.Finalise(true)
|
||||
orig.Finalise(params.Rules{IsEIP158: true})
|
||||
for i := byte(0); i < 255; i++ {
|
||||
balance := orig.GetBalance(common.BytesToAddress([]byte{i}))
|
||||
if !balance.IsZero() {
|
||||
t.Errorf("Unexpected balance %x", root)
|
||||
}
|
||||
}
|
||||
cpy.Finalise(true)
|
||||
cpy.Finalise(params.Rules{IsEIP158: true})
|
||||
for i := byte(0); i < 255; i++ {
|
||||
balance := cpy.GetBalance(common.BytesToAddress([]byte{i}))
|
||||
if !balance.IsZero() {
|
||||
t.Errorf("Unexpected balance %x", root)
|
||||
}
|
||||
}
|
||||
if cpy.IntermediateRoot(true) != orig.IntermediateRoot(true) {
|
||||
if cpy.IntermediateRoot(params.Rules{IsEIP158: true}) != orig.IntermediateRoot(params.Rules{IsEIP158: true}) {
|
||||
t.Error("State is not equal after copy")
|
||||
}
|
||||
}
|
||||
|
|
@ -278,14 +279,14 @@ func TestCopyObjectState(t *testing.T) {
|
|||
obj.AddBalance(uint256.NewInt(uint64(i)))
|
||||
obj.data.Root = common.HexToHash("0xdeadbeef")
|
||||
}
|
||||
orig.Finalise(true)
|
||||
orig.Finalise(params.Rules{IsEIP158: true})
|
||||
cpy := orig.Copy()
|
||||
for _, op := range cpy.mutations {
|
||||
if have, want := op.applied, false; have != want {
|
||||
t.Fatalf("Error in test itself, the 'done' flag should not be set before Commit, have %v want %v", have, want)
|
||||
}
|
||||
}
|
||||
orig.Commit(0, true, false)
|
||||
orig.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
for _, op := range cpy.mutations {
|
||||
if have, want := op.applied, false; have != want {
|
||||
t.Fatalf("Error: original state affected copy, have %v want %v", have, want)
|
||||
|
|
@ -690,7 +691,7 @@ func equalMutationSets(a, b map[common.Address]*journalMutationState) bool {
|
|||
func TestTouchDelete(t *testing.T) {
|
||||
s := newStateEnv()
|
||||
s.state.getOrNewStateObject(common.Address{})
|
||||
root, _ := s.state.Commit(0, false, false)
|
||||
root, _ := s.state.Commit(params.Rules{}, 0)
|
||||
s.state, _ = New(root, s.state.db)
|
||||
|
||||
snapshot := s.state.Snapshot()
|
||||
|
|
@ -820,7 +821,7 @@ func TestCopyCommitCopy(t *testing.T) {
|
|||
t.Fatalf("second copy committed storage slot mismatch: have %x, want %x", val, common.Hash{})
|
||||
}
|
||||
// Commit state, ensure states can be loaded from disk
|
||||
root, _ := state.Commit(0, false, false)
|
||||
root, _ := state.Commit(params.Rules{}, 0)
|
||||
state, _ = New(root, tdb)
|
||||
if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 {
|
||||
t.Fatalf("state post-commit balance mismatch: have %v, want %v", balance, 42)
|
||||
|
|
@ -934,11 +935,11 @@ func TestCommitCopy(t *testing.T) {
|
|||
if val := state.GetCommittedState(addr, skey1); val != (common.Hash{}) {
|
||||
t.Fatalf("initial committed storage slot mismatch: have %x, want %x", val, common.Hash{})
|
||||
}
|
||||
root, _ := state.Commit(0, true, false)
|
||||
root, _ := state.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
|
||||
state, _ = New(root, db)
|
||||
state.SetState(addr, skey2, sval2)
|
||||
state.Commit(1, true, false)
|
||||
state.Commit(params.Rules{IsEIP158: true}, 1)
|
||||
|
||||
// Copy the committed state database, the copied one is not fully functional.
|
||||
copied := state.Copy()
|
||||
|
|
@ -979,19 +980,19 @@ func TestDeleteCreateRevert(t *testing.T) {
|
|||
addr := common.BytesToAddress([]byte("so"))
|
||||
state.SetBalance(addr, uint256.NewInt(1), tracing.BalanceChangeUnspecified)
|
||||
|
||||
root, _ := state.Commit(0, false, false)
|
||||
root, _ := state.Commit(params.Rules{}, 0)
|
||||
state, _ = New(root, state.db)
|
||||
|
||||
// Simulate self-destructing in one transaction, then create-reverting in another
|
||||
state.SelfDestruct(addr)
|
||||
state.Finalise(true)
|
||||
state.Finalise(params.Rules{IsEIP158: true})
|
||||
|
||||
id := state.Snapshot()
|
||||
state.SetBalance(addr, uint256.NewInt(2), tracing.BalanceChangeUnspecified)
|
||||
state.RevertToSnapshot(id)
|
||||
|
||||
// Commit the entire state and make sure we don't crash and have the correct state
|
||||
root, _ = state.Commit(0, true, false)
|
||||
root, _ = state.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
state, _ = New(root, state.db)
|
||||
|
||||
if state.getStateObject(addr) != nil {
|
||||
|
|
@ -1006,7 +1007,7 @@ func TestWitnessIncludesAbsentAccountReads(t *testing.T) {
|
|||
addr := common.Address{i + 1}
|
||||
state.SetBalance(addr, uint256.NewInt(uint64(i+1)), tracing.BalanceChangeUnspecified)
|
||||
}
|
||||
root, err := state.Commit(0, false, false)
|
||||
root, err := state.Commit(params.Rules{}, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to commit initial state: %v", err)
|
||||
}
|
||||
|
|
@ -1027,7 +1028,7 @@ func TestWitnessIncludesAbsentAccountReads(t *testing.T) {
|
|||
if err := state.Error(); err != nil {
|
||||
t.Fatalf("unexpected state error after read: %v", err)
|
||||
}
|
||||
if got := state.IntermediateRoot(false); got != root {
|
||||
if got := state.IntermediateRoot(params.Rules{}); got != root {
|
||||
t.Fatalf("unexpected root after read-only access: have %x want %x", got, root)
|
||||
}
|
||||
if err := state.Error(); err != nil {
|
||||
|
|
@ -1075,7 +1076,7 @@ func testMissingTrieNodes(t *testing.T, scheme string) {
|
|||
a2 := common.BytesToAddress([]byte("another"))
|
||||
state.SetBalance(a2, uint256.NewInt(100), tracing.BalanceChangeUnspecified)
|
||||
state.SetCode(a2, []byte{1, 2, 4}, tracing.CodeChangeUnspecified)
|
||||
root, _ = state.Commit(0, false, false)
|
||||
root, _ = state.Commit(params.Rules{}, 0)
|
||||
t.Logf("root: %x", root)
|
||||
// force-flush
|
||||
tdb.Commit(root, false)
|
||||
|
|
@ -1106,7 +1107,7 @@ func testMissingTrieNodes(t *testing.T, scheme string) {
|
|||
}
|
||||
// Modify the state
|
||||
state.SetBalance(addr, uint256.NewInt(2), tracing.BalanceChangeUnspecified)
|
||||
root, err := state.Commit(0, false, false)
|
||||
root, err := state.Commit(params.Rules{}, 0)
|
||||
if err == nil {
|
||||
t.Fatalf("expected error, got root :%x", root)
|
||||
}
|
||||
|
|
@ -1297,7 +1298,7 @@ func TestFlushOrderDataLoss(t *testing.T) {
|
|||
state.SetState(common.Address{a}, common.Hash{a, s}, common.Hash{a, s})
|
||||
}
|
||||
}
|
||||
root, err := state.Commit(0, false, false)
|
||||
root, err := state.Commit(params.Rules{}, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to commit state trie: %v", err)
|
||||
}
|
||||
|
|
@ -1372,7 +1373,7 @@ func TestDeleteStorage(t *testing.T) {
|
|||
value := common.Hash(uint256.NewInt(uint64(10 * i)).Bytes32())
|
||||
state.SetState(addr, slot, value)
|
||||
}
|
||||
root, _ := state.Commit(0, true, false)
|
||||
root, _ := state.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
// Init phase done, create two states, one with snap and one without
|
||||
fastState, _ := New(root, NewMPTDatabase(tdb, nil).WithSnapshot(snaps))
|
||||
slowState, _ := New(root, NewMPTDatabase(tdb, nil))
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
"github.com/ethereum/go-ethereum/triedb"
|
||||
|
|
@ -81,7 +82,7 @@ func makeTestState(scheme string) (ethdb.Database, Database, *triedb.Database, c
|
|||
}
|
||||
accounts = append(accounts, acc)
|
||||
}
|
||||
root, _ := state.Commit(0, false, false)
|
||||
root, _ := state.Commit(params.Rules{}, 0)
|
||||
|
||||
// Return the generated state
|
||||
return db, sdb, nodeDb, root, accounts
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/internal/testrand"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/triedb"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
|
@ -83,7 +84,7 @@ func TestVerklePrefetcher(t *testing.T) {
|
|||
state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) // Change the account trie
|
||||
state.SetCode(addr, []byte("hello"), tracing.CodeChangeUnspecified) // Change an external metadata
|
||||
state.SetState(addr, skey, sval) // Change the storage trie
|
||||
root, _ := state.Commit(0, true, false)
|
||||
root, _ := state.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
|
||||
state, _ = New(root, sdb)
|
||||
fetcher := newTriePrefetcher(sdb, root, "", false)
|
||||
|
|
|
|||
|
|
@ -232,9 +232,9 @@ func ApplyTransactionWithEVM(msg *Message, gp *GasPool, statedb *state.StateDB,
|
|||
// Update the state with pending changes.
|
||||
var root []byte
|
||||
if evm.ChainConfig().IsByzantium(blockNumber) {
|
||||
bal = evm.StateDB.Finalise(true)
|
||||
bal = evm.StateDB.Finalise(evm.GetRules())
|
||||
} else {
|
||||
root = statedb.IntermediateRoot(evm.ChainConfig().IsEIP158(blockNumber)).Bytes()
|
||||
root = statedb.IntermediateRoot(evm.GetRules()).Bytes()
|
||||
}
|
||||
// Merge the tx-local access event into the "block-local" one, in order to collect
|
||||
// all values, so that the witness can be built.
|
||||
|
|
@ -337,7 +337,7 @@ func ProcessBeaconBlockRoot(beaconRoot common.Hash, evm *vm.EVM, blockAccessList
|
|||
if evm.StateDB.AccessEvents() != nil {
|
||||
evm.StateDB.AccessEvents().Merge(evm.AccessEvents)
|
||||
}
|
||||
blockAccessList.Merge(evm.StateDB.Finalise(true))
|
||||
blockAccessList.Merge(evm.StateDB.Finalise(evm.GetRules()))
|
||||
}
|
||||
|
||||
// ProcessParentBlockHash stores the parent block hash in the history storage contract
|
||||
|
|
@ -370,7 +370,7 @@ func ProcessParentBlockHash(prevHash common.Hash, evm *vm.EVM, blockAccessList *
|
|||
if evm.StateDB.AccessEvents() != nil {
|
||||
evm.StateDB.AccessEvents().Merge(evm.AccessEvents)
|
||||
}
|
||||
blockAccessList.Merge(evm.StateDB.Finalise(true))
|
||||
blockAccessList.Merge(evm.StateDB.Finalise(evm.GetRules()))
|
||||
}
|
||||
|
||||
// ProcessWithdrawalQueue calls the EIP-7002 withdrawal queue contract.
|
||||
|
|
@ -414,14 +414,14 @@ func processRequestsSystemCall(requests *[][]byte, rules params.Rules, evm *vm.E
|
|||
To: &addr,
|
||||
}
|
||||
evm.SetTxContext(NewEVMTxContext(msg))
|
||||
evm.StateDB.Prepare(rules, common.Address{}, common.Address{}, nil, nil, nil)
|
||||
evm.StateDB.Prepare(evm.GetRules(), common.Address{}, common.Address{}, nil, nil, nil)
|
||||
evm.StateDB.SetTxContext(common.Hash{}, 0, blockAccessIndex)
|
||||
evm.StateDB.AddAddressToAccessList(addr)
|
||||
ret, _, err := evm.Call(msg.From, *msg.To, msg.Data, gasBudget, common.U2560)
|
||||
if evm.StateDB.AccessEvents() != nil {
|
||||
evm.StateDB.AccessEvents().Merge(evm.AccessEvents)
|
||||
}
|
||||
bal := evm.StateDB.Finalise(true)
|
||||
bal := evm.StateDB.Finalise(evm.GetRules())
|
||||
if err != nil {
|
||||
return fmt.Errorf("system call failed to execute: %v", err)
|
||||
}
|
||||
|
|
@ -471,9 +471,10 @@ func onSystemCallStart(tracer *tracing.Hooks, ctx *tracing.VMContext) {
|
|||
// body and receipts.
|
||||
func AssembleBlock(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, body *types.Body, receipts []*types.Receipt, blockAccessList *bal.ConstructionBlockAccessList) *types.Block {
|
||||
// Assign the post-transition state root
|
||||
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
|
||||
rules := chain.Config().Rules(header.Number, header.Difficulty.Sign() == 0, header.Time)
|
||||
header.Root = state.IntermediateRoot(rules)
|
||||
|
||||
if !chain.Config().IsAmsterdam(header.Number, header.Time) {
|
||||
if !rules.IsAmsterdam {
|
||||
return types.NewBlock(header, body, receipts, trie.NewStackTrie(nil))
|
||||
}
|
||||
// Assign the BlockAccessListHash if Amsterdam has been enabled
|
||||
|
|
|
|||
|
|
@ -105,7 +105,6 @@ func (p *StateProcessor) processParallel(ctx context.Context, block *types.Block
|
|||
// blockAccessList is the access list rebuilt from the actual execution.
|
||||
blockAccessList = bal.NewConstructionBlockAccessList()
|
||||
)
|
||||
|
||||
// Resolve the parent state root, the point all execution reads from.
|
||||
parent := p.chain.GetHeader(block.ParentHash(), block.NumberU64()-1)
|
||||
if parent == nil {
|
||||
|
|
@ -135,7 +134,7 @@ func (p *StateProcessor) processParallel(ctx context.Context, block *types.Block
|
|||
stateApply = time.Since(start)
|
||||
|
||||
start = time.Now()
|
||||
statedb.IntermediateRoot(config.IsEIP158(header.Number))
|
||||
statedb.IntermediateRoot(config.Rules(header.Number, header.Difficulty.Sign() == 0, header.Time))
|
||||
stateHash = time.Since(start)
|
||||
return statedb.Error()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -77,6 +77,6 @@ func ExecuteStateless(ctx context.Context, config *params.ChainConfig, vmconfig
|
|||
}
|
||||
// Almost everything validated, but receipt and state root needs to be returned
|
||||
receiptRoot := types.DeriveSha(res.Receipts, trie.NewStackTrie(nil))
|
||||
stateRoot := db.IntermediateRoot(config.IsEIP158(block.Number()))
|
||||
stateRoot := db.IntermediateRoot(config.Rules(block.Number(), block.Difficulty().Sign() == 0, block.Time()))
|
||||
return stateRoot, receiptRoot, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -727,7 +727,7 @@ func TestOpenDrops(t *testing.T) {
|
|||
statedb.AddBalance(crypto.PubkeyToAddress(overcapper.PublicKey), uint256.NewInt(10000000), tracing.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(duplicater.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(crypto.PubkeyToAddress(repeater.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified)
|
||||
statedb.Commit(0, true, false)
|
||||
statedb.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
|
||||
chain := &testBlockChain{
|
||||
config: params.MainnetChainConfig,
|
||||
|
|
@ -847,7 +847,7 @@ func TestOpenIndex(t *testing.T) {
|
|||
// Create a blob pool out of the pre-seeded data
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||
statedb.AddBalance(addr, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.Commit(0, true, false)
|
||||
statedb.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
|
||||
chain := &testBlockChain{
|
||||
config: params.MainnetChainConfig,
|
||||
|
|
@ -948,7 +948,7 @@ func TestOpenHeap(t *testing.T) {
|
|||
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.Commit(0, true, false)
|
||||
statedb.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
|
||||
chain := &testBlockChain{
|
||||
config: params.MainnetChainConfig,
|
||||
|
|
@ -1030,7 +1030,7 @@ func TestOpenCap(t *testing.T) {
|
|||
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.Commit(0, true, false)
|
||||
statedb.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
|
||||
chain := &testBlockChain{
|
||||
config: params.MainnetChainConfig,
|
||||
|
|
@ -1116,7 +1116,7 @@ func TestChangingSlotterSize(t *testing.T) {
|
|||
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.Commit(0, true, false)
|
||||
statedb.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
|
||||
// Make custom chain config where the max blob count changes based on the loop variable.
|
||||
cancunTime := uint64(0)
|
||||
|
|
@ -1219,7 +1219,7 @@ func TestBillyMigration(t *testing.T) {
|
|||
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.Commit(0, true, false)
|
||||
statedb.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
|
||||
// Make custom chain config where the max blob count changes based on the loop variable.
|
||||
zero := uint64(0)
|
||||
|
|
@ -1316,7 +1316,7 @@ func TestLegacyTxConversion(t *testing.T) {
|
|||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.Commit(0, true, false)
|
||||
statedb.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
|
||||
chain := &testBlockChain{
|
||||
config: params.MainnetChainConfig,
|
||||
|
|
@ -1390,7 +1390,7 @@ func TestLegacyLimboConversion(t *testing.T) {
|
|||
store.Close()
|
||||
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||
statedb.Commit(0, true, false)
|
||||
statedb.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
chain := &testBlockChain{
|
||||
config: params.MainnetChainConfig,
|
||||
basefee: uint256.NewInt(params.InitialBaseFee),
|
||||
|
|
@ -1445,7 +1445,7 @@ func TestBlobCountLimit(t *testing.T) {
|
|||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.Commit(0, true, false)
|
||||
statedb.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
|
||||
// Make Prague-enabled custom chain config.
|
||||
cancunTime := uint64(0)
|
||||
|
|
@ -1901,7 +1901,7 @@ func TestAdd(t *testing.T) {
|
|||
store.Put(blob)
|
||||
}
|
||||
}
|
||||
statedb.Commit(0, true, false)
|
||||
statedb.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
store.Close()
|
||||
|
||||
// Create a blob pool out of the pre-seeded dats
|
||||
|
|
@ -2023,7 +2023,7 @@ func TestGetBlobs(t *testing.T) {
|
|||
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.Commit(0, true, false)
|
||||
statedb.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
|
||||
// Make custom chain config where the max blob count changes based on the loop variable.
|
||||
cancunTime := uint64(0)
|
||||
|
|
@ -2307,7 +2307,7 @@ func benchmarkPoolPending(b *testing.B, datacap uint64) {
|
|||
pooledTx, _ := newBlobTxForPool(tx)
|
||||
pool.AddPooledTx(pooledTx)
|
||||
}
|
||||
statedb.Commit(0, true, false)
|
||||
statedb.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
defer pool.Close()
|
||||
|
||||
// Benchmark assembling the pending
|
||||
|
|
@ -2350,7 +2350,7 @@ func TestGetCells(t *testing.T) {
|
|||
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
statedb.Commit(0, true, false)
|
||||
statedb.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
|
||||
chain := &testBlockChain{
|
||||
config: params.MainnetChainConfig,
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ func newTestCache(t *testing.T, txConfig []txSpec) *testCache {
|
|||
for _, a := range addrs {
|
||||
statedb.AddBalance(a, uint256.NewInt(1_000_000_000_000), tracing.BalanceChangeUnspecified)
|
||||
}
|
||||
statedb.Commit(0, true, false)
|
||||
statedb.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
|
||||
cancunTime := uint64(0)
|
||||
config := ¶ms.ChainConfig{
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ func run8037(t *testing.T, code []byte, gas GasBudget, value *uint256.Int, setup
|
|||
if setup != nil {
|
||||
setup(statedb, self)
|
||||
}
|
||||
statedb.Finalise(true)
|
||||
statedb.Finalise(params.Rules{IsEIP158: true})
|
||||
ret, result, err := amsterdam8037EVM(statedb).Call(common.Address{}, self, nil, gas, value)
|
||||
assertBudgetSane(t, gas, result)
|
||||
return ret, result, err
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ func run8038(t *testing.T, code []byte, gas GasBudget, value *uint256.Int, setup
|
|||
if setup != nil {
|
||||
setup(statedb, self)
|
||||
}
|
||||
statedb.Finalise(true)
|
||||
statedb.Finalise(params.Rules{IsEIP158: true})
|
||||
_, result, err := amsterdam8037EVM(statedb).Call(common.Address{}, self, nil, gas, value)
|
||||
return result, statedb.GetRefund(), err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ func TestEIP2200(t *testing.T) {
|
|||
statedb.CreateAccount(address)
|
||||
statedb.SetCode(address, hexutil.MustDecode(tt.input), tracing.CodeChangeUnspecified)
|
||||
statedb.SetState(address, common.Hash{}, common.BytesToHash([]byte{tt.original}))
|
||||
statedb.Finalise(true) // Push the state into the "original" slot
|
||||
statedb.Finalise(params.Rules{IsEIP158: true}) // Push the state into the "original" slot
|
||||
|
||||
vmctx := BlockContext{
|
||||
CanTransfer: func(StateDB, common.Address, *uint256.Int) bool { return true },
|
||||
|
|
@ -141,7 +141,7 @@ func TestCreateGas(t *testing.T) {
|
|||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||
statedb.CreateAccount(address)
|
||||
statedb.SetCode(address, hexutil.MustDecode(tt.code), tracing.CodeChangeUnspecified)
|
||||
statedb.Finalise(true)
|
||||
statedb.Finalise(params.Rules{IsEIP158: true})
|
||||
vmctx := BlockContext{
|
||||
CanTransfer: func(StateDB, common.Address, *uint256.Int) bool { return true },
|
||||
Transfer: func(StateDB, common.Address, common.Address, *uint256.Int, *params.Rules) {},
|
||||
|
|
|
|||
|
|
@ -99,6 +99,6 @@ type StateDB interface {
|
|||
AccessEvents() *state.AccessEvents
|
||||
|
||||
// Finalise must be invoked at the end of a transaction
|
||||
Finalise(bool) *bal.ConstructionBlockAccessList
|
||||
Finalise(rules params.Rules) *bal.ConstructionBlockAccessList
|
||||
SetTxContext(thash common.Hash, ti int, blockAccessIndex uint32)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ func TestLoopInterrupt(t *testing.T) {
|
|||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||
statedb.CreateAccount(address)
|
||||
statedb.SetCode(address, common.Hex2Bytes(tt), tracing.CodeChangeUnspecified)
|
||||
statedb.Finalise(true)
|
||||
statedb.Finalise(params.Rules{IsEIP158: true})
|
||||
|
||||
evm := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, Config{})
|
||||
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
|||
var (
|
||||
address = common.BytesToAddress([]byte("contract"))
|
||||
vmenv = NewEnv(cfg)
|
||||
rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time)
|
||||
rules = cfg.ChainConfig.Rules(cfg.BlockNumber, cfg.Random != nil, cfg.Time)
|
||||
)
|
||||
if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxStart != nil {
|
||||
cfg.EVMConfig.Tracer.OnTxStart(vmenv.GetVMContext(), types.NewTx(&types.LegacyTx{To: &address, Data: input, Value: cfg.Value, Gas: cfg.GasLimit}), cfg.Origin)
|
||||
|
|
@ -173,7 +173,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
|
|||
}
|
||||
var (
|
||||
vmenv = NewEnv(cfg)
|
||||
rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Random != nil, vmenv.Context.Time)
|
||||
rules = cfg.ChainConfig.Rules(cfg.BlockNumber, cfg.Random != nil, cfg.Time)
|
||||
)
|
||||
if cfg.EVMConfig.Tracer != nil && cfg.EVMConfig.Tracer.OnTxStart != nil {
|
||||
cfg.EVMConfig.Tracer.OnTxStart(vmenv.GetVMContext(), types.NewTx(&types.LegacyTx{Data: input, Value: cfg.Value, Gas: cfg.GasLimit}), cfg.Origin)
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ func (api *DebugAPI) replayBuild(ctx context.Context, block *types.Block, stated
|
|||
Withdrawals: block.Withdrawals(),
|
||||
}
|
||||
bc.Engine().Finalize(bc, header, statedb, &body, uint32(tcount+1), blockAL)
|
||||
root := statedb.IntermediateRoot(config.IsEIP158(header.Number))
|
||||
root := statedb.IntermediateRoot(evm.GetRules())
|
||||
|
||||
return blockAL.ToEncodingObj(), receipts, gp.Used(), root, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ func TestAccountRange(t *testing.T) {
|
|||
m[addr] = true
|
||||
}
|
||||
}
|
||||
root, _ := sdb.Commit(0, true, false)
|
||||
root, _ := sdb.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
sdb, _ = state.New(root, statedb)
|
||||
|
||||
trie, err := statedb.OpenTrie(root)
|
||||
|
|
@ -192,7 +192,7 @@ func TestEmptyAccountRange(t *testing.T) {
|
|||
st, _ = state.New(types.EmptyRootHash, statedb)
|
||||
)
|
||||
// Commit(although nothing to flush) and re-init the statedb
|
||||
st.Commit(0, true, false)
|
||||
st.Commit(params.Rules{IsEIP158: true}, 0)
|
||||
st, _ = state.New(types.EmptyRootHash, statedb)
|
||||
|
||||
results := st.RawDump(&state.DumpConfig{
|
||||
|
|
@ -235,7 +235,7 @@ func TestStorageRangeAt(t *testing.T) {
|
|||
for _, entry := range storage {
|
||||
sdb.SetState(addr, *entry.Key, entry.Value)
|
||||
}
|
||||
root, _ := sdb.Commit(0, false, false)
|
||||
root, _ := sdb.Commit(params.Rules{}, 0)
|
||||
sdb, _ = state.New(root, db)
|
||||
|
||||
// Check a few combinations of limit and start/end.
|
||||
|
|
|
|||
|
|
@ -156,7 +156,8 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, base *st
|
|||
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(current.NumberU64(), eth.blockchain.Config().IsEIP158(current.Number()), eth.blockchain.Config().IsCancun(current.Number(), current.Time()))
|
||||
rules := eth.blockchain.Config().Rules(current.Number(), current.Difficulty().Sign() == 0, current.Time())
|
||||
root, err := statedb.Commit(rules, current.NumberU64())
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("stateAtBlock commit failed, number %d root %v: %w",
|
||||
current.NumberU64(), current.Root().Hex(), err)
|
||||
|
|
@ -270,8 +271,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
|
|||
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
||||
}
|
||||
// Ensure any modifications are committed to the state
|
||||
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
|
||||
statedb.Finalise(evm.ChainConfig().IsEIP158(block.Number()))
|
||||
statedb.Finalise(evm.GetRules())
|
||||
}
|
||||
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -514,12 +514,12 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
|
|||
defer release()
|
||||
|
||||
var (
|
||||
roots []common.Hash
|
||||
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
|
||||
chainConfig = api.backend.ChainConfig()
|
||||
vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
||||
deleteEmptyObjects = chainConfig.IsEIP158(block.Number())
|
||||
evm = vm.NewEVM(vmctx, statedb, chainConfig, vm.Config{})
|
||||
roots []common.Hash
|
||||
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
|
||||
chainConfig = api.backend.ChainConfig()
|
||||
rules = chainConfig.Rules(block.Number(), block.Difficulty().Sign() == 0, block.Time())
|
||||
vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
||||
evm = vm.NewEVM(vmctx, statedb, chainConfig, vm.Config{})
|
||||
)
|
||||
defer evm.Release()
|
||||
// Run pre-execution system calls
|
||||
|
|
@ -543,7 +543,7 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
|
|||
}
|
||||
// Calling IntermediateRoot will internally call Finalize on the state
|
||||
// so any modifications are written to the trie
|
||||
roots = append(roots, statedb.IntermediateRoot(deleteEmptyObjects))
|
||||
roots = append(roots, statedb.IntermediateRoot(rules))
|
||||
}
|
||||
return roots, nil
|
||||
}
|
||||
|
|
@ -687,8 +687,7 @@ txloop:
|
|||
break txloop
|
||||
}
|
||||
// Finalize the state so any modifications are written to the trie
|
||||
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
|
||||
statedb.Finalise(evm.ChainConfig().IsEIP158(block.Number()))
|
||||
statedb.Finalise(evm.GetRules())
|
||||
}
|
||||
|
||||
close(jobs)
|
||||
|
|
@ -766,8 +765,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
|
|||
return dumps, err
|
||||
}
|
||||
// Finalize the state so any modifications are written to the trie
|
||||
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
|
||||
statedb.Finalise(evm.ChainConfig().IsEIP158(block.Number()))
|
||||
statedb.Finalise(evm.GetRules())
|
||||
continue
|
||||
}
|
||||
// The transaction should be traced.
|
||||
|
|
@ -810,8 +808,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
|
|||
return dumps, err
|
||||
}
|
||||
// Finalize the state so any modifications are written to the trie
|
||||
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
|
||||
statedb.Finalise(chainConfig.IsEIP158(block.Number()))
|
||||
statedb.Finalise(evm.GetRules())
|
||||
|
||||
// If we've traced the transaction we were looking for, abort
|
||||
if tx.Hash() == txHash {
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block
|
|||
if _, err := core.ApplyMessage(evm, msg, nil); err != nil {
|
||||
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
||||
}
|
||||
statedb.Finalise(evm.ChainConfig().IsEIP158(block.Number()))
|
||||
statedb.Finalise(evm.GetRules())
|
||||
}
|
||||
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
|
|
@ -121,7 +122,7 @@ func (diff *StateOverride) Apply(statedb *state.StateDB, precompiles vm.Precompi
|
|||
// Now finalize the changes. Finalize is normally performed between transactions.
|
||||
// By using finalize, the overrides are semantically behaving as
|
||||
// if they were created in a transaction just before the tracing occur.
|
||||
statedb.Finalise(false)
|
||||
statedb.Finalise(params.Rules{})
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -353,9 +353,9 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
|
|||
// Update the state with pending changes.
|
||||
var root []byte
|
||||
if sim.chainConfig.IsByzantium(blockContext.BlockNumber) {
|
||||
blockAccessList.Merge(tracingStateDB.Finalise(true))
|
||||
blockAccessList.Merge(tracingStateDB.Finalise(evm.GetRules()))
|
||||
} else {
|
||||
root = sim.state.IntermediateRoot(sim.chainConfig.IsEIP158(blockContext.BlockNumber)).Bytes()
|
||||
root = sim.state.IntermediateRoot(evm.GetRules()).Bytes()
|
||||
}
|
||||
receipts[i] = core.MakeReceipt(evm, result, sim.state, blockContext.BlockNumber, common.Hash{}, blockContext.Time, tx, gp.CumulativeUsed(), root)
|
||||
blobGasUsed += receipts[i].BlobGasUsed
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/eth/tracers/logger"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
func initMatcher(st *testMatcher) {
|
||||
|
|
@ -135,7 +136,7 @@ func execStateTest(t *testing.T, st *testMatcher, test *StateTest) {
|
|||
var result error
|
||||
test.Run(subtest, vmconfig, true, rawdb.HashScheme, func(err error, state *StateTestState) {
|
||||
if state.Snapshots != nil && state.StateDB != nil {
|
||||
if _, err := state.Snapshots.Journal(state.StateDB.IntermediateRoot(false)); err != nil {
|
||||
if _, err := state.Snapshots.Journal(state.StateDB.IntermediateRoot(params.Rules{})); err != nil {
|
||||
result = err
|
||||
return
|
||||
}
|
||||
|
|
@ -165,7 +166,7 @@ func execStateTest(t *testing.T, st *testMatcher, test *StateTest) {
|
|||
var result error
|
||||
test.Run(subtest, vmconfig, true, rawdb.PathScheme, func(err error, state *StateTestState) {
|
||||
if state.TrieDB != nil && state.StateDB != nil {
|
||||
if err := state.TrieDB.Journal(state.StateDB.IntermediateRoot(false)); err != nil {
|
||||
if err := state.TrieDB.Journal(state.StateDB.IntermediateRoot(params.Rules{})); err != nil {
|
||||
result = err
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -245,7 +245,9 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config, snapshotter bo
|
|||
if err != nil {
|
||||
return fmt.Errorf("failed to get chain config: %w", err)
|
||||
}
|
||||
root = st.StateDB.IntermediateRoot(config.IsEIP158(new(big.Int).SetUint64(t.json.Env.Number)))
|
||||
number := new(big.Int).SetUint64(t.json.Env.Number)
|
||||
isMerge := config.IsLondon(new(big.Int)) && t.json.Env.Random != nil
|
||||
root = st.StateDB.IntermediateRoot(config.Rules(number, isMerge, t.json.Env.Timestamp))
|
||||
if root != common.Hash(post.Root) {
|
||||
return fmt.Errorf("post-state root does not match the pre-state root, indicates an error in the test: got %x, want %x", root, post.Root)
|
||||
}
|
||||
|
|
@ -275,6 +277,10 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
|
|||
vmconfig.ExtraEips = eips
|
||||
|
||||
block := t.genesis(config).ToBlock()
|
||||
// The env's random is what makes the block post-merge; it is mirrored into the
|
||||
// block context below.
|
||||
isMerge := config.IsLondon(new(big.Int)) && t.json.Env.Random != nil
|
||||
rules := config.Rules(block.Number(), isMerge, block.Time())
|
||||
st = MakePreState(rawdb.NewMemoryDatabase(), t.json.Pre, snapshotter, scheme)
|
||||
|
||||
var baseFee *big.Int
|
||||
|
|
@ -324,7 +330,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
|
|||
if t.json.Env.Difficulty != nil {
|
||||
context.Difficulty = new(big.Int).Set(t.json.Env.Difficulty)
|
||||
}
|
||||
if config.IsLondon(new(big.Int)) && t.json.Env.Random != nil {
|
||||
if isMerge {
|
||||
rnd := common.BigToHash(t.json.Env.Random)
|
||||
context.Random = &rnd
|
||||
context.Difficulty = big.NewInt(0)
|
||||
|
|
@ -360,7 +366,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
|
|||
st.StateDB.AddBalance(block.Coinbase(), new(uint256.Int), tracing.BalanceChangeUnspecified)
|
||||
|
||||
// Commit state mutations into database.
|
||||
root, _ = st.StateDB.Commit(block.NumberU64(), config.IsEIP158(block.Number()), config.IsCancun(block.Number(), block.Time()))
|
||||
root, _ = st.StateDB.Commit(rules, block.NumberU64())
|
||||
if tracer := evm.Config.Tracer; tracer != nil && tracer.OnTxEnd != nil {
|
||||
receipt := &types.Receipt{GasUsed: vmRet.UsedGas}
|
||||
tracer.OnTxEnd(receipt, nil)
|
||||
|
|
@ -544,7 +550,8 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bo
|
|||
}
|
||||
}
|
||||
// Commit and re-open to start with a clean state.
|
||||
root, _ := statedb.Commit(0, false, false)
|
||||
// Materialising the alloc is not a fork-governed state transition.
|
||||
root, _ := statedb.Commit(params.Rules{}, 0)
|
||||
|
||||
// If snapshot is requested, initialize the snapshotter and use it in state.
|
||||
var snaps *snapshot.Tree
|
||||
|
|
|
|||
Loading…
Reference in a new issue