diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index bc807f7af6..b166d3ff88 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -200,8 +200,9 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, var ( prevNumber = pre.Env.Number - 1 prevHash = pre.Env.BlockHashes[math.HexOrDecimal64(prevNumber)] + evm = vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vmConfig) ) - core.ProcessParentBlockHash(statedb, prevHash, prevNumber) + core.ProcessParentBlockHash(statedb, evm, prevHash, prevNumber) } for i := 0; txIt.Next(); i++ { tx, err := txIt.Tx() diff --git a/core/state_processor.go b/core/state_processor.go index 66c10c627c..b2f97ca5ce 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -17,7 +17,6 @@ package core import ( - "encoding/binary" "errors" "fmt" "math/big" @@ -83,7 +82,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg } if p.config.IsPrague(block.Number(), block.Time()) { // This should not underflow as genesis block is not processed. - ProcessParentBlockHash(statedb, block.ParentHash(), block.NumberU64()-1) + ProcessParentBlockHash(statedb, vmenv, block.ParentHash(), block.NumberU64()-1) } // Iterate over and process the individual transactions for i, tx := range block.Transactions() { @@ -217,9 +216,25 @@ func ProcessBeaconBlockRoot(beaconRoot common.Hash, vmenv *vm.EVM, statedb *stat // ProcessParentBlockHash stores the parent block hash in the history storage contract // as per EIP-2935. -func ProcessParentBlockHash(statedb *state.StateDB, prevHash common.Hash, prevNumber uint64) { - ringIndex := prevNumber % params.HistoryServeWindow - var key common.Hash - binary.BigEndian.PutUint64(key[24:], ringIndex) - statedb.SetState(params.HistoryStorageAddress, key, prevHash) +func ProcessParentBlockHash(statedb *state.StateDB, vmenv *vm.EVM, prevHash common.Hash) { + if vmenv.Config.Tracer != nil && vmenv.Config.Tracer.OnSystemCallStart != nil { + vmenv.Config.Tracer.OnSystemCallStart() + } + if vmenv.Config.Tracer != nil && vmenv.Config.Tracer.OnSystemCallEnd != nil { + defer vmenv.Config.Tracer.OnSystemCallEnd() + } + + msg := &Message{ + From: params.SystemAddress, + GasLimit: 30_000_000, + GasPrice: common.Big0, + GasFeeCap: common.Big0, + GasTipCap: common.Big0, + To: ¶ms.HistoryStorageAddress, + Data: prevHash.Bytes(), + } + vmenv.Reset(NewEVMTxContext(msg), statedb) + statedb.AddAddressToAccessList(params.HistoryStorageAddress) + _, _, _ = vmenv.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560) + statedb.Finalise(true) } diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 7beda2764b..2ce4698966 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -534,23 +534,33 @@ func TestProcessVerkle(t *testing.T) { func TestProcessParentBlockHash(t *testing.T) { var ( - statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil) - hashA = common.Hash{0x01} - hashB = common.Hash{0x02} - header = &types.Header{ParentHash: hashA, Number: big.NewInt(2)} - parent = &types.Header{ParentHash: hashB, Number: big.NewInt(1)} - genesis = &types.Header{ParentHash: common.Hash{}, Number: big.NewInt(0)} + chainConfig = params.MergedTestChainConfig + statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil) + hashA = common.Hash{0x01} + hashB = common.Hash{0x02} + header = &types.Header{ParentHash: hashA, Number: big.NewInt(2), Difficulty: big.NewInt(0)} + parent = &types.Header{ParentHash: hashB, Number: big.NewInt(1), Difficulty: big.NewInt(0)} + genesis = &types.Header{ParentHash: common.Hash{}, Number: big.NewInt(0)} + coinbase = common.Address{} ) + statedb.SetNonce(params.HistoryStorageAddress, 1) + statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode) + statedb.IntermediateRoot(true) - ProcessParentBlockHash(statedb, header.ParentHash, parent.Number.Uint64()) - ProcessParentBlockHash(statedb, parent.ParentHash, genesis.Number.Uint64()) + vmContext := NewEVMBlockContext(header, nil, &coinbase) + evm := vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vm.Config{}) + ProcessParentBlockHash(statedb, evm, header.ParentHash, parent.Number.Uint64()) + + vmContext = NewEVMBlockContext(parent, nil, &coinbase) + evm = vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vm.Config{}) + ProcessParentBlockHash(statedb, evm, parent.ParentHash, genesis.Number.Uint64()) // make sure that the state is correct if have := getParentBlockHash(statedb, 1); have != hashA { - t.Fail() + t.Errorf("expected parent hash %v, got %v", hashA, have) } if have := getParentBlockHash(statedb, 0); have != hashB { - t.Fail() + t.Errorf("expected parent hash %v, got %v", hashB, have) } }