Skip to content

Commit

Permalink
Move msg.SetIsFree to core.ApplyMessage (#13880)
Browse files Browse the repository at this point in the history
See Issue #9259
  • Loading branch information
yperbasis authored Feb 21, 2025
1 parent 0ca5c6d commit 5e54fe0
Show file tree
Hide file tree
Showing 32 changed files with 134 additions and 173 deletions.
1 change: 1 addition & 0 deletions accounts/abi/bind/backends/simulated.go
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,7 @@ func (m callMsg) Data() []byte { return m.CallMsg.Data
func (m callMsg) AccessList() types.AccessList { return m.CallMsg.AccessList }
func (m callMsg) Authorizations() []types.Authorization { return m.CallMsg.Authorizations }
func (m callMsg) IsFree() bool { return false }
func (m callMsg) SetIsFree(_ bool) {}

func (m callMsg) BlobGas() uint64 { return misc.GetBlobGasUsed(len(m.CallMsg.BlobHashes)) }
func (m callMsg) MaxFeePerBlobGas() *uint256.Int { return m.CallMsg.MaxFeePerBlobGas }
Expand Down
9 changes: 1 addition & 8 deletions cmd/state/exec3/historical_trace_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,6 @@ func (rw *HistoricalTraceWorker) RunTxTask(txTask *state.TxTask) {
ibs.SetTxContext(txTask.TxIndex)
msg := txTask.TxAsMessage
msg.SetCheckNonce(!rw.vmConfig.StatelessExec)
if msg.FeeCap().IsZero() {
// Only zero-gas transactions may be service ones
syscall := func(contract common.Address, data []byte) ([]byte, error) {
return core.SysCallContract(contract, data, rw.execArgs.ChainConfig, ibs, header, rw.execArgs.Engine, true /* constCall */)
}
msg.SetIsFree(rw.execArgs.Engine.IsServiceTransaction(msg.From(), syscall))
}

txContext := core.NewEVMTxContext(msg)
if rw.vmConfig.TraceJumpDest {
Expand All @@ -209,7 +202,7 @@ func (rw *HistoricalTraceWorker) RunTxTask(txTask *state.TxTask) {
rw.evm.ResetBetweenBlocks(txTask.EvmBlockContext, txContext, ibs, *rw.vmConfig, rules)

// MA applytx
applyRes, err := core.ApplyMessage(rw.evm, msg, rw.taskGasPool, true /* refunds */, false /* gasBailout */)
applyRes, err := core.ApplyMessage(rw.evm, msg, rw.taskGasPool, true /* refunds */, false /* gasBailout */, rw.execArgs.Engine)
if err != nil {
txTask.Error = err
} else {
Expand Down
9 changes: 1 addition & 8 deletions cmd/state/exec3/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,18 +268,11 @@ func (rw *Worker) RunTxTaskNoLock(txTask *state.TxTask, isMining bool) {
rw.vmCfg.SkipAnalysis = txTask.SkipAnalysis
ibs.SetTxContext(txTask.TxIndex)
msg := txTask.TxAsMessage
if msg.FeeCap().IsZero() && rw.engine != nil {
// Only zero-gas transactions may be service ones
syscall := func(contract libcommon.Address, data []byte) ([]byte, error) {
return core.SysCallContract(contract, data, rw.chainConfig, ibs, header, rw.engine, true /* constCall */)
}
msg.SetIsFree(rw.engine.IsServiceTransaction(msg.From(), syscall))
}

rw.evm.ResetBetweenBlocks(txTask.EvmBlockContext, core.NewEVMTxContext(msg), ibs, rw.vmCfg, rules)

// MA applytx
applyRes, err := core.ApplyMessage(rw.evm, msg, rw.taskGasPool, true /* refunds */, false /* gasBailout */)
applyRes, err := core.ApplyMessage(rw.evm, msg, rw.taskGasPool, true /* refunds */, false /* gasBailout */, rw.engine)
if err != nil {
txTask.Error = err
} else {
Expand Down
9 changes: 1 addition & 8 deletions cmd/state/exec3/trace_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,6 @@ func (e *TraceWorker) ExecTxn(txNum uint64, txIndex int, txn types.Transaction,
return nil, err
}
msg.SetCheckNonce(!e.vmConfig.StatelessExec)
if msg.FeeCap().IsZero() {
// Only zero-gas transactions may be service ones
syscall := func(contract common.Address, data []byte) ([]byte, error) {
return core.SysCallContract(contract, data, e.chainConfig, e.ibs, e.header, e.engine, true /* constCall */)
}
msg.SetIsFree(e.engine.IsServiceTransaction(msg.From(), syscall))
}

txContext := core.NewEVMTxContext(msg)
if e.vmConfig.TraceJumpDest {
Expand All @@ -129,7 +122,7 @@ func (e *TraceWorker) ExecTxn(txNum uint64, txIndex int, txn types.Transaction,
e.evm.ResetBetweenBlocks(*e.blockCtx, txContext, e.ibs, *e.vmConfig, e.rules)

gp := new(core.GasPool).AddGas(txn.GetGas()).AddBlobGas(txn.GetBlobGas())
res, err := core.ApplyMessage(e.evm, msg, gp, true /* refunds */, gasBailout /* gasBailout */)
res, err := core.ApplyMessage(e.evm, msg, gp, true /* refunds */, gasBailout /* gasBailout */, e.engine)
if err != nil {
return nil, fmt.Errorf("%w: blockNum=%d, txNum=%d, %s", err, e.blockNum, txNum, e.ibs.Error())
}
Expand Down
18 changes: 13 additions & 5 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,19 @@ func rlpHash(x interface{}) (h libcommon.Hash) {
return h
}

func SysCallContract(contract libcommon.Address, data []byte, chainConfig *chain.Config, ibs *state.IntraBlockState, header *types.Header, engine consensus.EngineReader, constCall bool) (result []byte, err error) {
func SysCallContract(contract libcommon.Address, data []byte, chainConfig *chain.Config, ibs evmtypes.IntraBlockState, header *types.Header, engine consensus.EngineReader, constCall bool) (result []byte, err error) {
isBor := chainConfig.Bor != nil
var author *libcommon.Address
if isBor {
author = &header.Coinbase
} else {
author = &state.SystemAddress
}
blockContext := NewEVMBlockContext(header, GetHashFn(header, nil), engine, author, chainConfig)
return SysCallContractWithBlockContext(contract, data, chainConfig, ibs, blockContext, engine, constCall)
}

func SysCallContractWithBlockContext(contract libcommon.Address, data []byte, chainConfig *chain.Config, ibs evmtypes.IntraBlockState, blockContext evmtypes.BlockContext, engine consensus.EngineReader, constCall bool) (result []byte, err error) {
msg := types.NewMessage(
state.SystemAddress,
&contract,
Expand All @@ -266,15 +278,11 @@ func SysCallContract(contract libcommon.Address, data []byte, chainConfig *chain
// Create a new context to be used in the EVM environment
isBor := chainConfig.Bor != nil
var txContext evmtypes.TxContext
var author *libcommon.Address
if isBor {
author = &header.Coinbase
txContext = evmtypes.TxContext{}
} else {
author = &state.SystemAddress
txContext = NewEVMTxContext(msg)
}
blockContext := NewEVMBlockContext(header, GetHashFn(header, nil), engine, author, chainConfig)
evm := vm.NewEVM(blockContext, txContext, ibs, chainConfig, vmConfig)

ret, _, err := evm.Call(
Expand Down
11 changes: 5 additions & 6 deletions core/state/txtask.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,16 @@ import (
"sync"
"time"

"github.com/erigontech/erigon-lib/common/dbg"
"github.com/erigontech/erigon-lib/log/v3"

"github.com/erigontech/erigon-lib/kv"
"github.com/erigontech/erigon/core/rawdb/rawtemporaldb"
"github.com/holiman/uint256"

"github.com/erigontech/erigon-lib/chain"
libcommon "github.com/erigontech/erigon-lib/common"
"github.com/erigontech/erigon-lib/common/dbg"
"github.com/erigontech/erigon-lib/kv"
"github.com/erigontech/erigon-lib/log/v3"
"github.com/erigontech/erigon-lib/state"
"github.com/erigontech/erigon-lib/types/accounts"
"github.com/erigontech/erigon/core/rawdb/rawtemporaldb"
"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/core/vm/evmtypes"
)
Expand All @@ -58,7 +57,7 @@ type TxTask struct {
Failed bool
Tx types.Transaction
GetHashFn func(n uint64) libcommon.Hash
TxAsMessage types.Message
TxAsMessage *types.Message
EvmBlockContext evmtypes.BlockContext

HistoryExecution bool // use history reader for that txn instead of state reader
Expand Down
10 changes: 1 addition & 9 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,14 @@ func applyTransaction(config *chain.Config, engine consensus.EngineReader, gp *G
}
msg.SetCheckNonce(!cfg.StatelessExec)

if msg.FeeCap().IsZero() && engine != nil {
// Only zero-gas transactions may be service ones
syscall := func(contract libcommon.Address, data []byte) ([]byte, error) {
return SysCallContract(contract, data, config, ibs, header, engine, true /* constCall */)
}
msg.SetIsFree(engine.IsServiceTransaction(msg.From(), syscall))
}

txContext := NewEVMTxContext(msg)
if cfg.TraceJumpDest {
txContext.TxHash = txn.Hash()
}

// Update the evm with the new transaction context.
evm.Reset(txContext, ibs)
result, err := ApplyMessage(evm, msg, gp, true /* refunds */, false /* gasBailout */)
result, err := ApplyMessage(evm, msg, gp, true /* refunds */, false /* gasBailout */, engine)
if err != nil {
return nil, nil, err
}
Expand Down
17 changes: 15 additions & 2 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import (
"github.com/erigontech/erigon-lib/common/u256"
"github.com/erigontech/erigon-lib/crypto"
"github.com/erigontech/erigon-lib/log/v3"
"github.com/erigontech/erigon/consensus"
"github.com/erigontech/erigon/core/state"
"github.com/erigontech/erigon/core/tracing"
"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/core/vm"
Expand Down Expand Up @@ -102,7 +104,8 @@ type Message interface {
BlobHashes() []libcommon.Hash
Authorizations() []types.Authorization

IsFree() bool
IsFree() bool // service transactions on Gnosis are exempt from EIP-1559 mandatory fees
SetIsFree(bool)
}

// NewStateTransition initialises and returns a new state transition object.
Expand Down Expand Up @@ -133,7 +136,17 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition
// `refunds` is false when it is not required to apply gas refunds
// `gasBailout` is true when it is not required to fail transaction if the balance is not enough to pay gas.
// for trace_call to replicate OE/Parity behaviour
func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool, refunds bool, gasBailout bool) (*evmtypes.ExecutionResult, error) {
func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool, refunds bool, gasBailout bool, engine consensus.EngineReader) (
*evmtypes.ExecutionResult, error) {
// Only zero-gas transactions may be service ones
if msg.FeeCap().IsZero() && !msg.IsFree() && engine != nil {
blockContext := evm.Context
blockContext.Coinbase = state.SystemAddress
syscall := func(contract libcommon.Address, data []byte) ([]byte, error) {
return SysCallContractWithBlockContext(contract, data, evm.ChainConfig(), evm.IntraBlockState(), blockContext, engine, true /* constCall */)
}
msg.SetIsFree(engine.IsServiceTransaction(msg.From(), syscall))
}
return NewStateTransition(evm, msg, gp).TransitionDb(refunds, gasBailout)
}

Expand Down
6 changes: 3 additions & 3 deletions core/types/access_list_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ func (tx *AccessListTx) DecodeRLP(s *rlp.Stream) error {
}

// AsMessage returns the transaction as a core.Message.
func (tx *AccessListTx) AsMessage(s Signer, _ *big.Int, rules *chain.Rules) (Message, error) {
func (tx *AccessListTx) AsMessage(s Signer, _ *big.Int, rules *chain.Rules) (*Message, error) {
msg := Message{
nonce: tx.Nonce,
gasLimit: tx.Gas,
Expand All @@ -426,12 +426,12 @@ func (tx *AccessListTx) AsMessage(s Signer, _ *big.Int, rules *chain.Rules) (Mes
}

if !rules.IsBerlin {
return msg, errors.New("eip-2930 transactions require Berlin")
return nil, errors.New("eip-2930 transactions require Berlin")
}

var err error
msg.from, err = tx.Sender(s)
return msg, err
return &msg, err
}

func (tx *AccessListTx) WithSignature(signer Signer, sig []byte) (Transaction, error) {
Expand Down
8 changes: 4 additions & 4 deletions core/types/blob_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (stx *BlobTx) GetBlobGas() uint64 {
return fixedgas.BlobGasPerBlob * uint64(len(stx.BlobVersionedHashes))
}

func (stx *BlobTx) AsMessage(s Signer, baseFee *big.Int, rules *chain.Rules) (Message, error) {
func (stx *BlobTx) AsMessage(s Signer, baseFee *big.Int, rules *chain.Rules) (*Message, error) {
msg := Message{
nonce: stx.Nonce,
gasLimit: stx.Gas,
Expand All @@ -76,12 +76,12 @@ func (stx *BlobTx) AsMessage(s Signer, baseFee *big.Int, rules *chain.Rules) (Me
checkNonce: true,
}
if !rules.IsCancun {
return msg, errors.New("BlobTx transactions require Cancun")
return nil, errors.New("BlobTx transactions require Cancun")
}
if baseFee != nil {
overflow := msg.gasPrice.SetFromBig(baseFee)
if overflow {
return msg, errors.New("gasPrice higher than 2^256-1")
return nil, errors.New("gasPrice higher than 2^256-1")
}
}
msg.gasPrice.Add(&msg.gasPrice, stx.Tip)
Expand All @@ -92,7 +92,7 @@ func (stx *BlobTx) AsMessage(s Signer, baseFee *big.Int, rules *chain.Rules) (Me
msg.from, err = stx.Sender(s)
msg.maxFeePerBlobGas = *stx.MaxFeePerBlobGas
msg.blobHashes = stx.BlobVersionedHashes
return msg, err
return &msg, err
}

func (stx *BlobTx) cachedSender() (sender libcommon.Address, ok bool) {
Expand Down
2 changes: 1 addition & 1 deletion core/types/blob_tx_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ func (txw *BlobTxWrapper) GetBlobGas() uint64 { return txw.Tx.GetBlobGas(
func (txw *BlobTxWrapper) GetValue() *uint256.Int { return txw.Tx.GetValue() }
func (txw *BlobTxWrapper) GetTo() *libcommon.Address { return txw.Tx.GetTo() }

func (txw *BlobTxWrapper) AsMessage(s Signer, baseFee *big.Int, rules *chain.Rules) (Message, error) {
func (txw *BlobTxWrapper) AsMessage(s Signer, baseFee *big.Int, rules *chain.Rules) (*Message, error) {
return txw.Tx.AsMessage(s, baseFee, rules)
}
func (txw *BlobTxWrapper) WithSignature(signer Signer, sig []byte) (Transaction, error) {
Expand Down
8 changes: 4 additions & 4 deletions core/types/dynamic_fee_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ func (tx *DynamicFeeTransaction) DecodeRLP(s *rlp.Stream) error {
}

// AsMessage returns the transaction as a core.Message.
func (tx *DynamicFeeTransaction) AsMessage(s Signer, baseFee *big.Int, rules *chain.Rules) (Message, error) {
func (tx *DynamicFeeTransaction) AsMessage(s Signer, baseFee *big.Int, rules *chain.Rules) (*Message, error) {
msg := Message{
nonce: tx.Nonce,
gasLimit: tx.Gas,
Expand All @@ -343,12 +343,12 @@ func (tx *DynamicFeeTransaction) AsMessage(s Signer, baseFee *big.Int, rules *ch
checkNonce: true,
}
if !rules.IsLondon {
return msg, errors.New("eip-1559 transactions require London")
return nil, errors.New("eip-1559 transactions require London")
}
if baseFee != nil {
overflow := msg.gasPrice.SetFromBig(baseFee)
if overflow {
return msg, errors.New("gasPrice higher than 2^256-1")
return nil, errors.New("gasPrice higher than 2^256-1")
}
}
msg.gasPrice.Add(&msg.gasPrice, tx.Tip)
Expand All @@ -358,7 +358,7 @@ func (tx *DynamicFeeTransaction) AsMessage(s Signer, baseFee *big.Int, rules *ch

var err error
msg.from, err = tx.Sender(s)
return msg, err
return &msg, err
}

// Hash computes the hash (but not for signatures!)
Expand Down
4 changes: 2 additions & 2 deletions core/types/legacy_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ func (tx *LegacyTx) DecodeRLP(s *rlp.Stream) error {
}

// AsMessage returns the transaction as a core.Message.
func (tx *LegacyTx) AsMessage(s Signer, _ *big.Int, _ *chain.Rules) (Message, error) {
func (tx *LegacyTx) AsMessage(s Signer, _ *big.Int, _ *chain.Rules) (*Message, error) {
msg := Message{
nonce: tx.Nonce,
gasLimit: tx.Gas,
Expand All @@ -359,7 +359,7 @@ func (tx *LegacyTx) AsMessage(s Signer, _ *big.Int, _ *chain.Rules) (Message, er

var err error
msg.from, err = tx.Sender(s)
return msg, err
return &msg, err
}

func (tx *LegacyTx) WithSignature(signer Signer, sig []byte) (Transaction, error) {
Expand Down
10 changes: 5 additions & 5 deletions core/types/set_code_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func (tx *SetCodeTransaction) MarshalBinary(w io.Writer) error {
return nil
}

func (tx *SetCodeTransaction) AsMessage(s Signer, baseFee *big.Int, rules *chain.Rules) (Message, error) {
func (tx *SetCodeTransaction) AsMessage(s Signer, baseFee *big.Int, rules *chain.Rules) (*Message, error) {
msg := Message{
nonce: tx.Nonce,
gasLimit: tx.Gas,
Expand All @@ -128,12 +128,12 @@ func (tx *SetCodeTransaction) AsMessage(s Signer, baseFee *big.Int, rules *chain
checkNonce: true,
}
if !rules.IsPrague {
return msg, errors.New("SetCodeTransaction is only supported in Prague")
return nil, errors.New("SetCodeTransaction is only supported in Prague")
}
if baseFee != nil {
overflow := msg.gasPrice.SetFromBig(baseFee)
if overflow {
return msg, errors.New("gasPrice higher than 2^256-1")
return nil, errors.New("gasPrice higher than 2^256-1")
}
}
msg.gasPrice.Add(&msg.gasPrice, tx.Tip)
Expand All @@ -142,13 +142,13 @@ func (tx *SetCodeTransaction) AsMessage(s Signer, baseFee *big.Int, rules *chain
}

if len(tx.Authorizations) == 0 {
return msg, errors.New("SetCodeTransaction without authorizations is invalid")
return nil, errors.New("SetCodeTransaction without authorizations is invalid")
}
msg.authorizations = tx.Authorizations

var err error
msg.from, err = tx.Sender(s)
return msg, err
return &msg, err
}

func (tx *SetCodeTransaction) Sender(signer Signer) (libcommon.Address, error) {
Expand Down
Loading

0 comments on commit 5e54fe0

Please sign in to comment.