From cb3dddcbed3dbef67b219339c701d1abbb92a31a Mon Sep 17 00:00:00 2001 From: Cedrick AHOUANGANSI Date: Wed, 19 Feb 2025 07:12:37 +0100 Subject: [PATCH] core, cores/types: added Gas field in Message, precomputed it and updated computation bytes count algo --- core/state_processor.go | 7 +++++++ core/state_transition.go | 15 +++------------ core/types/transaction.go | 33 +++++++++++---------------------- 3 files changed, 21 insertions(+), 34 deletions(-) diff --git a/core/state_processor.go b/core/state_processor.go index 4e365c6550..35c7403a50 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -133,6 +133,13 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg // 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) { + rules := evm.ChainConfig().Rules(evm.Context.BlockNumber, evm.Context.Random != nil, evm.Context.Time) + // Intrinsic gas + gas, err := tx.IntrinsicGas(&rules) + if err != nil { + return nil, err + } + msg.Gas = gas if hooks := evm.Config.Tracer; hooks != nil { if hooks.OnTxStart != nil { hooks.OnTxStart(evm.GetVMContext(), tx, msg.From) diff --git a/core/state_transition.go b/core/state_transition.go index 2544fc0ece..22c77c5816 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -93,6 +93,7 @@ type Message struct { GasPrice *big.Int GasFeeCap *big.Int GasTipCap *big.Int + Gas uint64 Data []byte AccessList types.AccessList BlobGasFeeCap *big.Int @@ -370,24 +371,14 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { floorDataGas uint64 ) - tx := types.NewTx(&types.LegacyTx{ - Nonce: msg.Nonce, - To: msg.To, - Value: msg.Value, - Gas: msg.GasLimit, - Data: msg.Data, - GasPrice: msg.GasPrice, - }) + gas := msg.Gas // Check clauses 4-5, subtract intrinsic gas if everything is correct - gas, err := tx.IntrinsicGas(&rules) - if err != nil { - return nil, err - } if st.gasRemaining < gas { return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gasRemaining, gas) } // Gas limit suffices for the floor data cost (EIP-7623) if rules.IsPrague { + var err error floorDataGas, err = FloorDataGas(msg.Data) if err != nil { return nil, err diff --git a/core/types/transaction.go b/core/types/transaction.go index 61e55ddf14..17efc69255 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -577,30 +577,20 @@ func (tx *Transaction) IntrinsicGas(rules *params.Rules) (uint64, error) { // IntrinsicGas computes the 'intrinsic gas' for a message with the given data. func IntrinsicGas(txdata TxData, rules *params.Rules) (uint64, error) { - var ( - data = txdata.data() - accessList = txdata.accessList() - authList = txdata.setCodeAuthorizations() - isContractCreation = txdata.to() == nil - ) - // Set the starting gas for the raw transaction var gas uint64 - if isContractCreation && rules.IsHomestead { + if txdata.to() == nil && rules.IsHomestead { gas = params.TxGasContractCreation } else { gas = params.TxGas } - dataLen := uint64(len(data)) + dataLen := uint64(len(txdata.data())) // Bump the required gas by the amount of transactional data if dataLen > 0 { // Zero and non-zero bytes are priced differently - var nz uint64 - for _, byt := range data { - if byt != 0 { - nz++ - } - } + z := uint64(bytes.Count(txdata.data(), []byte{0})) + nz := dataLen - z + // Make sure we don't exceed uint64 for all data combinations nonZeroGas := params.TxDataNonZeroGasFrontier if rules.IsIstanbul { @@ -611,13 +601,12 @@ func IntrinsicGas(txdata TxData, rules *params.Rules) (uint64, error) { } gas += nz * nonZeroGas - z := dataLen - nz if (math.MaxUint64-gas)/params.TxDataZeroGas < z { return 0, ErrGasUintOverflow } gas += z * params.TxDataZeroGas - if isContractCreation && rules.IsShanghai { + if txdata.to() == nil && rules.IsShanghai { lenWords := toWordSize(dataLen) if (math.MaxUint64-gas)/params.InitCodeWordGas < lenWords { return 0, ErrGasUintOverflow @@ -625,12 +614,12 @@ func IntrinsicGas(txdata TxData, rules *params.Rules) (uint64, error) { gas += lenWords * params.InitCodeWordGas } } - if accessList != nil { - gas += uint64(len(accessList)) * params.TxAccessListAddressGas - gas += uint64(accessList.StorageKeys()) * params.TxAccessListStorageKeyGas + if txdata.accessList() != nil { + gas += uint64(len(txdata.accessList())) * params.TxAccessListAddressGas + gas += uint64(txdata.accessList().StorageKeys()) * params.TxAccessListStorageKeyGas } - if authList != nil { - gas += uint64(len(authList)) * params.CallNewAccountGas + if txdata.setCodeAuthorizations() != nil { + gas += uint64(len(txdata.setCodeAuthorizations())) * params.CallNewAccountGas } return gas, nil }