fixes evmc 'gasRefund'

This commit is contained in:
andri lim 2020-01-18 07:32:39 +07:00 committed by zah
parent c459879647
commit 37c282f1b9
2 changed files with 49 additions and 36 deletions

View File

@ -46,44 +46,39 @@ proc hostSetStorageImpl(ctx: Computation, address: var evmc_address,
assert storageAddr == ctx.msg.contractAddress assert storageAddr == ctx.msg.contractAddress
if newValue == currValue:
return EVMC_STORAGE_UNCHANGED
let
origValue = statedb.getCommittedStorage(storageAddr, slot)
InitRefundEIP2200 = gasFees[ctx.fork][GasSset] - gasFees[ctx.fork][GasSload]
CleanRefundEIP2200 = gasFees[ctx.fork][GasSreset] - gasFees[ctx.fork][GasSload]
ClearRefundEIP2200 = gasFees[ctx.fork][RefundsClear]
var var
gasRefund = 0.GasInt
status = EVMC_STORAGE_MODIFIED status = EVMC_STORAGE_MODIFIED
gasRefund = 0.GasInt
origValue = 0.u256
if origValue == currValue or ctx.fork < FkIstanbul: block:
if currValue == 0: if newValue == currValue:
status = EVMC_STORAGE_ADDED status = EVMC_STORAGE_UNCHANGED
elif newValue == 0: break
status = EVMC_STORAGE_DELETED
gasRefund += ClearRefundEIP2200 origValue = statedb.getCommittedStorage(storageAddr, slot)
else:
status = EVMC_STORAGE_MODIFIED_AGAIN if origValue == currValue or ctx.fork < FkIstanbul:
if origValue != 0:
if currValue == 0: if currValue == 0:
gasRefund -= ClearRefundEIP2200 # Can go negative status = EVMC_STORAGE_ADDED
if newValue == 0: elif newValue == 0:
gasRefund += ClearRefundEIP2200 status = EVMC_STORAGE_DELETED
if origValue == newValue: else:
if origValue == 0: status = EVMC_STORAGE_MODIFIED_AGAIN
gasRefund += InitRefundEIP2200
else:
gasRefund += CleanRefundEIP2200
if gasRefund > 0: ctx.vmState.mutateStateDB:
db.setStorage(storageAddr, slot, newValue)
let gasParam = GasParams(kind: Op.Sstore,
s_status: status,
s_currentValue: currValue,
s_originalValue: origValue
)
gasRefund = ctx.gasCosts[Sstore].c_handler(newValue, gasParam)[1]
if gasRefund != 0:
ctx.gasMeter.refundGas(gasRefund) ctx.gasMeter.refundGas(gasRefund)
ctx.vmState.mutateStateDB:
db.setStorage(storageAddr, slot, newValue)
result = status result = status
proc hostGetBalanceImpl(ctx: Computation, address: var evmc_address): evmc_uint256be {.cdecl.} = proc hostGetBalanceImpl(ctx: Computation, address: var evmc_address): evmc_uint256be {.cdecl.} =

View File

@ -71,8 +71,8 @@ type
s_status*: evmc_storage_status s_status*: evmc_storage_status
else: else:
s_isStorageEmpty*: bool s_isStorageEmpty*: bool
s_currentValue*: Uint256 s_currentValue*: Uint256
s_originalValue*: Uint256 s_originalValue*: Uint256
of Call, CallCode, DelegateCall, StaticCall: of Call, CallCode, DelegateCall, StaticCall:
c_isNewAccount*: bool c_isNewAccount*: bool
c_gasBalance*: GasInt c_gasBalance*: GasInt
@ -222,13 +222,31 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
sstoreLoad = FeeSchedule[GasSload] sstoreLoad = FeeSchedule[GasSload]
sstoreSet = FeeSchedule[GasSset] sstoreSet = FeeSchedule[GasSset]
sstoreReset= FeeSchedule[GasSreset] sstoreReset= FeeSchedule[GasSreset]
sstoreDirty= when fork >= FkIstanbul: sstoreLoad else: sstoreReset
InitRefundEIP2200 = FeeSchedule[GasSset] - FeeSchedule[GasSload]
CleanRefundEIP2200 = FeeSchedule[GasSreset] - FeeSchedule[GasSload]
ClearRefundEIP2200 = FeeSchedule[RefundsClear]
case gasParams.s_status case gasParams.s_status
of EVMC_STORAGE_ADDED: result.gasCost = sstoreSet of EVMC_STORAGE_ADDED: result.gasCost = sstoreSet
of EVMC_STORAGE_MODIFIED, EVMC_STORAGE_DELETED: result.gasCost = sstoreReset of EVMC_STORAGE_MODIFIED: result.gasCost = sstoreReset
of EVMC_STORAGE_UNCHANGED, EVMC_STORAGE_MODIFIED_AGAIN: of EVMC_STORAGE_DELETED:
result.gasCost = if fork >= FkIstanbul: sstoreLoad else: sstoreReset result.gasCost = sstoreReset
result.gasRefund += ClearRefundEIP2200
of EVMC_STORAGE_UNCHANGED: result.gasCost = sstoreDirty
of EVMC_STORAGE_MODIFIED_AGAIN:
result.gasCost = sstoreDirty
if not gasParams.s_originalValue.isZero:
if gasParams.s_currentValue.isZero:
result.gasRefund -= ClearRefundEIP2200
if value.isZero:
result.gasRefund += ClearRefundEIP2200
if gasParams.s_originalValue == value:
if gasParams.s_originalValue.isZero:
result.gasRefund += InitRefundEIP2200
else:
result.gasRefund += CleanRefundEIP2200
else: else:
when fork < FkIstanbul: when fork < FkIstanbul:
# workaround for static evaluation not working for if expression # workaround for static evaluation not working for if expression