core, cores/types: added Gas field in Message, precomputed it and updated computation bytes count algo

This commit is contained in:
Cedrick AHOUANGANSI 2025-02-19 07:12:37 +01:00 committed by lightclient
parent 45c2c0bd3d
commit 47daf83bb6
No known key found for this signature in database
GPG key ID: 657913021EF45A6A
3 changed files with 21 additions and 34 deletions

View file

@ -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, // and uses the input parameters for its environment similar to ApplyTransaction. However,
// this method takes an already created EVM instance as input. // 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) (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 := evm.Config.Tracer; hooks != nil {
if hooks.OnTxStart != nil { if hooks.OnTxStart != nil {
hooks.OnTxStart(evm.GetVMContext(), tx, msg.From) hooks.OnTxStart(evm.GetVMContext(), tx, msg.From)

View file

@ -93,6 +93,7 @@ type Message struct {
GasPrice *big.Int GasPrice *big.Int
GasFeeCap *big.Int GasFeeCap *big.Int
GasTipCap *big.Int GasTipCap *big.Int
Gas uint64
Data []byte Data []byte
AccessList types.AccessList AccessList types.AccessList
BlobGasFeeCap *big.Int BlobGasFeeCap *big.Int
@ -370,24 +371,14 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
floorDataGas uint64 floorDataGas uint64
) )
tx := types.NewTx(&types.LegacyTx{ gas := msg.Gas
Nonce: msg.Nonce,
To: msg.To,
Value: msg.Value,
Gas: msg.GasLimit,
Data: msg.Data,
GasPrice: msg.GasPrice,
})
// Check clauses 4-5, subtract intrinsic gas if everything is correct // 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 { if st.gasRemaining < gas {
return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, 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) // Gas limit suffices for the floor data cost (EIP-7623)
if rules.IsPrague { if rules.IsPrague {
var err error
floorDataGas, err = FloorDataGas(msg.Data) floorDataGas, err = FloorDataGas(msg.Data)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -588,30 +588,20 @@ func (tx *Transaction) IntrinsicGas(rules *params.Rules) (uint64, error) {
// IntrinsicGas computes the 'intrinsic gas' for a message with the given data. // IntrinsicGas computes the 'intrinsic gas' for a message with the given data.
func IntrinsicGas(txdata TxData, rules *params.Rules) (uint64, error) { 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 // Set the starting gas for the raw transaction
var gas uint64 var gas uint64
if isContractCreation && rules.IsHomestead { if txdata.to() == nil && rules.IsHomestead {
gas = params.TxGasContractCreation gas = params.TxGasContractCreation
} else { } else {
gas = params.TxGas gas = params.TxGas
} }
dataLen := uint64(len(data)) dataLen := uint64(len(txdata.data()))
// Bump the required gas by the amount of transactional data // Bump the required gas by the amount of transactional data
if dataLen > 0 { if dataLen > 0 {
// Zero and non-zero bytes are priced differently // Zero and non-zero bytes are priced differently
var nz uint64 z := uint64(bytes.Count(txdata.data(), []byte{0}))
for _, byt := range data { nz := dataLen - z
if byt != 0 {
nz++
}
}
// Make sure we don't exceed uint64 for all data combinations // Make sure we don't exceed uint64 for all data combinations
nonZeroGas := params.TxDataNonZeroGasFrontier nonZeroGas := params.TxDataNonZeroGasFrontier
if rules.IsIstanbul { if rules.IsIstanbul {
@ -622,13 +612,12 @@ func IntrinsicGas(txdata TxData, rules *params.Rules) (uint64, error) {
} }
gas += nz * nonZeroGas gas += nz * nonZeroGas
z := dataLen - nz
if (math.MaxUint64-gas)/params.TxDataZeroGas < z { if (math.MaxUint64-gas)/params.TxDataZeroGas < z {
return 0, ErrGasUintOverflow return 0, ErrGasUintOverflow
} }
gas += z * params.TxDataZeroGas gas += z * params.TxDataZeroGas
if isContractCreation && rules.IsShanghai { if txdata.to() == nil && rules.IsShanghai {
lenWords := toWordSize(dataLen) lenWords := toWordSize(dataLen)
if (math.MaxUint64-gas)/params.InitCodeWordGas < lenWords { if (math.MaxUint64-gas)/params.InitCodeWordGas < lenWords {
return 0, ErrGasUintOverflow return 0, ErrGasUintOverflow
@ -636,12 +625,12 @@ func IntrinsicGas(txdata TxData, rules *params.Rules) (uint64, error) {
gas += lenWords * params.InitCodeWordGas gas += lenWords * params.InitCodeWordGas
} }
} }
if accessList != nil { if txdata.accessList() != nil {
gas += uint64(len(accessList)) * params.TxAccessListAddressGas gas += uint64(len(txdata.accessList())) * params.TxAccessListAddressGas
gas += uint64(accessList.StorageKeys()) * params.TxAccessListStorageKeyGas gas += uint64(txdata.accessList().StorageKeys()) * params.TxAccessListStorageKeyGas
} }
if authList != nil { if txdata.setCodeAuthorizations() != nil {
gas += uint64(len(authList)) * params.CallNewAccountGas gas += uint64(len(txdata.setCodeAuthorizations())) * params.CallNewAccountGas
} }
return gas, nil return gas, nil
} }