diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index b2e5f70714..1f1db4e7a6 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -146,7 +146,6 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, statedb = MakePreState(rawdb.NewMemoryDatabase(), pre.Pre) signer = types.MakeSigner(chainConfig, new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp) gaspool = new(core.GasPool) - blockHash = common.Hash{0x13, 0x37} rejectedTxs []*rejectedTx includedTxs types.Transactions gasUsed = uint64(0) @@ -303,7 +302,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, } // Set the receipt logs and create the bloom filter. - receipt.Logs = statedb.GetLogs(tx.Hash(), vmContext.BlockNumber.Uint64(), blockHash) + receipt.Logs = statedb.GetLogs(tx.Hash()) receipt.Bloom = types.CreateBloom(receipt) // These three are non-consensus fields: diff --git a/core/chain_makers.go b/core/chain_makers.go index 37bddcfda5..e3e5867e99 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -130,7 +130,7 @@ func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transacti b.txs = append(b.txs, tx) b.receipts = append(b.receipts, receipt) if b.header.BlobGasUsed != nil { - *b.header.BlobGasUsed += receipt.BlobGasUsed + *b.header.BlobGasUsed += uint64(len(tx.BlobHashes()) * params.BlobTxBlobGasPerBlob) } } diff --git a/core/state/statedb.go b/core/state/statedb.go index 2453d67f3e..f09356e403 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -250,15 +250,9 @@ func (s *StateDB) AddLog(log *types.Log) { s.logSize++ } -// GetLogs returns the logs matching the specified transaction hash, and annotates -// them with the given blockNumber and blockHash. -func (s *StateDB) GetLogs(hash common.Hash, blockNumber uint64, blockHash common.Hash) []*types.Log { - logs := s.logs[hash] - for _, l := range logs { - l.BlockNumber = blockNumber - l.BlockHash = blockHash - } - return logs +// GetLogs returns the logs matching the specified transaction hash. +func (s *StateDB) GetLogs(hash common.Hash) []*types.Log { + return s.logs[hash] } func (s *StateDB) Logs() []*types.Log { diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index e740c64faa..90ec22f40c 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -669,9 +669,9 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error { return fmt.Errorf("got GetRefund() == %d, want GetRefund() == %d", state.GetRefund(), checkstate.GetRefund()) } - if !reflect.DeepEqual(state.GetLogs(common.Hash{}, 0, common.Hash{}), checkstate.GetLogs(common.Hash{}, 0, common.Hash{})) { + if !reflect.DeepEqual(state.GetLogs(common.Hash{}), checkstate.GetLogs(common.Hash{})) { return fmt.Errorf("got GetLogs(common.Hash{}) == %v, want GetLogs(common.Hash{}) == %v", - state.GetLogs(common.Hash{}, 0, common.Hash{}), checkstate.GetLogs(common.Hash{}, 0, common.Hash{})) + state.GetLogs(common.Hash{}), checkstate.GetLogs(common.Hash{})) } if !maps.Equal(state.journal.dirties, checkstate.journal.dirties) { getKeys := func(dirty map[common.Address]int) string { diff --git a/core/state_processor.go b/core/state_processor.go index 322bd24f41..c42428aa9b 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -97,7 +97,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg } statedb.SetTxContext(tx.Hash(), i) - receipt, err := ApplyTransactionWithEVM(msg, gp, statedb, blockNumber, blockHash, tx, usedGas, evm) + receipt, err := ApplyTransactionWithEVM(msg, gp, statedb, blockNumber, blockHash, tx, usedGas, evm, true) if err != nil { return nil, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) } @@ -136,7 +136,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg // ApplyTransactionWithEVM attempts to apply a transaction to the given state database // and uses the input parameters for its environment similar to ApplyTransaction. However, // this method takes an already created EVM instance as input. -func ApplyTransactionWithEVM(msg *Message, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (receipt *types.Receipt, err error) { +func ApplyTransactionWithEVM(msg *Message, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, fullReceipts bool) (receipt *types.Receipt, err error) { if hooks := evm.Config.Tracer; hooks != nil { if hooks.OnTxStart != nil { hooks.OnTxStart(evm.GetVMContext(), tx, msg.From) @@ -165,19 +165,32 @@ func ApplyTransactionWithEVM(msg *Message, gp *GasPool, statedb *state.StateDB, statedb.AccessEvents().Merge(evm.AccessEvents) } - return MakeReceipt(evm, result, statedb, blockNumber, blockHash, tx, *usedGas, root), nil + if fullReceipts { + return MakeFullReceipt(evm, result, statedb, blockNumber, blockHash, tx, *usedGas, root), nil + } + return makeConsensusReceipt(result, statedb, tx, *usedGas, root), nil } -// MakeReceipt generates the receipt object for a transaction given its execution result. -func MakeReceipt(evm *vm.EVM, result *ExecutionResult, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas uint64, root []byte) *types.Receipt { - // Create a new receipt for the transaction, storing the intermediate root and gas used - // by the tx. +// makeConsensusReceipt generates the receipt object for a transaction given its execution result. +// It only populates the fields strictly required for consensus. +func makeConsensusReceipt(result *ExecutionResult, statedb *state.StateDB, tx *types.Transaction, usedGas uint64, root []byte) *types.Receipt { receipt := &types.Receipt{Type: tx.Type(), PostState: root, CumulativeGasUsed: usedGas} if result.Failed() { receipt.Status = types.ReceiptStatusFailed } else { receipt.Status = types.ReceiptStatusSuccessful } + receipt.Logs = statedb.GetLogs(tx.Hash()) + receipt.Bloom = types.CreateBloom(receipt) + return receipt +} + +// MakeFullReceipt generates the receipt object for a transaction given its execution result. +// It also populates non-consensus fields. +func MakeFullReceipt(evm *vm.EVM, result *ExecutionResult, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas uint64, root []byte) *types.Receipt { + // Create a new receipt for the transaction, storing the intermediate root and gas used + // by the tx. + receipt := makeConsensusReceipt(result, statedb, tx, usedGas, root) receipt.TxHash = tx.Hash() receipt.GasUsed = result.UsedGas @@ -191,9 +204,11 @@ func MakeReceipt(evm *vm.EVM, result *ExecutionResult, statedb *state.StateDB, b receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, tx.Nonce()) } - // Set the receipt logs and create the bloom filter. - receipt.Logs = statedb.GetLogs(tx.Hash(), blockNumber.Uint64(), blockHash) - receipt.Bloom = types.CreateBloom(receipt) + // Annotate the logs with blockhash and blocknumber. + for _, log := range receipt.Logs { + log.BlockHash = blockHash + log.BlockNumber = blockNumber.Uint64() + } receipt.BlockHash = blockHash receipt.BlockNumber = blockNumber receipt.TransactionIndex = uint(statedb.TxIndex()) @@ -210,7 +225,7 @@ func ApplyTransaction(evm *vm.EVM, gp *GasPool, statedb *state.StateDB, header * return nil, err } // Create a new context to be used in the EVM environment - return ApplyTransactionWithEVM(msg, gp, statedb, header.Number, header.Hash(), tx, usedGas, evm) + return ApplyTransactionWithEVM(msg, gp, statedb, header.Number, common.Hash{}, tx, usedGas, evm, false) } // ProcessBeaconBlockRoot applies the EIP-4788 system call to the beacon block root diff --git a/eth/tracers/api.go b/eth/tracers/api.go index fe72924828..fecac58268 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -1041,7 +1041,7 @@ func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *cor // Call Prepare to clear out the statedb access list statedb.SetTxContext(txctx.TxHash, txctx.TxIndex) - _, err = core.ApplyTransactionWithEVM(message, new(core.GasPool).AddGas(message.GasLimit), statedb, vmctx.BlockNumber, txctx.BlockHash, tx, &usedGas, evm) + _, err = core.ApplyTransactionWithEVM(message, new(core.GasPool).AddGas(message.GasLimit), statedb, vmctx.BlockNumber, txctx.BlockHash, tx, &usedGas, evm, true) if err != nil { return nil, fmt.Errorf("tracing failed: %w", err) } diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index b997cf297b..61baffae2a 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -301,7 +301,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, root = sim.state.IntermediateRoot(sim.chainConfig.IsEIP158(blockContext.BlockNumber)).Bytes() } gasUsed += result.UsedGas - receipts[i] = core.MakeReceipt(evm, result, sim.state, blockContext.BlockNumber, common.Hash{}, tx, gasUsed, root) + receipts[i] = core.MakeFullReceipt(evm, result, sim.state, blockContext.BlockNumber, common.Hash{}, tx, gasUsed, root) blobGasUsed += receipts[i].BlobGasUsed logs := tracer.Logs() callRes := simCallResult{ReturnValue: result.Return(), Logs: logs, GasUsed: hexutil.Uint64(result.UsedGas)} diff --git a/miner/worker.go b/miner/worker.go index d80cb8913b..44041281b8 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -297,7 +297,7 @@ func (miner *Miner) commitBlobTransaction(env *environment, tx *types.Transactio env.receipts = append(env.receipts, receipt) env.sidecars = append(env.sidecars, sc) env.blobs += len(sc.Blobs) - *env.header.BlobGasUsed += receipt.BlobGasUsed + *env.header.BlobGasUsed += uint64(len(tx.BlobHashes()) * params.BlobTxBlobGasPerBlob) env.tcount++ return nil }