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
|
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.} =
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue