core, cores/types: added Gas field in Message, precomputed it and updated computation bytes count algo
This commit is contained in:
parent
ac108963fc
commit
cb3dddcbed
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue