Skip to content

Commit 672da00

Browse files
committed
fix(core): refresh coinbase owner per transaction
Problem: block processing reused a coinbase owner value captured before the transaction loop, so fee credits could go to a stale owner when the owner mapping changed during execution. Cause: Process and ProcessBlockNoValidator computed coinbaseOwner once and passed it through ApplyTransactionWithEVM for every transaction in the block. Solution: move the owner lookup into ApplyTransactionWithEVM so each transaction reads the current owner from state, remove the unused helper, and update tests to the new function signature.
1 parent f5fe86c commit 672da00

3 files changed

Lines changed: 11 additions & 21 deletions

File tree

core/state_processor.go

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, tra
100100
context := NewEVMBlockContext(header, p.bc, nil)
101101
evm := vm.NewEVM(context, tracingStateDB, tradingState, p.config, cfg)
102102
signer := types.MakeSigner(p.config, blockNumber)
103-
coinbaseOwner := getCoinbaseOwner(p.bc, statedb, header, nil)
104103

105104
if p.config.IsPrague(block.Number()) {
106105
ProcessParentBlockHash(block.ParentHash(), evm)
@@ -146,7 +145,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, tra
146145
}
147146
statedb.SetTxContext(tx.Hash(), i)
148147

149-
receipt, gas, tokenFeeUsed, err := ApplyTransactionWithEVM(msg, gp, statedb, blockNumber, blockHash, tx, usedGas, evm, balanceFee, coinbaseOwner)
148+
receipt, gas, tokenFeeUsed, err := ApplyTransactionWithEVM(msg, gp, statedb, blockNumber, blockHash, tx, usedGas, evm, balanceFee)
150149
if err != nil {
151150
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
152151
}
@@ -207,7 +206,6 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
207206
context := NewEVMBlockContext(header, p.bc, nil)
208207
evm := vm.NewEVM(context, tracingStateDB, tradingState, p.config, cfg)
209208
signer := types.MakeSigner(p.config, blockNumber)
210-
coinbaseOwner := getCoinbaseOwner(p.bc, statedb, header, nil)
211209

212210
if p.config.IsPrague(block.Number()) {
213211
ProcessParentBlockHash(block.ParentHash(), evm)
@@ -253,7 +251,7 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
253251
}
254252
statedb.SetTxContext(tx.Hash(), i)
255253

