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. # The gas cost specification for storage instructions.
StorageCostSpec = object StorageCostSpec = object
netCost : bool # Is this net gas cost metering schedule? netCost : bool # Is this net gas cost metering schedule?
warmAccess: int16 # Storage warm access cost, YP: G_{warmaccess} warmAccess: uint16 # Storage warm access cost, YP: G_{warmaccess}
sset : int16 # Storage addition cost, YP: G_{sset} sset : uint16 # Storage addition cost, YP: G_{sset}
reset : int16 # Storage modification cost, YP: G_{sreset} reset : uint16 # Storage modification cost, YP: G_{sreset}
clear : int16 # Storage deletion refund, YP: R_{sclear} clear : uint16 # Storage deletion refund, YP: R_{sclear}
StorageStoreCost* = object StorageStoreCost* = object
gasCost* : int16 gasCost* : uint16
gasRefund*: int16 gasRefund*: uint16
reduceRefund*: uint16
SstoreCosts* = array[evmc_storage_status, StorageStoreCost] 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_ADDED] = StorageStoreCost(gasCost: c.sset , gasRefund: 0)
e[EVMC_STORAGE_DELETED] = StorageStoreCost(gasCost: c.reset , gasRefund: c.clear) e[EVMC_STORAGE_DELETED] = StorageStoreCost(gasCost: c.reset , gasRefund: c.clear)
e[EVMC_STORAGE_MODIFIED] = StorageStoreCost(gasCost: c.reset , gasRefund: 0) 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_MODIFIED_DELETED] = StorageStoreCost(gasCost: c.warmAccess, gasRefund: c.clear)
e[EVMC_STORAGE_DELETED_RESTORED] = StorageStoreCost(gasCost: c.warmAccess, 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, 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, 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.} = proc storageStoreCost(): array[EVMFork, SstoreCosts] {.compileTime.} =
const tbl = storageCostSpec() const tbl = storageCostSpec()

View File

@ -95,7 +95,11 @@ type
GckSstore GckSstore
# gasRefund of sstore can be a negative number # 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] CallGasResult = tuple[gasCost, childGasLimit: GasInt]
GasCost = object GasCost = object
@ -301,7 +305,7 @@ template gasCosts(fork: EVMFork, prefix, ResultGasCostsName: untyped) =
if not params.originalValue.isZero: if not params.originalValue.isZero:
if params.currentValue.isZero: # recreate slot (2.2.1.1) 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) if value.isZero: # delete slot (2.2.1.2)
res.gasRefund += ClearRefund 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) = func returnGas*(gasMeter: var GasMeter; amount: GasInt) =
gasMeter.gasRemaining += amount gasMeter.gasRemaining += amount
# some gasRefunded operations still relying
# on negative number
func refundGas*(gasMeter: var GasMeter; amount: GasInt) = func refundGas*(gasMeter: var GasMeter; amount: GasInt) =
gasMeter.gasRefunded += amount gasMeter.gasRefunded += amount
func reduceRefund*(gasMeter: var GasMeter; amount: GasInt) =
gasMeter.gasRefunded -= amount

View File

@ -47,11 +47,10 @@ when evmc_enabled:
let let
status = c.host.setStorage(c.msg.contractAddress, slot, newValue) status = c.host.setStorage(c.msg.contractAddress, slot, newValue)
res = ForkToSstoreCost[c.fork][status] res = ForkToSstoreCost[c.fork][status]
gasCost = res.gasCost + coldAccess gasCost = res.gasCost.GasInt + coldAccess
if res.gasRefund != 0:
c.gasMeter.refundGas(res.gasRefund)
c.gasMeter.refundGas(res.gasRefund.GasInt)
c.gasMeter.reduceRefund(res.reduceRefund.GasInt)
c.opcodeGastCost(Sstore, gasCost, "SSTORE") c.opcodeGastCost(Sstore, gasCost, "SSTORE")
else: else:
@ -60,12 +59,12 @@ else:
currentValue = c.getStorage(slot) currentValue = c.getStorage(slot)
gasParam = GasParamsSs( gasParam = GasParamsSs(
currentValue: currentValue) currentValue: currentValue)
res = c.gasCosts[Sstore].ss_handler(newValue, gasParam) res = c.gasCosts[Sstore].ss_handler(newValue, gasParam)
? c.opcodeGastCost(Sstore, res.gasCost, "SSTORE") ? 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: c.vmState.mutateStateDB:
db.setStorage(c.msg.contractAddress, slot, newValue) db.setStorage(c.msg.contractAddress, slot, newValue)
@ -85,8 +84,8 @@ else:
? c.opcodeGastCost(Sstore, res.gasCost + coldAccess, "SSTORE") ? 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: c.vmState.mutateStateDB:
db.setStorage(c.msg.contractAddress, slot, newValue) db.setStorage(c.msg.contractAddress, slot, newValue)