diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 659a6ef43f..9f30d7ba6c 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -23,6 +23,7 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/consensus/misc" @@ -50,6 +51,8 @@ type Prestate struct { Pre types.GenesisAlloc `json:"pre"` } +//go:generate go run github.com/fjl/gencodec -type ExecutionResult -field-override executionResultMarshaling -out gen_execresult.go + // ExecutionResult contains the execution status after running a state test, any // error that might have occurred and a dump of the final state if requested. type ExecutionResult struct { @@ -70,6 +73,10 @@ type ExecutionResult struct { Requests [][]byte `json:"requests,omitempty"` } +type executionResultMarshaling struct { + Requests []hexutil.Bytes `json:"requests,omitempty"` +} + type ommer struct { Delta uint64 `json:"delta"` Address common.Address `json:"address"` @@ -354,6 +361,28 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, amount := new(big.Int).Mul(new(big.Int).SetUint64(w.Amount), big.NewInt(params.GWei)) statedb.AddBalance(w.Address, uint256.MustFromBig(amount), tracing.BalanceIncreaseWithdrawal) } + + // Gather the execution-layer triggered requests. + var requests [][]byte + if chainConfig.IsPrague(vmContext.BlockNumber, vmContext.Time) { + // EIP-6110 deposits + var allLogs []*types.Log + for _, receipt := range receipts { + allLogs = append(allLogs, receipt.Logs...) + } + depositRequests, err := core.ParseDepositLogs(allLogs, chainConfig) + if err != nil { + return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not parse requests logs: %v", err)) + } + requests = append(requests, depositRequests) + // create EVM for system calls + vmenv := vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vm.Config{}) + // EIP-7002 withdrawals + requests = append(requests, core.ProcessWithdrawalQueue(vmenv, statedb)) + // EIP-7251 consolidations + requests = append(requests, core.ProcessConsolidationQueue(vmenv, statedb)) + } + // Commit block root, err := statedb.Commit(vmContext.BlockNumber.Uint64(), chainConfig.IsEIP158(vmContext.BlockNumber)) if err != nil { @@ -379,32 +408,14 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, execRs.CurrentExcessBlobGas = (*math.HexOrDecimal64)(&excessBlobGas) execRs.CurrentBlobGasUsed = (*math.HexOrDecimal64)(&blobGasUsed) } - - var requests [][]byte - if chainConfig.IsPrague(vmContext.BlockNumber, vmContext.Time) { - // EIP-6110 deposits - var allLogs []*types.Log - for _, receipt := range receipts { - allLogs = append(allLogs, receipt.Logs...) - } - depositRequests, err := core.ParseDepositLogs(allLogs, chainConfig) - if err != nil { - return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not parse requests logs: %v", err)) - } - requests = append(requests, depositRequests) - // create EVM for system calls - vmenv := vm.NewEVM(vmContext, vm.TxContext{}, statedb, chainConfig, vm.Config{}) - // EIP-7002 withdrawals - withdrawalRequests := core.ProcessWithdrawalQueue(vmenv, statedb) - requests = append(requests, withdrawalRequests) - // EIP-7251 consolidations - consolidationRequests := core.ProcessConsolidationQueue(vmenv, statedb) - requests = append(requests, consolidationRequests) - } if requests != nil { // Set requestsHash on block. h := types.CalcRequestsHash(requests) execRs.RequestsHash = &h + for i := range requests { + // remove prefix + requests[i] = requests[i][1:] + } execRs.Requests = requests } diff --git a/cmd/evm/internal/t8ntool/gen_execresult.go b/cmd/evm/internal/t8ntool/gen_execresult.go new file mode 100644 index 0000000000..0da94f5ca2 --- /dev/null +++ b/cmd/evm/internal/t8ntool/gen_execresult.go @@ -0,0 +1,134 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package t8ntool + +import ( + "encoding/json" + "errors" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/types" +) + +var _ = (*executionResultMarshaling)(nil) + +// MarshalJSON marshals as JSON. +func (e ExecutionResult) MarshalJSON() ([]byte, error) { + type ExecutionResult struct { + StateRoot common.Hash `json:"stateRoot"` + TxRoot common.Hash `json:"txRoot"` + ReceiptRoot common.Hash `json:"receiptsRoot"` + LogsHash common.Hash `json:"logsHash"` + Bloom types.Bloom `json:"logsBloom" gencodec:"required"` + Receipts types.Receipts `json:"receipts"` + Rejected []*rejectedTx `json:"rejected,omitempty"` + Difficulty *math.HexOrDecimal256 `json:"currentDifficulty" gencodec:"required"` + GasUsed math.HexOrDecimal64 `json:"gasUsed"` + BaseFee *math.HexOrDecimal256 `json:"currentBaseFee,omitempty"` + WithdrawalsRoot *common.Hash `json:"withdrawalsRoot,omitempty"` + CurrentExcessBlobGas *math.HexOrDecimal64 `json:"currentExcessBlobGas,omitempty"` + CurrentBlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed,omitempty"` + RequestsHash *common.Hash `json:"requestsHash,omitempty"` + Requests []hexutil.Bytes `json:"requests,omitempty"` + } + var enc ExecutionResult + enc.StateRoot = e.StateRoot + enc.TxRoot = e.TxRoot + enc.ReceiptRoot = e.ReceiptRoot + enc.LogsHash = e.LogsHash + enc.Bloom = e.Bloom + enc.Receipts = e.Receipts + enc.Rejected = e.Rejected + enc.Difficulty = e.Difficulty + enc.GasUsed = e.GasUsed + enc.BaseFee = e.BaseFee + enc.WithdrawalsRoot = e.WithdrawalsRoot + enc.CurrentExcessBlobGas = e.CurrentExcessBlobGas + enc.CurrentBlobGasUsed = e.CurrentBlobGasUsed + enc.RequestsHash = e.RequestsHash + if e.Requests != nil { + enc.Requests = make([]hexutil.Bytes, len(e.Requests)) + for k, v := range e.Requests { + enc.Requests[k] = v + } + } + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (e *ExecutionResult) UnmarshalJSON(input []byte) error { + type ExecutionResult struct { + StateRoot *common.Hash `json:"stateRoot"` + TxRoot *common.Hash `json:"txRoot"` + ReceiptRoot *common.Hash `json:"receiptsRoot"` + LogsHash *common.Hash `json:"logsHash"` + Bloom *types.Bloom `json:"logsBloom" gencodec:"required"` + Receipts *types.Receipts `json:"receipts"` + Rejected []*rejectedTx `json:"rejected,omitempty"` + Difficulty *math.HexOrDecimal256 `json:"currentDifficulty" gencodec:"required"` + GasUsed *math.HexOrDecimal64 `json:"gasUsed"` + BaseFee *math.HexOrDecimal256 `json:"currentBaseFee,omitempty"` + WithdrawalsRoot *common.Hash `json:"withdrawalsRoot,omitempty"` + CurrentExcessBlobGas *math.HexOrDecimal64 `json:"currentExcessBlobGas,omitempty"` + CurrentBlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed,omitempty"` + RequestsHash *common.Hash `json:"requestsHash,omitempty"` + Requests []hexutil.Bytes `json:"requests,omitempty"` + } + var dec ExecutionResult + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.StateRoot != nil { + e.StateRoot = *dec.StateRoot + } + if dec.TxRoot != nil { + e.TxRoot = *dec.TxRoot + } + if dec.ReceiptRoot != nil { + e.ReceiptRoot = *dec.ReceiptRoot + } + if dec.LogsHash != nil { + e.LogsHash = *dec.LogsHash + } + if dec.Bloom == nil { + return errors.New("missing required field 'logsBloom' for ExecutionResult") + } + e.Bloom = *dec.Bloom + if dec.Receipts != nil { + e.Receipts = *dec.Receipts + } + if dec.Rejected != nil { + e.Rejected = dec.Rejected + } + if dec.Difficulty == nil { + return errors.New("missing required field 'currentDifficulty' for ExecutionResult") + } + e.Difficulty = dec.Difficulty + if dec.GasUsed != nil { + e.GasUsed = *dec.GasUsed + } + if dec.BaseFee != nil { + e.BaseFee = dec.BaseFee + } + if dec.WithdrawalsRoot != nil { + e.WithdrawalsRoot = dec.WithdrawalsRoot + } + if dec.CurrentExcessBlobGas != nil { + e.CurrentExcessBlobGas = dec.CurrentExcessBlobGas + } + if dec.CurrentBlobGasUsed != nil { + e.CurrentBlobGasUsed = dec.CurrentBlobGasUsed + } + if dec.RequestsHash != nil { + e.RequestsHash = dec.RequestsHash + } + if dec.Requests != nil { + e.Requests = make([][]byte, len(dec.Requests)) + for k, v := range dec.Requests { + e.Requests[k] = v + } + } + return nil +}