mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
core/vm, params: deprecate gastable, use both constant and dynamic gas
This commit is contained in:
parent
7ef08f1166
commit
be2827213a
4 changed files with 109 additions and 140 deletions
|
|
@ -59,11 +59,6 @@ func gasCallDataCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *St
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var overflow bool
|
|
||||||
if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
|
|
||||||
return 0, errGasUintOverflow
|
|
||||||
}
|
|
||||||
|
|
||||||
words, overflow := bigUint64(stack.Back(2))
|
words, overflow := bigUint64(stack.Back(2))
|
||||||
if overflow {
|
if overflow {
|
||||||
return 0, errGasUintOverflow
|
return 0, errGasUintOverflow
|
||||||
|
|
@ -85,11 +80,6 @@ func gasReturnDataCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var overflow bool
|
|
||||||
if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
|
|
||||||
return 0, errGasUintOverflow
|
|
||||||
}
|
|
||||||
|
|
||||||
words, overflow := bigUint64(stack.Back(2))
|
words, overflow := bigUint64(stack.Back(2))
|
||||||
if overflow {
|
if overflow {
|
||||||
return 0, errGasUintOverflow
|
return 0, errGasUintOverflow
|
||||||
|
|
@ -211,10 +201,6 @@ func gasSha3(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if gas, overflow = math.SafeAdd(gas, params.Sha3Gas); overflow {
|
|
||||||
return 0, errGasUintOverflow
|
|
||||||
}
|
|
||||||
|
|
||||||
wordGas, overflow := bigUint64(stack.Back(1))
|
wordGas, overflow := bigUint64(stack.Back(1))
|
||||||
if overflow {
|
if overflow {
|
||||||
return 0, errGasUintOverflow
|
return 0, errGasUintOverflow
|
||||||
|
|
@ -235,10 +221,6 @@ func gasCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack,
|
||||||
}
|
}
|
||||||
|
|
||||||
var overflow bool
|
var overflow bool
|
||||||
if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
|
|
||||||
return 0, errGasUintOverflow
|
|
||||||
}
|
|
||||||
|
|
||||||
wordGas, overflow := bigUint64(stack.Back(2))
|
wordGas, overflow := bigUint64(stack.Back(2))
|
||||||
if overflow {
|
if overflow {
|
||||||
return 0, errGasUintOverflow
|
return 0, errGasUintOverflow
|
||||||
|
|
@ -259,9 +241,6 @@ func gasExtCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Sta
|
||||||
}
|
}
|
||||||
|
|
||||||
var overflow bool
|
var overflow bool
|
||||||
if gas, overflow = math.SafeAdd(gas, gt.ExtcodeCopy); overflow {
|
|
||||||
return 0, errGasUintOverflow
|
|
||||||
}
|
|
||||||
|
|
||||||
wordGas, overflow := bigUint64(stack.Back(3))
|
wordGas, overflow := bigUint64(stack.Back(3))
|
||||||
if overflow {
|
if overflow {
|
||||||
|
|
@ -279,62 +258,26 @@ func gasExtCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Sta
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasMLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
func gasMLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
var overflow bool
|
return memoryGasCost(mem, memorySize)
|
||||||
gas, err := memoryGasCost(mem, memorySize)
|
|
||||||
if err != nil {
|
|
||||||
return 0, errGasUintOverflow
|
|
||||||
}
|
|
||||||
if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
|
|
||||||
return 0, errGasUintOverflow
|
|
||||||
}
|
|
||||||
return gas, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasMStore8(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
func gasMStore8(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
var overflow bool
|
return memoryGasCost(mem, memorySize)
|
||||||
gas, err := memoryGasCost(mem, memorySize)
|
|
||||||
if err != nil {
|
|
||||||
return 0, errGasUintOverflow
|
|
||||||
}
|
|
||||||
if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
|
|
||||||
return 0, errGasUintOverflow
|
|
||||||
}
|
|
||||||
return gas, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasMStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
func gasMStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
var overflow bool
|
return memoryGasCost(mem, memorySize)
|
||||||
gas, err := memoryGasCost(mem, memorySize)
|
|
||||||
if err != nil {
|
|
||||||
return 0, errGasUintOverflow
|
|
||||||
}
|
|
||||||
if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
|
|
||||||
return 0, errGasUintOverflow
|
|
||||||
}
|
|
||||||
return gas, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasCreate(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
func gasCreate(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
var overflow bool
|
return memoryGasCost(mem, memorySize)
|
||||||
gas, err := memoryGasCost(mem, memorySize)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
if gas, overflow = math.SafeAdd(gas, params.CreateGas); overflow {
|
|
||||||
return 0, errGasUintOverflow
|
|
||||||
}
|
|
||||||
return gas, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasCreate2(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
func gasCreate2(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
var overflow bool
|
|
||||||
gas, err := memoryGasCost(mem, memorySize)
|
gas, err := memoryGasCost(mem, memorySize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if gas, overflow = math.SafeAdd(gas, params.Create2Gas); overflow {
|
|
||||||
return 0, errGasUintOverflow
|
|
||||||
}
|
|
||||||
wordGas, overflow := bigUint64(stack.Back(2))
|
wordGas, overflow := bigUint64(stack.Back(2))
|
||||||
if overflow {
|
if overflow {
|
||||||
return 0, errGasUintOverflow
|
return 0, errGasUintOverflow
|
||||||
|
|
@ -349,11 +292,24 @@ func gasCreate2(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack,
|
||||||
return gas, nil
|
return gas, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func gasExp(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
func gasExpFrontier(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
expByteLen := uint64((stack.data[stack.len()-2].BitLen() + 7) / 8)
|
expByteLen := uint64((stack.data[stack.len()-2].BitLen() + 7) / 8)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
gas = expByteLen * gt.ExpByte // no overflow check required. Max is 256 * ExpByte gas
|
gas = expByteLen * params.ExpByteFrontier // no overflow check required. Max is 256 * ExpByte gas
|
||||||
|
overflow bool
|
||||||
|
)
|
||||||
|
if gas, overflow = math.SafeAdd(gas, params.ExpGas); overflow {
|
||||||
|
return 0, errGasUintOverflow
|
||||||
|
}
|
||||||
|
return gas, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func gasExpEip158(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
|
||||||
|
expByteLen := uint64((stack.data[stack.len()-2].BitLen() + 7) / 8)
|
||||||
|
|
||||||
|
var (
|
||||||
|
gas = expByteLen * params.ExpByteEip158 // no overflow check required. Max is 256 * ExpByte gas
|
||||||
overflow bool
|
overflow bool
|
||||||
)
|
)
|
||||||
if gas, overflow = math.SafeAdd(gas, params.ExpGas); overflow {
|
if gas, overflow = math.SafeAdd(gas, params.ExpGas); overflow {
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ func newConstantinopleInstructionSet() [256]operation {
|
||||||
}
|
}
|
||||||
instructionSet[CREATE2] = operation{
|
instructionSet[CREATE2] = operation{
|
||||||
execute: opCreate2,
|
execute: opCreate2,
|
||||||
|
constantGas: params.Create2Gas,
|
||||||
dynamicGas: gasCreate2,
|
dynamicGas: gasCreate2,
|
||||||
minStack: minStack(4, 1),
|
minStack: minStack(4, 1),
|
||||||
maxStack: maxStack(4, 1),
|
maxStack: maxStack(4, 1),
|
||||||
|
|
@ -131,6 +132,7 @@ func newByzantiumInstructionSet() [256]operation {
|
||||||
}
|
}
|
||||||
instructionSet[RETURNDATACOPY] = operation{
|
instructionSet[RETURNDATACOPY] = operation{
|
||||||
execute: opReturnDataCopy,
|
execute: opReturnDataCopy,
|
||||||
|
constantGas: GasFastestStep,
|
||||||
dynamicGas: gasReturnDataCopy,
|
dynamicGas: gasReturnDataCopy,
|
||||||
minStack: minStack(3, 0),
|
minStack: minStack(3, 0),
|
||||||
maxStack: maxStack(3, 0),
|
maxStack: maxStack(3, 0),
|
||||||
|
|
@ -152,6 +154,7 @@ func newByzantiumInstructionSet() [256]operation {
|
||||||
|
|
||||||
func newSpuriousDragonInstructionSet() [256]operation {
|
func newSpuriousDragonInstructionSet() [256]operation {
|
||||||
instructionSet := newTangerineWhistleInstructionSet()
|
instructionSet := newTangerineWhistleInstructionSet()
|
||||||
|
instructionSet[EXP].dynamicGas = gasExpEip158
|
||||||
return instructionSet
|
return instructionSet
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -161,6 +164,7 @@ func newTangerineWhistleInstructionSet() [256]operation {
|
||||||
instructionSet[BALANCE].constantGas = params.BalanceGasEip150
|
instructionSet[BALANCE].constantGas = params.BalanceGasEip150
|
||||||
instructionSet[EXTCODESIZE].constantGas = params.ExtcodeSizeGasEip150
|
instructionSet[EXTCODESIZE].constantGas = params.ExtcodeSizeGasEip150
|
||||||
instructionSet[SLOAD].constantGas = params.SloadGasEip150
|
instructionSet[SLOAD].constantGas = params.SloadGasEip150
|
||||||
|
instructionSet[EXTCODECOPY].constantGas = params.ExtcodeCopyBaseEip150
|
||||||
return instructionSet
|
return instructionSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,7 +261,7 @@ func newFrontierInstructionSet() [256]operation {
|
||||||
},
|
},
|
||||||
EXP: {
|
EXP: {
|
||||||
execute: opExp,
|
execute: opExp,
|
||||||
dynamicGas: gasExp,
|
dynamicGas: gasExpFrontier,
|
||||||
minStack: minStack(2, 1),
|
minStack: minStack(2, 1),
|
||||||
maxStack: maxStack(2, 1),
|
maxStack: maxStack(2, 1),
|
||||||
valid: true,
|
valid: true,
|
||||||
|
|
@ -348,6 +352,7 @@ func newFrontierInstructionSet() [256]operation {
|
||||||
},
|
},
|
||||||
SHA3: {
|
SHA3: {
|
||||||
execute: opSha3,
|
execute: opSha3,
|
||||||
|
constantGas: params.Sha3Gas,
|
||||||
dynamicGas: gasSha3,
|
dynamicGas: gasSha3,
|
||||||
minStack: minStack(2, 1),
|
minStack: minStack(2, 1),
|
||||||
maxStack: maxStack(2, 1),
|
maxStack: maxStack(2, 1),
|
||||||
|
|
@ -405,6 +410,7 @@ func newFrontierInstructionSet() [256]operation {
|
||||||
},
|
},
|
||||||
CALLDATACOPY: {
|
CALLDATACOPY: {
|
||||||
execute: opCallDataCopy,
|
execute: opCallDataCopy,
|
||||||
|
constantGas: GasFastestStep,
|
||||||
dynamicGas: gasCallDataCopy,
|
dynamicGas: gasCallDataCopy,
|
||||||
minStack: minStack(3, 0),
|
minStack: minStack(3, 0),
|
||||||
maxStack: maxStack(3, 0),
|
maxStack: maxStack(3, 0),
|
||||||
|
|
@ -420,6 +426,7 @@ func newFrontierInstructionSet() [256]operation {
|
||||||
},
|
},
|
||||||
CODECOPY: {
|
CODECOPY: {
|
||||||
execute: opCodeCopy,
|
execute: opCodeCopy,
|
||||||
|
constantGas: GasFastestStep,
|
||||||
dynamicGas: gasCodeCopy,
|
dynamicGas: gasCodeCopy,
|
||||||
minStack: minStack(3, 0),
|
minStack: minStack(3, 0),
|
||||||
maxStack: maxStack(3, 0),
|
maxStack: maxStack(3, 0),
|
||||||
|
|
@ -442,6 +449,7 @@ func newFrontierInstructionSet() [256]operation {
|
||||||
},
|
},
|
||||||
EXTCODECOPY: {
|
EXTCODECOPY: {
|
||||||
execute: opExtCodeCopy,
|
execute: opExtCodeCopy,
|
||||||
|
constantGas: params.ExtcodeCopyBaseFrontier,
|
||||||
dynamicGas: gasExtCodeCopy,
|
dynamicGas: gasExtCodeCopy,
|
||||||
minStack: minStack(4, 0),
|
minStack: minStack(4, 0),
|
||||||
maxStack: maxStack(4, 0),
|
maxStack: maxStack(4, 0),
|
||||||
|
|
@ -499,6 +507,7 @@ func newFrontierInstructionSet() [256]operation {
|
||||||
},
|
},
|
||||||
MLOAD: {
|
MLOAD: {
|
||||||
execute: opMload,
|
execute: opMload,
|
||||||
|
constantGas: GasFastestStep,
|
||||||
dynamicGas: gasMLoad,
|
dynamicGas: gasMLoad,
|
||||||
minStack: minStack(1, 1),
|
minStack: minStack(1, 1),
|
||||||
maxStack: maxStack(1, 1),
|
maxStack: maxStack(1, 1),
|
||||||
|
|
@ -507,6 +516,7 @@ func newFrontierInstructionSet() [256]operation {
|
||||||
},
|
},
|
||||||
MSTORE: {
|
MSTORE: {
|
||||||
execute: opMstore,
|
execute: opMstore,
|
||||||
|
constantGas: GasFastestStep,
|
||||||
dynamicGas: gasMStore,
|
dynamicGas: gasMStore,
|
||||||
minStack: minStack(2, 0),
|
minStack: minStack(2, 0),
|
||||||
maxStack: maxStack(2, 0),
|
maxStack: maxStack(2, 0),
|
||||||
|
|
@ -515,6 +525,7 @@ func newFrontierInstructionSet() [256]operation {
|
||||||
},
|
},
|
||||||
MSTORE8: {
|
MSTORE8: {
|
||||||
execute: opMstore8,
|
execute: opMstore8,
|
||||||
|
constantGas: GasFastestStep,
|
||||||
dynamicGas: gasMStore8,
|
dynamicGas: gasMStore8,
|
||||||
memorySize: memoryMStore8,
|
memorySize: memoryMStore8,
|
||||||
minStack: minStack(2, 0),
|
minStack: minStack(2, 0),
|
||||||
|
|
@ -1076,6 +1087,7 @@ func newFrontierInstructionSet() [256]operation {
|
||||||
},
|
},
|
||||||
CREATE: {
|
CREATE: {
|
||||||
execute: opCreate,
|
execute: opCreate,
|
||||||
|
constantGas: params.CreateGas,
|
||||||
dynamicGas: gasCreate,
|
dynamicGas: gasCreate,
|
||||||
minStack: minStack(3, 1),
|
minStack: minStack(3, 1),
|
||||||
maxStack: maxStack(3, 1),
|
maxStack: maxStack(3, 1),
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,7 @@ package params
|
||||||
|
|
||||||
// GasTable organizes gas prices for different ethereum phases.
|
// GasTable organizes gas prices for different ethereum phases.
|
||||||
type GasTable struct {
|
type GasTable struct {
|
||||||
ExtcodeCopy uint64
|
|
||||||
Calls uint64
|
Calls uint64
|
||||||
|
|
||||||
ExpByte uint64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Variables containing gas prices for different ethereum phases.
|
// Variables containing gas prices for different ethereum phases.
|
||||||
|
|
@ -29,23 +26,17 @@ var (
|
||||||
// GasTableHomestead contain the gas prices for
|
// GasTableHomestead contain the gas prices for
|
||||||
// the homestead phase.
|
// the homestead phase.
|
||||||
GasTableHomestead = GasTable{
|
GasTableHomestead = GasTable{
|
||||||
ExtcodeCopy: 20,
|
|
||||||
Calls: 40,
|
Calls: 40,
|
||||||
ExpByte: 10,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GasTableEIP150 contain the gas re-prices for
|
// GasTableEIP150 contain the gas re-prices for
|
||||||
// the EIP150 phase (a.k.a TangerineWhistle).
|
// the EIP150 phase (a.k.a TangerineWhistle).
|
||||||
GasTableEIP150 = GasTable{
|
GasTableEIP150 = GasTable{
|
||||||
ExtcodeCopy: 700,
|
|
||||||
Calls: 700,
|
Calls: 700,
|
||||||
ExpByte: 10,
|
|
||||||
}
|
}
|
||||||
// GasTableEIP158 contain the gas re-prices for
|
// GasTableEIP158 contain the gas re-prices for
|
||||||
// the EIP155/EIP158 phase (a.k.a Spurious Dragon).
|
// the EIP155/EIP158 phase (a.k.a Spurious Dragon).
|
||||||
GasTableEIP158 = GasTable{
|
GasTableEIP158 = GasTable{
|
||||||
ExtcodeCopy: 700,
|
|
||||||
Calls: 700,
|
Calls: 700,
|
||||||
ExpByte: 50,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,16 @@ const (
|
||||||
SloadGasEip150 uint64 = 200
|
SloadGasEip150 uint64 = 200
|
||||||
ExtcodeHashGas uint64 = 400 // Cost of EXTCODEHASH (introduced in Constantinople)
|
ExtcodeHashGas uint64 = 400 // Cost of EXTCODEHASH (introduced in Constantinople)
|
||||||
SuicideGasEip150 uint64 = 5000 // Cost of SELFDESTRUCT post T.W
|
SuicideGasEip150 uint64 = 5000 // Cost of SELFDESTRUCT post T.W
|
||||||
|
|
||||||
|
// EXP has a dynamic portion depending on the size of the exponent
|
||||||
|
ExpByteFrontier uint64 = 10 // was set to 10 in Frontier
|
||||||
|
ExpByteEip158 uint64 = 50 // was raised to 50 during Eip158 (Spurious Dragon)
|
||||||
|
|
||||||
|
// Extcodecopy has a dynamic AND a static cost. This represents only the
|
||||||
|
// static portion of the gas. It was changed during EIP 150 (Tangerine Whistle)
|
||||||
|
ExtcodeCopyBaseFrontier uint64 = 20
|
||||||
|
ExtcodeCopyBaseEip150 uint64 = 700
|
||||||
|
|
||||||
// CreateBySuicide occurs when the refunded account is one that does
|
// CreateBySuicide occurs when the refunded account is one that does
|
||||||
// not exist. This logic is similar to call.
|
// not exist. This logic is similar to call.
|
||||||
// Introduced in Tangerine Whistle (Eip 150)
|
// Introduced in Tangerine Whistle (Eip 150)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue