|
|
@ -68,7 +68,7 @@ func (result *ExecutionResult) Revert() []byte { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 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(data []byte, accessList types.AccessList, isContractCreation, isHomestead, isEIP2028, isEIP3860 bool) (uint64, error) { |
|
|
|
func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation, isHomestead, isEIP2028, isEIP3860, isEIP7623 bool) (uint64, error) { |
|
|
|
// Set the starting gas for the raw transaction
|
|
|
|
// Set the starting gas for the raw transaction
|
|
|
|
var gas uint64 |
|
|
|
var gas uint64 |
|
|
|
if isContractCreation && isHomestead { |
|
|
|
if isContractCreation && isHomestead { |
|
|
@ -79,6 +79,15 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation, |
|
|
|
dataLen := uint64(len(data)) |
|
|
|
dataLen := uint64(len(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 { |
|
|
|
|
|
|
|
// Charge for the contract creation
|
|
|
|
|
|
|
|
if isContractCreation && isEIP3860 { |
|
|
|
|
|
|
|
lenWords := toWordSize(dataLen) |
|
|
|
|
|
|
|
if (math.MaxUint64-gas)/params.InitCodeWordGas < lenWords { |
|
|
|
|
|
|
|
return 0, ErrGasUintOverflow |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
gas += lenWords * params.InitCodeWordGas |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Zero and non-zero bytes are priced differently
|
|
|
|
// Zero and non-zero bytes are priced differently
|
|
|
|
var nz uint64 |
|
|
|
var nz uint64 |
|
|
|
for _, byt := range data { |
|
|
|
for _, byt := range data { |
|
|
@ -86,6 +95,7 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation, |
|
|
|
nz++ |
|
|
|
nz++ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
var gasForData uint64 |
|
|
|
// 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 isEIP2028 { |
|
|
|
if isEIP2028 { |
|
|
@ -94,21 +104,24 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation, |
|
|
|
if (math.MaxUint64-gas)/nonZeroGas < nz { |
|
|
|
if (math.MaxUint64-gas)/nonZeroGas < nz { |
|
|
|
return 0, ErrGasUintOverflow |
|
|
|
return 0, ErrGasUintOverflow |
|
|
|
} |
|
|
|
} |
|
|
|
gas += nz * nonZeroGas |
|
|
|
gasForData += nz * nonZeroGas |
|
|
|
|
|
|
|
|
|
|
|
z := dataLen - nz |
|
|
|
z := dataLen - nz |
|
|
|
if (math.MaxUint64-gas)/params.TxDataZeroGas < z { |
|
|
|
if (math.MaxUint64-gas-gasForData)/params.TxDataZeroGas < z { |
|
|
|
return 0, ErrGasUintOverflow |
|
|
|
return 0, ErrGasUintOverflow |
|
|
|
} |
|
|
|
} |
|
|
|
gas += z * params.TxDataZeroGas |
|
|
|
gasForData += z * params.TxDataZeroGas |
|
|
|
|
|
|
|
|
|
|
|
if isContractCreation && isEIP3860 { |
|
|
|
if isEIP7623 { |
|
|
|
lenWords := toWordSize(dataLen) |
|
|
|
tokens := z + nz*params.TokenPerNonZeroByte7623 |
|
|
|
if (math.MaxUint64-gas)/params.InitCodeWordGas < lenWords { |
|
|
|
if (math.MaxUint64-gas-gasForData)/params.CostFloorPerToken7623 < tokens { |
|
|
|
return 0, ErrGasUintOverflow |
|
|
|
return 0, ErrGasUintOverflow |
|
|
|
} |
|
|
|
} |
|
|
|
gas += lenWords * params.InitCodeWordGas |
|
|
|
if floor := params.CostFloorPerToken7623 * tokens; gasForData < floor { |
|
|
|
|
|
|
|
gasForData = floor |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
gas += gasForData |
|
|
|
} |
|
|
|
} |
|
|
|
if accessList != nil { |
|
|
|
if accessList != nil { |
|
|
|
gas += uint64(len(accessList)) * params.TxAccessListAddressGas |
|
|
|
gas += uint64(len(accessList)) * params.TxAccessListAddressGas |
|
|
@ -400,7 +413,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
// Check clauses 4-5, subtract intrinsic gas if everything is correct
|
|
|
|
// Check clauses 4-5, subtract intrinsic gas if everything is correct
|
|
|
|
gas, err := IntrinsicGas(msg.Data, msg.AccessList, contractCreation, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai) |
|
|
|
gas, err := IntrinsicGas(msg.Data, msg.AccessList, contractCreation, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai, false) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
} |
|
|
|