fixes evmc 'gasRefund'
This commit is contained in:
parent
c459879647
commit
37c282f1b9
|
@ -46,44 +46,39 @@ proc hostSetStorageImpl(ctx: Computation, address: var evmc_address,
|
|||
|
||||
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
|
||||
gasRefund = 0.GasInt
|
||||
status = EVMC_STORAGE_MODIFIED
|
||||
gasRefund = 0.GasInt
|
||||
origValue = 0.u256
|
||||
|
||||
if origValue == currValue or ctx.fork < FkIstanbul:
|
||||
if currValue == 0:
|
||||
status = EVMC_STORAGE_ADDED
|
||||
elif newValue == 0:
|
||||
status = EVMC_STORAGE_DELETED
|
||||
gasRefund += ClearRefundEIP2200
|
||||
else:
|
||||
status = EVMC_STORAGE_MODIFIED_AGAIN
|
||||
if origValue != 0:
|
||||
block:
|
||||
if newValue == currValue:
|
||||
status = EVMC_STORAGE_UNCHANGED
|
||||
break
|
||||
|
||||
origValue = statedb.getCommittedStorage(storageAddr, slot)
|
||||
|
||||
if origValue == currValue or ctx.fork < FkIstanbul:
|
||||
if currValue == 0:
|
||||
gasRefund -= ClearRefundEIP2200 # Can go negative
|
||||
if newValue == 0:
|
||||
gasRefund += ClearRefundEIP2200
|
||||
if origValue == newValue:
|
||||
if origValue == 0:
|
||||
gasRefund += InitRefundEIP2200
|
||||
else:
|
||||
gasRefund += CleanRefundEIP2200
|
||||
status = EVMC_STORAGE_ADDED
|
||||
elif newValue == 0:
|
||||
status = EVMC_STORAGE_DELETED
|
||||
else:
|
||||
status = EVMC_STORAGE_MODIFIED_AGAIN
|
||||
|
||||
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.vmState.mutateStateDB:
|
||||
db.setStorage(storageAddr, slot, newValue)
|
||||
|
||||
result = status
|
||||
|
||||
proc hostGetBalanceImpl(ctx: Computation, address: var evmc_address): evmc_uint256be {.cdecl.} =
|
||||
|
|
|
@ -71,8 +71,8 @@ type
|
|||
s_status*: evmc_storage_status
|
||||
else:
|
||||
s_isStorageEmpty*: bool
|
||||
s_currentValue*: Uint256
|
||||
s_originalValue*: Uint256
|
||||
s_currentValue*: Uint256
|
||||
s_originalValue*: Uint256
|
||||
of Call, CallCode, DelegateCall, StaticCall:
|
||||
c_isNewAccount*: bool
|
||||
c_gasBalance*: GasInt
|
||||
|
@ -222,13 +222,31 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
|
|||
sstoreLoad = FeeSchedule[GasSload]
|
||||
sstoreSet = FeeSchedule[GasSset]
|
||||
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
|
||||
of EVMC_STORAGE_ADDED: result.gasCost = sstoreSet
|
||||
of EVMC_STORAGE_MODIFIED, EVMC_STORAGE_DELETED: result.gasCost = sstoreReset
|
||||
of EVMC_STORAGE_UNCHANGED, EVMC_STORAGE_MODIFIED_AGAIN:
|
||||
result.gasCost = if fork >= FkIstanbul: sstoreLoad else: sstoreReset
|
||||
of EVMC_STORAGE_MODIFIED: result.gasCost = sstoreReset
|
||||
of EVMC_STORAGE_DELETED:
|
||||
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:
|
||||
when fork < FkIstanbul:
|
||||
# workaround for static evaluation not working for if expression
|
||||
|
|
Loading…
Reference in New Issue