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:
andri lim 2024-07-06 08:39:38 +07:00 committed by GitHub
parent 4eaae5cbfa
commit e8683692fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 28 additions and 23 deletions

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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)