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