aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Holst Swende <martin@swende.se>2019-08-05 16:01:02 +0800
committerPéter Szilágyi <peterke@gmail.com>2019-08-05 16:01:02 +0800
commitaa6005b469fdd1aa7a95f501ce87908011f43159 (patch)
tree53a14d1b2f32798bbf22b2d74d4cbf16239b86b7
parenta7de796840eeb267e298bcc98cdaa3a538234bef (diff)
downloadgo-tangerine-aa6005b469fdd1aa7a95f501ce87908011f43159.tar
go-tangerine-aa6005b469fdd1aa7a95f501ce87908011f43159.tar.gz
go-tangerine-aa6005b469fdd1aa7a95f501ce87908011f43159.tar.bz2
go-tangerine-aa6005b469fdd1aa7a95f501ce87908011f43159.tar.lz
go-tangerine-aa6005b469fdd1aa7a95f501ce87908011f43159.tar.xz
go-tangerine-aa6005b469fdd1aa7a95f501ce87908011f43159.tar.zst
go-tangerine-aa6005b469fdd1aa7a95f501ce87908011f43159.zip
core/vm, params: refactor chain configuration (#19735)
* params, core/vm: deprecating gastable, part 1 * core/vm, params: deprecate gastable, use both constant and dynamic gas * core/vm, params: remove gastable, remove copypaste * core/vm: make use of the chainrules * interpreter: make tracing count constant+dynamic gas * core/vm: review concerns (param/method name changes) * core/vm: make use of chainrules more
-rw-r--r--core/vm/evm.go12
-rw-r--r--core/vm/gas.go10
-rw-r--r--core/vm/gas_table.go335
-rw-r--r--core/vm/instructions.go4
-rw-r--r--core/vm/interpreter.go28
-rw-r--r--core/vm/jump_table.go275
-rw-r--r--params/config.go19
-rw-r--r--params/gas_table.go93
-rw-r--r--params/protocol_params.go58
9 files changed, 329 insertions, 505 deletions
diff --git a/core/vm/evm.go b/core/vm/evm.go
index d47b00938..030f0c789 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -44,7 +44,7 @@ type (
func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, error) {
if contract.CodeAddr != nil {
precompiles := PrecompiledContractsHomestead
- if evm.ChainConfig().IsByzantium(evm.BlockNumber) {
+ if evm.chainRules.IsByzantium {
precompiles = PrecompiledContractsByzantium
}
if p := precompiles[*contract.CodeAddr]; p != nil {
@@ -203,10 +203,10 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
)
if !evm.StateDB.Exist(addr) {
precompiles := PrecompiledContractsHomestead
- if evm.ChainConfig().IsByzantium(evm.BlockNumber) {
+ if evm.chainRules.IsByzantium {
precompiles = PrecompiledContractsByzantium
}
- if precompiles[addr] == nil && evm.ChainConfig().IsEIP158(evm.BlockNumber) && value.Sign() == 0 {
+ if precompiles[addr] == nil && evm.chainRules.IsEIP158 && value.Sign() == 0 {
// Calling a non existing account, don't do anything, but ping the tracer
if evm.vmConfig.Debug && evm.depth == 0 {
evm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
@@ -394,7 +394,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
// Create a new account on the state
snapshot := evm.StateDB.Snapshot()
evm.StateDB.CreateAccount(address)
- if evm.ChainConfig().IsEIP158(evm.BlockNumber) {
+ if evm.chainRules.IsEIP158 {
evm.StateDB.SetNonce(address, 1)
}
evm.Transfer(evm.StateDB, caller.Address(), address, value)
@@ -416,7 +416,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
ret, err := run(evm, contract, nil, false)
// check whether the max code size has been exceeded
- maxCodeSizeExceeded := evm.ChainConfig().IsEIP158(evm.BlockNumber) && len(ret) > params.MaxCodeSize
+ maxCodeSizeExceeded := evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize
// if the contract creation ran successfully and no errors were returned
// calculate the gas required to store the code. If the code could not
// be stored due to not enough gas set an error and let it be handled
@@ -433,7 +433,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
// When an error was returned by the EVM or when setting the creation code
// above we revert to the snapshot and consume any gas remaining. Additionally
// when we're in homestead this also counts for code storage gas errors.
- if maxCodeSizeExceeded || (err != nil && (evm.ChainConfig().IsHomestead(evm.BlockNumber) || err != ErrCodeStoreOutOfGas)) {
+ if maxCodeSizeExceeded || (err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas)) {
evm.StateDB.RevertToSnapshot(snapshot)
if err != errExecutionReverted {
contract.UseGas(contract.Gas)
diff --git a/core/vm/gas.go b/core/vm/gas.go
index 022a84f24..bd8b4f104 100644
--- a/core/vm/gas.go
+++ b/core/vm/gas.go
@@ -18,8 +18,6 @@ package vm
import (
"math/big"
-
- "github.com/ethereum/go-ethereum/params"
)
// Gas costs
@@ -34,10 +32,10 @@ const (
// calcGas returns the actual gas cost of the call.
//
-// The cost of gas was changed during the homestead price change HF. To allow for EIP150
-// to be implemented. The returned gas is gas - base * 63 / 64.
-func callGas(gasTable params.GasTable, availableGas, base uint64, callCost *big.Int) (uint64, error) {
- if gasTable.CreateBySuicide > 0 {
+// The cost of gas was changed during the homestead price change HF.
+// As part of EIP 150 (TangerineWhistle), the returned gas is gas - base * 63 / 64.
+func callGas(isEip150 bool, availableGas, base uint64, callCost *big.Int) (uint64, error) {
+ if isEip150 {
availableGas = availableGas - base
gas := availableGas - availableGas/64
// If the bit length exceeds 64 bit we know that the newly calculated "gas" for EIP150
diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go
index 8270300ba..b2999fdea 100644
--- a/core/vm/gas_table.go
+++ b/core/vm/gas_table.go
@@ -53,59 +53,45 @@ func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) {
return 0, nil
}
-func gasCallDataCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- gas, err := memoryGasCost(mem, memorySize)
- if err != nil {
- return 0, err
- }
-
- var overflow bool
- if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
- return 0, errGasUintOverflow
- }
-
- words, overflow := bigUint64(stack.Back(2))
- if overflow {
- return 0, errGasUintOverflow
- }
+// memoryCopierGas creates the gas functions for the following opcodes, and takes
+// the stack position of the operand which determines the size of the data to copy
+// as argument:
+// CALLDATACOPY (stack position 2)
+// CODECOPY (stack position 2)
+// EXTCODECOPY (stack poition 3)
+// RETURNDATACOPY (stack position 2)
+func memoryCopierGas(stackpos int) gasFunc {
+ return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+ // Gas for expanding the memory
+ gas, err := memoryGasCost(mem, memorySize)
+ if err != nil {
+ return 0, err
+ }
+ // And gas for copying data, charged per word at param.CopyGas
+ words, overflow := bigUint64(stack.Back(stackpos))
+ if overflow {
+ return 0, errGasUintOverflow
+ }
- if words, overflow = math.SafeMul(toWordSize(words), params.CopyGas); overflow {
- return 0, errGasUintOverflow
- }
+ if words, overflow = math.SafeMul(toWordSize(words), params.CopyGas); overflow {
+ return 0, errGasUintOverflow
+ }
- if gas, overflow = math.SafeAdd(gas, words); overflow {
- return 0, errGasUintOverflow
+ if gas, overflow = math.SafeAdd(gas, words); overflow {
+ return 0, errGasUintOverflow
+ }
+ return gas, nil
}
- return gas, nil
}
-func gasReturnDataCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- gas, err := memoryGasCost(mem, memorySize)
- if err != nil {
- return 0, err
- }
-
- var overflow bool
- if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
- return 0, errGasUintOverflow
- }
-
- words, overflow := bigUint64(stack.Back(2))
- if overflow {
- return 0, errGasUintOverflow
- }
-
- if words, overflow = math.SafeMul(toWordSize(words), params.CopyGas); overflow {
- return 0, errGasUintOverflow
- }
-
- if gas, overflow = math.SafeAdd(gas, words); overflow {
- return 0, errGasUintOverflow
- }
- return gas, nil
-}
+var (
+ gasCallDataCopy = memoryCopierGas(2)
+ gasCodeCopy = memoryCopierGas(2)
+ gasExtCodeCopy = memoryCopierGas(3)
+ gasReturnDataCopy = memoryCopierGas(2)
+)
-func gasSStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
var (
y, x = stack.Back(1), stack.Back(0)
current = evm.StateDB.GetState(contract.Address(), common.BigToHash(x))
@@ -175,7 +161,7 @@ func gasSStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, m
}
func makeGasLog(n uint64) gasFunc {
- return func(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+ return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
requestedSize, overflow := bigUint64(stack.Back(1))
if overflow {
return 0, errGasUintOverflow
@@ -204,17 +190,11 @@ func makeGasLog(n uint64) gasFunc {
}
}
-func gasSha3(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- var overflow bool
+func gasSha3(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
return 0, err
}
-
- if gas, overflow = math.SafeAdd(gas, params.Sha3Gas); overflow {
- return 0, errGasUintOverflow
- }
-
wordGas, overflow := bigUint64(stack.Back(1))
if overflow {
return 0, errGasUintOverflow
@@ -228,117 +208,27 @@ func gasSha3(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem
return gas, nil
}
-func gasCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- gas, err := memoryGasCost(mem, memorySize)
- if err != nil {
- return 0, err
- }
-
- var overflow bool
- if gas, overflow = math.SafeAdd(gas, GasFastestStep); overflow {
- return 0, errGasUintOverflow
- }
-
- wordGas, overflow := bigUint64(stack.Back(2))
- if overflow {
- return 0, errGasUintOverflow
- }
- if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.CopyGas); overflow {
- return 0, errGasUintOverflow
- }
- if gas, overflow = math.SafeAdd(gas, wordGas); overflow {
- return 0, errGasUintOverflow
- }
- return gas, nil
-}
-
-func gasExtCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- gas, err := memoryGasCost(mem, memorySize)
- if err != nil {
- return 0, err
- }
-
- var overflow bool
- if gas, overflow = math.SafeAdd(gas, gt.ExtcodeCopy); overflow {
- return 0, errGasUintOverflow
- }
-
- wordGas, overflow := bigUint64(stack.Back(3))
- if overflow {
- return 0, errGasUintOverflow
- }
-
- if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.CopyGas); overflow {
- return 0, errGasUintOverflow
- }
-
- if gas, overflow = math.SafeAdd(gas, wordGas); overflow {
- return 0, errGasUintOverflow
- }
- return gas, nil
-}
-
-func gasExtCodeHash(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- return gt.ExtcodeHash, nil
-}
-
-func gasMLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- var overflow bool
- 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) {
- var overflow bool
- 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) {
- var overflow bool
- 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
+// pureMemoryGascost is used by several operations, which aside from their
+// static cost have a dynamic cost which is solely based on the memory
+// expansion
+func pureMemoryGascost(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+ return memoryGasCost(mem, memorySize)
}
-func gasCreate(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- var overflow bool
- 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
-}
+var (
+ gasReturn = pureMemoryGascost
+ gasRevert = pureMemoryGascost
+ gasMLoad = pureMemoryGascost
+ gasMStore8 = pureMemoryGascost
+ gasMStore = pureMemoryGascost
+ gasCreate = pureMemoryGascost
+)
-func gasCreate2(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- var overflow bool
+func gasCreate2(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
return 0, err
}
- if gas, overflow = math.SafeAdd(gas, params.Create2Gas); overflow {
- return 0, errGasUintOverflow
- }
wordGas, overflow := bigUint64(stack.Back(2))
if overflow {
return 0, errGasUintOverflow
@@ -349,27 +239,27 @@ func gasCreate2(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack,
if gas, overflow = math.SafeAdd(gas, wordGas); overflow {
return 0, errGasUintOverflow
}
-
return gas, nil
}
-func gasBalance(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- return gt.Balance, nil
-}
-
-func gasExtCodeSize(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- return gt.ExtcodeSize, nil
-}
+func gasExpFrontier(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+ expByteLen := uint64((stack.data[stack.len()-2].BitLen() + 7) / 8)
-func gasSLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- return gt.SLoad, nil
+ var (
+ 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 gasExp(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+func gasExpEIP158(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 * gt.ExpByte // no overflow check required. Max is 256 * ExpByte gas
+ gas = expByteLen * params.ExpByteEIP158 // no overflow check required. Max is 256 * ExpByte gas
overflow bool
)
if gas, overflow = math.SafeAdd(gas, params.ExpGas); overflow {
@@ -378,14 +268,13 @@ func gasExp(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem
return gas, nil
}
-func gasCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
var (
- gas = gt.Calls
+ gas uint64
transfersValue = stack.Back(2).Sign() != 0
address = common.BigToAddress(stack.Back(1))
- eip158 = evm.ChainConfig().IsEIP158(evm.BlockNumber)
)
- if eip158 {
+ if evm.chainRules.IsEIP158 {
if transfersValue && evm.StateDB.Empty(address) {
gas += params.CallNewAccountGas
}
@@ -404,7 +293,7 @@ func gasCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem
return 0, errGasUintOverflow
}
- evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
+ evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
if err != nil {
return 0, err
}
@@ -414,21 +303,22 @@ func gasCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem
return gas, nil
}
-func gasCallCode(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- gas := gt.Calls
- if stack.Back(2).Sign() != 0 {
- gas += params.CallValueTransferGas
- }
+func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
memoryGas, err := memoryGasCost(mem, memorySize)
if err != nil {
return 0, err
}
- var overflow bool
+ var (
+ gas uint64
+ overflow bool
+ )
+ if stack.Back(2).Sign() != 0 {
+ gas += params.CallValueTransferGas
+ }
if gas, overflow = math.SafeAdd(gas, memoryGas); overflow {
return 0, errGasUintOverflow
}
-
- evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
+ evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
if err != nil {
return 0, err
}
@@ -438,76 +328,57 @@ func gasCallCode(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack,
return gas, nil
}
-func gasReturn(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- return memoryGasCost(mem, memorySize)
-}
-
-func gasRevert(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- return memoryGasCost(mem, memorySize)
-}
-
-func gasSuicide(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
- var gas uint64
- // EIP150 homestead gas reprice fork:
- if evm.ChainConfig().IsEIP150(evm.BlockNumber) {
- gas = gt.Suicide
- var (
- address = common.BigToAddress(stack.Back(0))
- eip158 = evm.ChainConfig().IsEIP158(evm.BlockNumber)
- )
-
- if eip158 {
- // if empty and transfers value
- if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 {
- gas += gt.CreateBySuicide
- }
- } else if !evm.StateDB.Exist(address) {
- gas += gt.CreateBySuicide
- }
- }
-
- if !evm.StateDB.HasSuicided(contract.Address()) {
- evm.StateDB.AddRefund(params.SuicideRefundGas)
- }
- return gas, nil
-}
-
-func gasDelegateCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+func gasDelegateCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
return 0, err
}
- var overflow bool
- if gas, overflow = math.SafeAdd(gas, gt.Calls); overflow {
- return 0, errGasUintOverflow
- }
-
- evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
+ evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
if err != nil {
return 0, err
}
+ var overflow bool
if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
return 0, errGasUintOverflow
}
return gas, nil
}
-func gasStaticCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
return 0, err
}
- var overflow bool
- if gas, overflow = math.SafeAdd(gas, gt.Calls); overflow {
- return 0, errGasUintOverflow
- }
-
- evm.callGasTemp, err = callGas(gt, contract.Gas, gas, stack.Back(0))
+ evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0))
if err != nil {
return 0, err
}
+ var overflow bool
if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
return 0, errGasUintOverflow
}
return gas, nil
}
+
+func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
+ var gas uint64
+ // EIP150 homestead gas reprice fork:
+ if evm.chainRules.IsEIP150 {
+ gas = params.SelfdestructGasEIP150
+ var address = common.BigToAddress(stack.Back(0))
+
+ if evm.chainRules.IsEIP158 {
+ // if empty and transfers value
+ if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 {
+ gas += params.CreateBySelfdestructGas
+ }
+ } else if !evm.StateDB.Exist(address) {
+ gas += params.CreateBySelfdestructGas
+ }
+ }
+
+ if !evm.StateDB.HasSuicided(contract.Address()) {
+ evm.StateDB.AddRefund(params.SelfdestructRefundGas)
+ }
+ return gas, nil
+}
diff --git a/core/vm/instructions.go b/core/vm/instructions.go
index 2a062d7e7..7b6909c92 100644
--- a/core/vm/instructions.go
+++ b/core/vm/instructions.go
@@ -694,7 +694,7 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memor
input = memory.Get(offset.Int64(), size.Int64())
gas = contract.Gas
)
- if interpreter.evm.ChainConfig().IsEIP150(interpreter.evm.BlockNumber) {
+ if interpreter.evm.chainRules.IsEIP150 {
gas -= gas / 64
}
@@ -704,7 +704,7 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memor
// homestead we must check for CodeStoreOutOfGasError (homestead only
// rule) and treat as an error, if the ruleset is frontier we must
// ignore this error and pretend the operation was successful.
- if interpreter.evm.ChainConfig().IsHomestead(interpreter.evm.BlockNumber) && suberr == ErrCodeStoreOutOfGas {
+ if interpreter.evm.chainRules.IsHomestead && suberr == ErrCodeStoreOutOfGas {
stack.push(interpreter.intPool.getZero())
} else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
stack.push(interpreter.intPool.getZero())
diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go
index 989f85f5d..18081ec4c 100644
--- a/core/vm/interpreter.go
+++ b/core/vm/interpreter.go
@@ -23,7 +23,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/params"
)
// Config are the configuration options for the Interpreter
@@ -71,9 +70,8 @@ type keccakState interface {
// EVMInterpreter represents an EVM interpreter
type EVMInterpreter struct {
- evm *EVM
- cfg Config
- gasTable params.GasTable
+ evm *EVM
+ cfg Config
intPool *intPool
@@ -91,11 +89,15 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
// we'll set the default jump table.
if !cfg.JumpTable[STOP].valid {
switch {
- case evm.ChainConfig().IsConstantinople(evm.BlockNumber):
+ case evm.chainRules.IsConstantinople:
cfg.JumpTable = constantinopleInstructionSet
- case evm.ChainConfig().IsByzantium(evm.BlockNumber):
+ case evm.chainRules.IsByzantium:
cfg.JumpTable = byzantiumInstructionSet
- case evm.ChainConfig().IsHomestead(evm.BlockNumber):
+ case evm.chainRules.IsEIP158:
+ cfg.JumpTable = spuriousDragonInstructionSet
+ case evm.chainRules.IsEIP150:
+ cfg.JumpTable = tangerineWhistleInstructionSet
+ case evm.chainRules.IsHomestead:
cfg.JumpTable = homesteadInstructionSet
default:
cfg.JumpTable = frontierInstructionSet
@@ -103,9 +105,8 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
}
return &EVMInterpreter{
- evm: evm,
- cfg: cfg,
- gasTable: evm.ChainConfig().GasTable(evm.BlockNumber),
+ evm: evm,
+ cfg: cfg,
}
}
@@ -210,6 +211,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
}
}
// Static portion of gas
+ cost = operation.constantGas // For tracing
if !contract.UseGas(operation.constantGas) {
return nil, ErrOutOfGas
}
@@ -234,8 +236,10 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
// consume the gas and return an error if not enough gas is available.
// cost is explicitly set so that the capture state defer method can get the proper cost
if operation.dynamicGas != nil {
- cost, err = operation.dynamicGas(in.gasTable, in.evm, contract, stack, mem, memorySize)
- if err != nil || !contract.UseGas(cost) {
+ var dynamicCost uint64
+ dynamicCost, err = operation.dynamicGas(in.evm, contract, stack, mem, memorySize)
+ cost += dynamicCost // total cost, for debug tracing
+ if err != nil || !contract.UseGas(dynamicCost) {
return nil, ErrOutOfGas
}
}
diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go
index 425436f9e..a14f3fd98 100644
--- a/core/vm/jump_table.go
+++ b/core/vm/jump_table.go
@@ -24,7 +24,7 @@ import (
type (
executionFunc func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)
- gasFunc func(params.GasTable, *EVM, *Contract, *Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64
+ gasFunc func(*EVM, *Contract, *Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64
// memorySizeFunc returns the required size, and whether the operation overflowed a uint64
memorySizeFunc func(*Stack) (size uint64, overflow bool)
)
@@ -54,10 +54,12 @@ type operation struct {
}
var (
- frontierInstructionSet = newFrontierInstructionSet()
- homesteadInstructionSet = newHomesteadInstructionSet()
- byzantiumInstructionSet = newByzantiumInstructionSet()
- constantinopleInstructionSet = newConstantinopleInstructionSet()
+ frontierInstructionSet = newFrontierInstructionSet()
+ homesteadInstructionSet = newHomesteadInstructionSet()
+ tangerineWhistleInstructionSet = newTangerineWhistleInstructionSet()
+ spuriousDragonInstructionSet = newSpuriousDragonInstructionSet()
+ byzantiumInstructionSet = newByzantiumInstructionSet()
+ constantinopleInstructionSet = newConstantinopleInstructionSet()
)
// NewConstantinopleInstructionSet returns the frontier, homestead
@@ -87,21 +89,22 @@ func newConstantinopleInstructionSet() [256]operation {
valid: true,
}
instructionSet[EXTCODEHASH] = operation{
- execute: opExtCodeHash,
- dynamicGas: gasExtCodeHash,
- minStack: minStack(1, 1),
- maxStack: maxStack(1, 1),
- valid: true,
+ execute: opExtCodeHash,
+ constantGas: params.ExtcodeHashGas,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
}
instructionSet[CREATE2] = operation{
- execute: opCreate2,
- dynamicGas: gasCreate2,
- minStack: minStack(4, 1),
- maxStack: maxStack(4, 1),
- memorySize: memoryCreate2,
- valid: true,
- writes: true,
- returns: true,
+ execute: opCreate2,
+ constantGas: params.Create2Gas,
+ dynamicGas: gasCreate2,
+ minStack: minStack(4, 1),
+ maxStack: maxStack(4, 1),
+ memorySize: memoryCreate2,
+ valid: true,
+ writes: true,
+ returns: true,
}
return instructionSet
}
@@ -110,15 +113,16 @@ func newConstantinopleInstructionSet() [256]operation {
// byzantium instructions.
func newByzantiumInstructionSet() [256]operation {
// instructions that can be executed during the homestead phase.
- instructionSet := newHomesteadInstructionSet()
+ instructionSet := newSpuriousDragonInstructionSet()
instructionSet[STATICCALL] = operation{
- execute: opStaticCall,
- dynamicGas: gasStaticCall,
- minStack: minStack(6, 1),
- maxStack: maxStack(6, 1),
- memorySize: memoryStaticCall,
- valid: true,
- returns: true,
+ execute: opStaticCall,
+ constantGas: params.CallGasEIP150,
+ dynamicGas: gasStaticCall,
+ minStack: minStack(6, 1),
+ maxStack: maxStack(6, 1),
+ memorySize: memoryStaticCall,
+ valid: true,
+ returns: true,
}
instructionSet[RETURNDATASIZE] = operation{
execute: opReturnDataSize,
@@ -128,12 +132,13 @@ func newByzantiumInstructionSet() [256]operation {
valid: true,
}
instructionSet[RETURNDATACOPY] = operation{
- execute: opReturnDataCopy,
- dynamicGas: gasReturnDataCopy,
- minStack: minStack(3, 0),
- maxStack: maxStack(3, 0),
- memorySize: memoryReturnDataCopy,
- valid: true,
+ execute: opReturnDataCopy,
+ constantGas: GasFastestStep,
+ dynamicGas: gasReturnDataCopy,
+ minStack: minStack(3, 0),
+ maxStack: maxStack(3, 0),
+ memorySize: memoryReturnDataCopy,
+ valid: true,
}
instructionSet[REVERT] = operation{
execute: opRevert,
@@ -148,18 +153,40 @@ func newByzantiumInstructionSet() [256]operation {
return instructionSet
}
+// EIP 158 a.k.a Spurious Dragon
+func newSpuriousDragonInstructionSet() [256]operation {
+ instructionSet := newTangerineWhistleInstructionSet()
+ instructionSet[EXP].dynamicGas = gasExpEIP158
+ return instructionSet
+
+}
+
+// EIP 150 a.k.a Tangerine Whistle
+func newTangerineWhistleInstructionSet() [256]operation {
+ instructionSet := newHomesteadInstructionSet()
+ instructionSet[BALANCE].constantGas = params.BalanceGasEIP150
+ instructionSet[EXTCODESIZE].constantGas = params.ExtcodeSizeGasEIP150
+ instructionSet[SLOAD].constantGas = params.SloadGasEIP150
+ instructionSet[EXTCODECOPY].constantGas = params.ExtcodeCopyBaseEIP150
+ instructionSet[CALL].constantGas = params.CallGasEIP150
+ instructionSet[CALLCODE].constantGas = params.CallGasEIP150
+ instructionSet[DELEGATECALL].constantGas = params.CallGasEIP150
+ return instructionSet
+}
+
// NewHomesteadInstructionSet returns the frontier and homestead
// instructions that can be executed during the homestead phase.
func newHomesteadInstructionSet() [256]operation {
instructionSet := newFrontierInstructionSet()
instructionSet[DELEGATECALL] = operation{
- execute: opDelegateCall,
- dynamicGas: gasDelegateCall,
- minStack: minStack(6, 1),
- maxStack: maxStack(6, 1),
- memorySize: memoryDelegateCall,
- valid: true,
- returns: true,
+ execute: opDelegateCall,
+ dynamicGas: gasDelegateCall,
+ constantGas: params.CallGasFrontier,
+ minStack: minStack(6, 1),
+ maxStack: maxStack(6, 1),
+ memorySize: memoryDelegateCall,
+ valid: true,
+ returns: true,
}
return instructionSet
}
@@ -241,7 +268,7 @@ func newFrontierInstructionSet() [256]operation {
},
EXP: {
execute: opExp,
- dynamicGas: gasExp,
+ dynamicGas: gasExpFrontier,
minStack: minStack(2, 1),
maxStack: maxStack(2, 1),
valid: true,
@@ -331,12 +358,13 @@ func newFrontierInstructionSet() [256]operation {
valid: true,
},
SHA3: {
- execute: opSha3,
- dynamicGas: gasSha3,
- minStack: minStack(2, 1),
- maxStack: maxStack(2, 1),
- memorySize: memorySha3,
- valid: true,
+ execute: opSha3,
+ constantGas: params.Sha3Gas,
+ dynamicGas: gasSha3,
+ minStack: minStack(2, 1),
+ maxStack: maxStack(2, 1),
+ memorySize: memorySha3,
+ valid: true,
},
ADDRESS: {
execute: opAddress,
@@ -346,11 +374,11 @@ func newFrontierInstructionSet() [256]operation {
valid: true,
},
BALANCE: {
- execute: opBalance,
- dynamicGas: gasBalance,
- minStack: minStack(1, 1),
- maxStack: maxStack(1, 1),
- valid: true,
+ execute: opBalance,
+ constantGas: params.BalanceGasFrontier,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
},
ORIGIN: {
execute: opOrigin,
@@ -388,12 +416,13 @@ func newFrontierInstructionSet() [256]operation {
valid: true,
},
CALLDATACOPY: {
- execute: opCallDataCopy,
- dynamicGas: gasCallDataCopy,
- minStack: minStack(3, 0),
- maxStack: maxStack(3, 0),
- memorySize: memoryCallDataCopy,
- valid: true,
+ execute: opCallDataCopy,
+ constantGas: GasFastestStep,
+ dynamicGas: gasCallDataCopy,
+ minStack: minStack(3, 0),
+ maxStack: maxStack(3, 0),
+ memorySize: memoryCallDataCopy,
+ valid: true,
},
CODESIZE: {
execute: opCodeSize,
@@ -403,12 +432,13 @@ func newFrontierInstructionSet() [256]operation {
valid: true,
},
CODECOPY: {
- execute: opCodeCopy,
- dynamicGas: gasCodeCopy,
- minStack: minStack(3, 0),
- maxStack: maxStack(3, 0),
- memorySize: memoryCodeCopy,
- valid: true,
+ execute: opCodeCopy,
+ constantGas: GasFastestStep,
+ dynamicGas: gasCodeCopy,
+ minStack: minStack(3, 0),
+ maxStack: maxStack(3, 0),
+ memorySize: memoryCodeCopy,
+ valid: true,
},
GASPRICE: {
execute: opGasprice,
@@ -418,19 +448,20 @@ func newFrontierInstructionSet() [256]operation {
valid: true,
},
EXTCODESIZE: {
- execute: opExtCodeSize,
- dynamicGas: gasExtCodeSize,
- minStack: minStack(1, 1),
- maxStack: maxStack(1, 1),
- valid: true,
+ execute: opExtCodeSize,
+ constantGas: params.ExtcodeSizeGasFrontier,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
},
EXTCODECOPY: {
- execute: opExtCodeCopy,
- dynamicGas: gasExtCodeCopy,
- minStack: minStack(4, 0),
- maxStack: maxStack(4, 0),
- memorySize: memoryExtCodeCopy,
- valid: true,
+ execute: opExtCodeCopy,
+ constantGas: params.ExtcodeCopyBaseFrontier,
+ dynamicGas: gasExtCodeCopy,
+ minStack: minStack(4, 0),
+ maxStack: maxStack(4, 0),
+ memorySize: memoryExtCodeCopy,
+ valid: true,
},
BLOCKHASH: {
execute: opBlockhash,
@@ -482,36 +513,39 @@ func newFrontierInstructionSet() [256]operation {
valid: true,
},
MLOAD: {
- execute: opMload,
- dynamicGas: gasMLoad,
- minStack: minStack(1, 1),
- maxStack: maxStack(1, 1),
- memorySize: memoryMLoad,
- valid: true,
+ execute: opMload,
+ constantGas: GasFastestStep,
+ dynamicGas: gasMLoad,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ memorySize: memoryMLoad,
+ valid: true,
},
MSTORE: {
- execute: opMstore,
- dynamicGas: gasMStore,
- minStack: minStack(2, 0),
- maxStack: maxStack(2, 0),
- memorySize: memoryMStore,
- valid: true,
+ execute: opMstore,
+ constantGas: GasFastestStep,
+ dynamicGas: gasMStore,
+ minStack: minStack(2, 0),
+ maxStack: maxStack(2, 0),
+ memorySize: memoryMStore,
+ valid: true,
},
MSTORE8: {
- execute: opMstore8,
- dynamicGas: gasMStore8,
- memorySize: memoryMStore8,
- minStack: minStack(2, 0),
- maxStack: maxStack(2, 0),
+ execute: opMstore8,
+ constantGas: GasFastestStep,
+ dynamicGas: gasMStore8,
+ memorySize: memoryMStore8,
+ minStack: minStack(2, 0),
+ maxStack: maxStack(2, 0),
valid: true,
},
SLOAD: {
- execute: opSload,
- dynamicGas: gasSLoad,
- minStack: minStack(1, 1),
- maxStack: maxStack(1, 1),
- valid: true,
+ execute: opSload,
+ constantGas: params.SloadGasFrontier,
+ minStack: minStack(1, 1),
+ maxStack: maxStack(1, 1),
+ valid: true,
},
SSTORE: {
execute: opSstore,
@@ -1059,32 +1093,35 @@ func newFrontierInstructionSet() [256]operation {
writes: true,
},
CREATE: {
- execute: opCreate,
- dynamicGas: gasCreate,
- minStack: minStack(3, 1),
- maxStack: maxStack(3, 1),
- memorySize: memoryCreate,
- valid: true,
- writes: true,
- returns: true,
+ execute: opCreate,
+ constantGas: params.CreateGas,
+ dynamicGas: gasCreate,
+ minStack: minStack(3, 1),
+ maxStack: maxStack(3, 1),
+ memorySize: memoryCreate,
+ valid: true,
+ writes: true,
+ returns: true,
},
CALL: {
- execute: opCall,
- dynamicGas: gasCall,
- minStack: minStack(7, 1),
- maxStack: maxStack(7, 1),
- memorySize: memoryCall,
- valid: true,
- returns: true,
+ execute: opCall,
+ constantGas: params.CallGasFrontier,
+ dynamicGas: gasCall,
+ minStack: minStack(7, 1),
+ maxStack: maxStack(7, 1),
+ memorySize: memoryCall,
+ valid: true,
+ returns: true,
},
CALLCODE: {
- execute: opCallCode,
- dynamicGas: gasCallCode,
- minStack: minStack(7, 1),
- maxStack: maxStack(7, 1),
- memorySize: memoryCall,
- valid: true,
- returns: true,
+ execute: opCallCode,
+ constantGas: params.CallGasFrontier,
+ dynamicGas: gasCallCode,
+ minStack: minStack(7, 1),
+ maxStack: maxStack(7, 1),
+ memorySize: memoryCall,
+ valid: true,
+ returns: true,
},
RETURN: {
execute: opReturn,
@@ -1097,7 +1134,7 @@ func newFrontierInstructionSet() [256]operation {
},
SELFDESTRUCT: {
execute: opSuicide,
- dynamicGas: gasSuicide,
+ dynamicGas: gasSelfdestruct,
minStack: minStack(1, 0),
maxStack: maxStack(1, 0),
halts: true,
diff --git a/params/config.go b/params/config.go
index 2c7be848a..8c40b797d 100644
--- a/params/config.go
+++ b/params/config.go
@@ -386,25 +386,6 @@ func (c *ChainConfig) IsEWASM(num *big.Int) bool {
return isForked(c.EWASMBlock, num)
}
-// GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice).
-//
-// The returned GasTable's fields shouldn't, under any circumstances, be changed.
-func (c *ChainConfig) GasTable(num *big.Int) GasTable {
- if num == nil {
- return GasTableHomestead
- }
- switch {
- case c.IsConstantinople(num):
- return GasTableConstantinople
- case c.IsEIP158(num):
- return GasTableEIP158
- case c.IsEIP150(num):
- return GasTableEIP150
- default:
- return GasTableHomestead
- }
-}
-
// CheckCompatible checks whether scheduled fork transitions have been imported
// with a mismatching chain configuration.
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
diff --git a/params/gas_table.go b/params/gas_table.go
deleted file mode 100644
index 6c4a38269..000000000
--- a/params/gas_table.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package params
-
-// GasTable organizes gas prices for different ethereum phases.
-type GasTable struct {
- ExtcodeSize uint64
- ExtcodeCopy uint64
- ExtcodeHash uint64
- Balance uint64
- SLoad uint64
- Calls uint64
- Suicide uint64
-
- ExpByte uint64
-
- // CreateBySuicide occurs when the
- // refunded account is one that does
- // not exist. This logic is similar
- // to call. May be left nil. Nil means
- // not charged.
- CreateBySuicide uint64
-}
-
-// Variables containing gas prices for different ethereum phases.
-var (
- // GasTableHomestead contain the gas prices for
- // the homestead phase.
- GasTableHomestead = GasTable{
- ExtcodeSize: 20,
- ExtcodeCopy: 20,
- Balance: 20,
- SLoad: 50,
- Calls: 40,
- Suicide: 0,
- ExpByte: 10,
- }
-
- // GasTableEIP150 contain the gas re-prices for
- // the EIP150 phase.
- GasTableEIP150 = GasTable{
- ExtcodeSize: 700,
- ExtcodeCopy: 700,
- Balance: 400,
- SLoad: 200,
- Calls: 700,
- Suicide: 5000,
- ExpByte: 10,
-
- CreateBySuicide: 25000,
- }
- // GasTableEIP158 contain the gas re-prices for
- // the EIP155/EIP158 phase.
- GasTableEIP158 = GasTable{
- ExtcodeSize: 700,
- ExtcodeCopy: 700,
- Balance: 400,
- SLoad: 200,
- Calls: 700,
- Suicide: 5000,
- ExpByte: 50,
-
- CreateBySuicide: 25000,
- }
- // GasTableConstantinople contain the gas re-prices for
- // the constantinople phase.
- GasTableConstantinople = GasTable{
- ExtcodeSize: 700,
- ExtcodeCopy: 700,
- ExtcodeHash: 400,
- Balance: 400,
- SLoad: 200,
- Calls: 700,
- Suicide: 5000,
- ExpByte: 50,
-
- CreateBySuicide: 25000,
- }
-)
diff --git a/params/protocol_params.go b/params/protocol_params.go
index 14750f6a1..01dc197af 100644
--- a/params/protocol_params.go
+++ b/params/protocol_params.go
@@ -52,22 +52,48 @@ const (
NetSstoreResetRefund uint64 = 4800 // Once per SSTORE operation for resetting to the original non-zero value
NetSstoreResetClearRefund uint64 = 19800 // Once per SSTORE operation for resetting to the original zero value
- JumpdestGas uint64 = 1 // Once per JUMPDEST operation.
- EpochDuration uint64 = 30000 // Duration between proof-of-work epochs.
- CallGas uint64 = 40 // Once per CALL operation & message call transaction.
- CreateDataGas uint64 = 200 //
- CallCreateDepth uint64 = 1024 // Maximum depth of call/create stack.
- ExpGas uint64 = 10 // Once per EXP instruction
- LogGas uint64 = 375 // Per LOG* operation.
- CopyGas uint64 = 3 //
- StackLimit uint64 = 1024 // Maximum size of VM stack allowed.
- TierStepGas uint64 = 0 // Once per operation, for a selection of them.
- LogTopicGas uint64 = 375 // Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas.
- CreateGas uint64 = 32000 // Once per CREATE operation & contract-creation transaction.
- Create2Gas uint64 = 32000 // Once per CREATE2 operation
- SuicideRefundGas uint64 = 24000 // Refunded following a suicide operation.
- MemoryGas uint64 = 3 // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL.
- TxDataNonZeroGas uint64 = 68 // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions.
+ JumpdestGas uint64 = 1 // Once per JUMPDEST operation.
+ EpochDuration uint64 = 30000 // Duration between proof-of-work epochs.
+
+ CreateDataGas uint64 = 200 //
+ CallCreateDepth uint64 = 1024 // Maximum depth of call/create stack.
+ ExpGas uint64 = 10 // Once per EXP instruction
+ LogGas uint64 = 375 // Per LOG* operation.
+ CopyGas uint64 = 3 //
+ StackLimit uint64 = 1024 // Maximum size of VM stack allowed.
+ TierStepGas uint64 = 0 // Once per operation, for a selection of them.
+ LogTopicGas uint64 = 375 // Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas.
+ CreateGas uint64 = 32000 // Once per CREATE operation & contract-creation transaction.
+ Create2Gas uint64 = 32000 // Once per CREATE2 operation
+ SelfdestructRefundGas uint64 = 24000 // Refunded following a selfdestruct operation.
+ MemoryGas uint64 = 3 // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL.
+ TxDataNonZeroGas uint64 = 68 // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions.
+
+ // These have been changed during the course of the chain
+ CallGasFrontier uint64 = 40 // Once per CALL operation & message call transaction.
+ CallGasEIP150 uint64 = 700 // Static portion of gas for CALL-derivates after EIP 150 (Tangerine)
+ BalanceGasFrontier uint64 = 20 // The cost of a BALANCE operation
+ BalanceGasEIP150 uint64 = 400 // The cost of a BALANCE operation after Tangerine
+ ExtcodeSizeGasFrontier uint64 = 20 // Cost of EXTCODESIZE before EIP 150 (Tangerine)
+ ExtcodeSizeGasEIP150 uint64 = 700 // Cost of EXTCODESIZE after EIP 150 (Tangerine)
+ SloadGasFrontier uint64 = 50
+ SloadGasEIP150 uint64 = 200
+ ExtcodeHashGas uint64 = 400 // Cost of EXTCODEHASH (introduced in Constantinople)
+ SelfdestructGasEIP150 uint64 = 5000 // Cost of SELFDESTRUCT post EIP 150 (Tangerine)
+
+ // 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)
+ ExtcodeCopyBaseFrontier uint64 = 20
+ ExtcodeCopyBaseEIP150 uint64 = 700
+
+ // CreateBySelfdestructGas is used when the refunded account is one that does
+ // not exist. This logic is similar to call.
+ // Introduced in Tangerine Whistle (Eip 150)
+ CreateBySelfdestructGas uint64 = 25000
MaxCodeSize = 24576 // Maximum bytecode to permit for a contract