EVM gasSstore refund reduction using positive integer (#2460)
This is the hopefully the last part of preparations before converting GasInt to uint64
This commit is contained in:
parent
4eaae5cbfa
commit
e8683692fd
|
@ -18,14 +18,15 @@ type
|
|||
# The gas cost specification for storage instructions.
|
||||
StorageCostSpec = object
|
||||
netCost : bool # Is this net gas cost metering schedule?
|
||||
warmAccess: int16 # Storage warm access cost, YP: G_{warmaccess}
|
||||
sset : int16 # Storage addition cost, YP: G_{sset}
|
||||
reset : int16 # Storage modification cost, YP: G_{sreset}
|
||||
clear : int16 # Storage deletion refund, YP: R_{sclear}
|
||||
warmAccess: uint16 # Storage warm access cost, YP: G_{warmaccess}
|
||||
sset : uint16 # Storage addition cost, YP: G_{sset}
|
||||
reset : uint16 # Storage modification cost, YP: G_{sreset}
|
||||
clear : uint16 # Storage deletion refund, YP: R_{sclear}
|
||||
|
||||
StorageStoreCost* = object
|
||||
gasCost* : int16
|
||||
gasRefund*: int16
|
||||
gasCost* : uint16
|
||||
gasRefund*: uint16
|
||||
reduceRefund*: uint16
|
||||
|
||||
SstoreCosts* = array[evmc_storage_status, StorageStoreCost]
|
||||
|
||||
|
@ -79,14 +80,14 @@ proc netSStoreCost(e: var SstoreCosts,
|
|||
e[EVMC_STORAGE_ADDED] = StorageStoreCost(gasCost: c.sset , gasRefund: 0)
|
||||
e[EVMC_STORAGE_DELETED] = StorageStoreCost(gasCost: c.reset , gasRefund: c.clear)
|
||||
e[EVMC_STORAGE_MODIFIED] = StorageStoreCost(gasCost: c.reset , gasRefund: 0)
|
||||
e[EVMC_STORAGE_DELETED_ADDED] = StorageStoreCost(gasCost: c.warmAccess, gasRefund: -c.clear)
|
||||
e[EVMC_STORAGE_DELETED_ADDED] = StorageStoreCost(gasCost: c.warmAccess, reduceRefund: c.clear)
|
||||
e[EVMC_STORAGE_MODIFIED_DELETED] = StorageStoreCost(gasCost: c.warmAccess, gasRefund: c.clear)
|
||||
e[EVMC_STORAGE_DELETED_RESTORED] = StorageStoreCost(gasCost: c.warmAccess,
|
||||
gasRefund: c.reset - c.warmAccess - c.clear)
|
||||
gasRefund: c.reset, reduceRefund: c.warmAccess + c.clear)
|
||||
e[EVMC_STORAGE_ADDED_DELETED] = StorageStoreCost(gasCost: c.warmAccess,
|
||||
gasRefund: c.sset - c.warmAccess)
|
||||
gasRefund: c.sset, reduceRefund: c.warmAccess)
|
||||
e[EVMC_STORAGE_MODIFIED_RESTORED] = StorageStoreCost(gasCost: c.warmAccess,
|
||||
gasRefund: c.reset - c.warmAccess)
|
||||
gasRefund: c.reset, reduceRefund: c.warmAccess)
|
||||
|
||||
proc storageStoreCost(): array[EVMFork, SstoreCosts] {.compileTime.} =
|
||||
const tbl = storageCostSpec()
|
||||
|
|
|
@ -95,7 +95,11 @@ type
|
|||
GckSstore
|
||||
|
||||
# gasRefund of sstore can be a negative number
|
||||
SStoreGasResult = tuple[gasCost: GasInt, gasRefund: int64]
|
||||
SStoreGasResult* = object
|
||||
gasCost*: GasInt
|
||||
gasRefund*: GasInt
|
||||
reduceRefund*: GasInt
|
||||
|
||||
CallGasResult = tuple[gasCost, childGasLimit: GasInt]
|
||||
|
||||
GasCost = object
|
||||
|
@ -301,7 +305,7 @@ template gasCosts(fork: EVMFork, prefix, ResultGasCostsName: untyped) =
|
|||
|
||||
if not params.originalValue.isZero:
|
||||
if params.currentValue.isZero: # recreate slot (2.2.1.1)
|
||||
res.gasRefund -= ClearRefund
|
||||
res.reduceRefund = ClearRefund
|
||||
if value.isZero: # delete slot (2.2.1.2)
|
||||
res.gasRefund += ClearRefund
|
||||
|
||||
|
|
|
@ -28,7 +28,8 @@ func consumeGas*(gasMeter: var GasMeter; amount: GasInt; reason: string): EvmRes
|
|||
func returnGas*(gasMeter: var GasMeter; amount: GasInt) =
|
||||
gasMeter.gasRemaining += amount
|
||||
|
||||
# some gasRefunded operations still relying
|
||||
# on negative number
|
||||
func refundGas*(gasMeter: var GasMeter; amount: GasInt) =
|
||||
gasMeter.gasRefunded += amount
|
||||
|
||||
func reduceRefund*(gasMeter: var GasMeter; amount: GasInt) =
|
||||
gasMeter.gasRefunded -= amount
|
||||
|
|
|
@ -47,11 +47,10 @@ when evmc_enabled:
|
|||
let
|
||||
status = c.host.setStorage(c.msg.contractAddress, slot, newValue)
|
||||
res = ForkToSstoreCost[c.fork][status]
|
||||
gasCost = res.gasCost + coldAccess
|
||||
|
||||
if res.gasRefund != 0:
|
||||
c.gasMeter.refundGas(res.gasRefund)
|
||||
gasCost = res.gasCost.GasInt + coldAccess
|
||||
|
||||
c.gasMeter.refundGas(res.gasRefund.GasInt)
|
||||
c.gasMeter.reduceRefund(res.reduceRefund.GasInt)
|
||||
c.opcodeGastCost(Sstore, gasCost, "SSTORE")
|
||||
|
||||
else:
|
||||
|
@ -60,12 +59,12 @@ else:
|
|||
currentValue = c.getStorage(slot)
|
||||
gasParam = GasParamsSs(
|
||||
currentValue: currentValue)
|
||||
|
||||
res = c.gasCosts[Sstore].ss_handler(newValue, gasParam)
|
||||
|
||||
? c.opcodeGastCost(Sstore, res.gasCost, "SSTORE")
|
||||
if res.gasRefund > 0:
|
||||
c.gasMeter.refundGas(res.gasRefund)
|
||||
|
||||
c.gasMeter.refundGas(res.gasRefund)
|
||||
c.gasMeter.reduceRefund(res.reduceRefund)
|
||||
|
||||
c.vmState.mutateStateDB:
|
||||
db.setStorage(c.msg.contractAddress, slot, newValue)
|
||||
|
@ -85,8 +84,8 @@ else:
|
|||
|
||||
? c.opcodeGastCost(Sstore, res.gasCost + coldAccess, "SSTORE")
|
||||
|
||||
if res.gasRefund != 0:
|
||||
c.gasMeter.refundGas(res.gasRefund)
|
||||
c.gasMeter.refundGas(res.gasRefund)
|
||||
c.gasMeter.reduceRefund(res.reduceRefund)
|
||||
|
||||
c.vmState.mutateStateDB:
|
||||
db.setStorage(c.msg.contractAddress, slot, newValue)
|
||||
|
|
Loading…
Reference in New Issue