implement EIP-2200 stub

This commit is contained in:
andri lim 2019-11-12 19:49:46 +07:00 committed by zah
parent b5e8a8d61b
commit c0c62b94b8
3 changed files with 43 additions and 12 deletions

View File

@ -208,6 +208,7 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
func `prefix gasSstore`(value: Uint256, gasParams: Gasparams): GasResult {.nimcall.} =
## Value is word to save
when fork < FkIstanbul:
# workaround for static evaluation not working for if expression
const
gSet = FeeSchedule[GasSset]
@ -222,6 +223,30 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
# Refund
if value.isZero and not gasParams.s_isStorageEmpty:
result.gasRefund = static(FeeSchedule[RefundSclear])
else:
# 0. If *gasleft* is less than or equal to 2300, fail the current call.
# 1. If current value equals new value (this is a no-op), SSTORE_NOOP_GAS gas is deducted.
# 2. If current value does not equal new value:
# 2.1. If original value equals current value (this storage slot has not been changed by the current execution context):
# 2.1.1. If original value is 0, SSTORE_INIT_GAS gas is deducted.
# 2.1.2. Otherwise, SSTORE_CLEAN_GAS gas is deducted. If new value is 0, add SSTORE_CLEAR_REFUND to refund counter.
# 2.2. If original value does not equal current value (this storage slot is dirty), SSTORE_DIRTY_GAS gas is deducted. Apply both of the following clauses:
# 2.2.1. If original value is not 0:
# 2.2.1.1. If current value is 0 (also means that new value is not 0), subtract SSTORE_CLEAR_REFUND gas from refund counter. We can prove that refund counter will never go below 0.
# 2.2.1.2. If new value is 0 (also means that current value is not 0), add SSTORE_CLEAR_REFUND gas to refund counter.
# 2.2.2. If original value equals new value (this storage slot is reset):
# 2.2.2.1. If original value is 0, add SSTORE_INIT_REFUND to refund counter.
# 2.2.2.2. Otherwise, add SSTORE_CLEAN_REFUND gas to refund counter.
const
NoopGasEIP2200 = FeeSchedule[GasSload] # if the value doesn't change.
DirtyGasEIP2200 = FeeSchedule[GasSload] # if a dirty value is changed.
InitGasEIP2200 = FeeSchedule[GasSset] # from clean zero to non-zero
InitRefundEIP2200 = FeeSchedule[GasSset] - FeeSchedule[GasSload] # resetting to the original zero value
CleanGasEIP2200 = FeeSchedule[GasSreset]# from clean non-zero to something else
CleanRefundEIP2200 = FeeSchedule[GasSreset] - FeeSchedule[GasSload] # resetting to the original non-zero value
ClearRefundEIP2200 = FeeSchedule[RefundSclear]# clearing an originally existing storage slot
# Gas sentry honoured, do the actual gas calculation based on the stored value
func `prefix gasLog0`(currentMemSize, memOffset, memLength: GasNatural): GasInt {.nimcall.} =
result = `prefix gasMemoryExpansion`(currentMemSize, memOffset, memLength)
@ -611,6 +636,7 @@ func istanbulGasFees(previous_fees: GasFeeSchedule): GasFeeSchedule =
result[GasExtCodeHash] = 700
result[GasBalance] = 700
result[GasTXDataNonZero]= 16
const
HomesteadGasFees = BaseGasFees.homesteadGasFees
TangerineGasFees = HomesteadGasFees.tangerineGasFees

View File

@ -930,3 +930,7 @@ op extCodeHash, inline = true:
push: 0
else:
push: computation.vmState.readOnlyStateDB.getCodeHash(address)
op sstoreEIP2200, inline = false, slot, value:
checkInStaticContext(computation)
# TODO: stub

View File

@ -219,6 +219,7 @@ proc genIstanbulJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compile
result = ops
result[ChainId] = newIdentNode "chainId"
result[SelfBalance] = newIdentNode "selfBalance"
result[SStore] = newIdentNode "sstoreEIP2200"
let IstanbulOpDispatch {.compileTime.}: array[Op, NimNode] = genIstanbulJumpTable(ConstantinopleOpDispatch)