256-
receipt, gas, tokenFeeUsed, err := ApplyTransactionWithEVM(msg, gp, statedb, blockNumber, blockHash, tx, usedGas, evm, balanceFee, coinbaseOwner)
254+
receipt, gas, tokenFeeUsed, err := ApplyTransactionWithEVM(msg, gp, statedb, blockNumber, blockHash, tx, usedGas, evm, balanceFee)
257255
if err != nil {
258256
return nil, nil, 0, err
259257
}
@@ -279,7 +277,7 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
279277
// ApplyTransactionWithEVM attempts to apply a transaction to the given state database
280278
// and uses the input parameters for its environment similar to ApplyTransaction. However,
281279
// this method takes an already created EVM instance as input.
282-
func ApplyTransactionWithEVM(msg *Message, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, balanceFee *big.Int, coinbaseOwner common.Address) (receipt *types.Receipt, gasUsed uint64, tokenFeeUsed bool, err error) {
280+
func ApplyTransactionWithEVM(msg *Message, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, balanceFee *big.Int) (receipt *types.Receipt, gasUsed uint64, tokenFeeUsed bool, err error) {
283281
if hooks := evm.Config.Tracer; hooks != nil {
284282
if hooks.OnTxStart != nil {
285283
hooks.OnTxStart(evm.GetVMContext(), tx, msg.From)
@@ -458,6 +456,10 @@ func ApplyTransactionWithEVM(msg *Message, gp *GasPool, statedb *state.StateDB,
458456
// End Bypass denylist address
459457

460458
// Apply the transaction to the current state (included in the env)
459+
var coinbaseOwner common.Address
460+
if balanceFee != nil && blockNumber.Cmp(common.TIPTRC21Fee) > 0 {
461+
coinbaseOwner = statedb.GetOwner(evm.Context.Coinbase)
462+
}
461463
result, err := ApplyMessage(evm, msg, gp, coinbaseOwner)
462464
if err != nil {
463465
return nil, 0, false, err
@@ -506,17 +508,6 @@ func MakeReceipt(evm *vm.EVM, result *ExecutionResult, statedb *state.StateDB, b
506508
return receipt
507509
}
508510

509-
func getCoinbaseOwner(bc *BlockChain, statedb *state.StateDB, header *types.Header, author *common.Address) common.Address {
510-
// If we don't have an explicit author (i.e. not mining), extract from the header
511-
var beneficiary common.Address
512-
if author == nil {
513-
beneficiary, _ = bc.Engine().Author(header) // Ignore error, we're past header validation
514-
} else {
515-
beneficiary = *author
516-
}
517-
return statedb.GetOwner(beneficiary)
518-
}
519-
520511
// ApplyTransaction attempts to apply a transaction to the given state database
521512
// and uses the input parameters for its environment. It returns the receipt
522513
// for the transaction, gas used and an error if the transaction failed,
@@ -534,8 +525,7 @@ func ApplyTransaction(tokensFee map[common.Address]*big.Int, evm *vm.EVM, gp *Ga
534525
if err != nil {
535526
return nil, 0, false, err
536527
}
537-
coinbaseOwner := statedb.GetOwner(evm.Context.Coinbase)
538-
return ApplyTransactionWithEVM(msg, gp, statedb, header.Number, header.Hash(), tx, usedGas, evm, balanceFee, coinbaseOwner)
528+
return ApplyTransactionWithEVM(msg, gp, statedb, header.Number, header.Hash(), tx, usedGas, evm, balanceFee)
539529
}
540530

541531
func ApplySignTransaction(msg *Message, config *params.ChainConfig, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (receipt *types.Receipt, gasUsed uint64, tokenFeeUsed bool, err error) {

core/state_processor_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ func TestApplyTransactionWithEVMTracer(t *testing.T) {
501501

502502
// Apply transaction
503503
var usedGas uint64
504-
_, _, _, err = ApplyTransactionWithEVM(msg, gasPool, statedb, blockNumber, blockHash, signedTx, &usedGas, evm, big.NewInt(0), common.Address{})
504+
_, _, _, err = ApplyTransactionWithEVM(msg, gasPool, statedb, blockNumber, blockHash, signedTx, &usedGas, evm, big.NewInt(0))
505505
// NOTE: Some special transactions (like BlockSignersBinary or XDCXAddrBinary)
506506
// may fail in test environment due to missing configuration or state, but
507507
// the tracer should still be called at the beginning of ApplyTransactionWithEVM.
@@ -589,7 +589,7 @@ func TestApplyTransactionWithEVMStateChangeHooks(t *testing.T) {
589589

590590
gasPool := new(GasPool).AddGas(1000000)
591591
var usedGas uint64
592-
_, _, _, err = ApplyTransactionWithEVM(msg, gasPool, statedb, big.NewInt(1), genesis.Hash(), signedTx, &usedGas, evmenv, nil, common.Address{})
592+
_, _, _, err = ApplyTransactionWithEVM(msg, gasPool, statedb, big.NewInt(1), genesis.Hash(), signedTx, &usedGas, evmenv, nil)
593593
if err != nil {
594594
t.Fatalf("ApplyTransactionWithEVM failed: %v", err)
595595
}

eth/tracers/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,7 @@ func (api *API) traceTx(ctx context.Context, tx *types.Transaction, message *cor
931931

932932
// Call SetTxContext to clear out the statedb access list
933933
statedb.SetTxContext(txctx.TxHash, txctx.TxIndex)
934-
_, _, _, err = core.ApplyTransactionWithEVM(message, new(core.GasPool).AddGas(message.GasLimit), statedb, vmctx.BlockNumber, txctx.BlockHash, tx, &usedGas, evm, balance, common.Address{})
934+
_, _, _, err = core.ApplyTransactionWithEVM(message, new(core.GasPool).AddGas(message.GasLimit), statedb, vmctx.BlockNumber, txctx.BlockHash, tx, &usedGas, evm, balance)
935935
if err != nil {
936936
return nil, fmt.Errorf("tracing failed: %w", err)
937937
}

0 commit comments

Comments
 (0)