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.
|
# 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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue