mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-25 18:35:32 +00:00
EVM: Use the EVMC calls for EIP-2929 access-list and refactor in EVM
Signed-off-by: Jamie Lokier <jamie@shareable.org>
This commit is contained in:
parent
74f53c7761
commit
a7b40b0762
@ -23,15 +23,47 @@ logScope:
|
|||||||
# ##################################
|
# ##################################
|
||||||
# Syntactic sugar
|
# Syntactic sugar
|
||||||
|
|
||||||
proc gasEip2929AccountCheck(c: Computation, address: EthAddress, prevCost = 0.GasInt) =
|
template accessGas(c: Computation, address: EthAddress): GasInt =
|
||||||
c.vmState.mutateStateDB:
|
c.accessGas(ColdAccountAccessCost, WarmStorageReadCost, address)
|
||||||
let gasCost = if not db.inAccessList(address):
|
|
||||||
db.accessList(address)
|
|
||||||
ColdAccountAccessCost
|
|
||||||
else:
|
|
||||||
WarmStorageReadCost
|
|
||||||
|
|
||||||
c.gasMeter.consumeGas(gasCost - prevCost, reason = "gasEIP2929AccountCheck")
|
template accessGas(c: Computation, coldAccessGas, warmAccessGas: GasInt): GasInt =
|
||||||
|
# Simulate making the `address` argument default `= c.msg.contractAddress`.
|
||||||
|
# Works around Nim 1.2.10 compiler's "internal error: environment misses: c".
|
||||||
|
c.accessGas(coldAccessGas, warmAccessGas, c.msg.contractAddress)
|
||||||
|
|
||||||
|
template accessGas(c: Computation, coldAccessGas, warmAccessGas: GasInt,
|
||||||
|
address: EthAddress): GasInt =
|
||||||
|
c.accessGas(address, coldAccessGas, warmAccessGas)
|
||||||
|
|
||||||
|
proc accessGas(c: Computation, address = c.msg.contractAddress,
|
||||||
|
coldAccessGas, warmAccessGas: GasInt): GasInt {.inline.} =
|
||||||
|
when evmc_enabled:
|
||||||
|
if c.host.accessAccount(address) == EVMC_ACCESS_COLD:
|
||||||
|
coldAccessGas
|
||||||
|
else:
|
||||||
|
warmAccessGas
|
||||||
|
else:
|
||||||
|
c.vmState.mutateStateDB:
|
||||||
|
if not db.inAccessList(address):
|
||||||
|
db.accessList(address)
|
||||||
|
return coldAccessGas
|
||||||
|
else:
|
||||||
|
return warmAccessGas
|
||||||
|
|
||||||
|
proc accessGas(c: Computation, coldAccessGas, warmAccessGas: GasInt,
|
||||||
|
slot: Uint256): GasInt {.inline.} =
|
||||||
|
when evmc_enabled:
|
||||||
|
if c.host.accessStorage(c.msg.contractAddress, slot) == EVMC_ACCESS_COLD:
|
||||||
|
coldAccessGas
|
||||||
|
else:
|
||||||
|
warmAccessGas
|
||||||
|
else:
|
||||||
|
c.vmState.mutateStateDB:
|
||||||
|
if not db.inAccessList(c.msg.contractAddress, slot):
|
||||||
|
db.accessList(c.msg.contractAddress, slot)
|
||||||
|
return coldAccessGas
|
||||||
|
else:
|
||||||
|
return warmAccessGas
|
||||||
|
|
||||||
template push(x: typed) {.dirty.} =
|
template push(x: typed) {.dirty.} =
|
||||||
## Push an expression on the computation stack
|
## Push an expression on the computation stack
|
||||||
@ -782,11 +814,11 @@ template genCall(callName: untyped, opCode: Op): untyped =
|
|||||||
# because it will affect `c.gasMeter.gasRemaining`
|
# because it will affect `c.gasMeter.gasRemaining`
|
||||||
# and further `childGasLimit`
|
# and further `childGasLimit`
|
||||||
if c.fork >= FkBerlin:
|
if c.fork >= FkBerlin:
|
||||||
c.vmState.mutateStateDB:
|
# The WarmStorageReadCostEIP2929 (100) is already deducted in the form of a constant `gasCall`
|
||||||
if not db.inAccessList(destination):
|
let gasCost = c.accessGas(ColdAccountAccessCost - WarmStorageReadCost, 0,
|
||||||
db.accessList(destination)
|
destination)
|
||||||
# The WarmStorageReadCostEIP2929 (100) is already deducted in the form of a constant `gasCall`
|
if gasCost != 0:
|
||||||
c.gasMeter.consumeGas(ColdAccountAccessCost - WarmStorageReadCost, reason = "EIP2929 gasCall")
|
c.gasMeter.consumeGas(gasCost, reason = "EIP2929 gasCall")
|
||||||
|
|
||||||
let contractAddress = when opCode in {Call, StaticCall}: destination else: c.msg.contractAddress
|
let contractAddress = when opCode in {Call, StaticCall}: destination else: c.msg.contractAddress
|
||||||
var (gasCost, childGasLimit) = c.gasCosts[opCode].c_handler(
|
var (gasCost, childGasLimit) = c.gasCosts[opCode].c_handler(
|
||||||
@ -986,19 +1018,21 @@ op extCodeHash, inline = true:
|
|||||||
op balanceEIP2929, inline = true:
|
op balanceEIP2929, inline = true:
|
||||||
## 0x31, Get balance of the given account.
|
## 0x31, Get balance of the given account.
|
||||||
let address = c.stack.popAddress()
|
let address = c.stack.popAddress()
|
||||||
|
c.gasMeter.consumeGas(c.accessGas(address) - gasFees[c.fork][GasBalance],
|
||||||
c.gasEip2929AccountCheck(address, gasFees[c.fork][GasBalance])
|
reason = "balanceEIP2929")
|
||||||
push: c.getBalance(address)
|
push: c.getBalance(address)
|
||||||
|
|
||||||
op extCodeHashEIP2929, inline = true:
|
op extCodeHashEIP2929, inline = true:
|
||||||
let address = c.stack.popAddress()
|
let address = c.stack.popAddress()
|
||||||
c.gasEip2929AccountCheck(address, gasFees[c.fork][GasExtCodeHash])
|
c.gasMeter.consumeGas(c.accessGas(address) - gasFees[c.fork][GasExtCodeHash],
|
||||||
|
reason = "extCodeHashEIP2929")
|
||||||
push: c.getCodeHash(address)
|
push: c.getCodeHash(address)
|
||||||
|
|
||||||
op extCodeSizeEIP2929, inline = true:
|
op extCodeSizeEIP2929, inline = true:
|
||||||
## 0x3b, Get size of an account's code
|
## 0x3b, Get size of an account's code
|
||||||
let address = c.stack.popAddress()
|
let address = c.stack.popAddress()
|
||||||
c.gasEip2929AccountCheck(address, gasFees[c.fork][GasExtCode])
|
c.gasMeter.consumeGas(c.accessGas(address) - gasFees[c.fork][GasExtCode],
|
||||||
|
reason = "extCodeSizeEIP2929")
|
||||||
push: c.getCodeSize(address)
|
push: c.getCodeSize(address)
|
||||||
|
|
||||||
op extCodeCopyEIP2929, inline = true:
|
op extCodeCopyEIP2929, inline = true:
|
||||||
@ -1011,7 +1045,8 @@ op extCodeCopyEIP2929, inline = true:
|
|||||||
c.gasCosts[ExtCodeCopy].m_handler(c.memory.len, memPos, len),
|
c.gasCosts[ExtCodeCopy].m_handler(c.memory.len, memPos, len),
|
||||||
reason="ExtCodeCopy fee")
|
reason="ExtCodeCopy fee")
|
||||||
|
|
||||||
c.gasEip2929AccountCheck(address, gasFees[c.fork][GasExtCode])
|
c.gasMeter.consumeGas(c.accessGas(address) - gasFees[c.fork][GasExtCode],
|
||||||
|
reason = "extCodeCopyEIP2929")
|
||||||
|
|
||||||
let codeBytes = c.getCode(address)
|
let codeBytes = c.getCode(address)
|
||||||
c.memory.writePaddedResult(codeBytes, memPos, codePos, len)
|
c.memory.writePaddedResult(codeBytes, memPos, codePos, len)
|
||||||
@ -1029,25 +1064,15 @@ op selfDestructEIP2929, inline = false:
|
|||||||
)
|
)
|
||||||
|
|
||||||
var gasCost = c.gasCosts[SelfDestruct].c_handler(0.u256, gasParams).gasCost
|
var gasCost = c.gasCosts[SelfDestruct].c_handler(0.u256, gasParams).gasCost
|
||||||
|
gasCost += c.accessGas(ColdAccountAccessCost, 0, beneficiary)
|
||||||
c.vmState.mutateStateDB:
|
|
||||||
if not db.inAccessList(beneficiary):
|
|
||||||
db.accessList(beneficiary)
|
|
||||||
gasCost = gasCost + ColdAccountAccessCost
|
|
||||||
|
|
||||||
c.gasMeter.consumeGas(gasCost, reason = "SELFDESTRUCT EIP161")
|
c.gasMeter.consumeGas(gasCost, reason = "SELFDESTRUCT EIP161")
|
||||||
c.selfDestruct(beneficiary)
|
c.selfDestruct(beneficiary)
|
||||||
|
|
||||||
op sloadEIP2929, inline = true, slot:
|
op sloadEIP2929, inline = true, slot:
|
||||||
## 0x54, Load word from storage.
|
## 0x54, Load word from storage.
|
||||||
c.vmState.mutateStateDB:
|
let gasCost = c.accessGas(ColdSloadCost, WarmStorageReadCost, slot)
|
||||||
let gasCost = if not db.inAccessList(c.msg.contractAddress, slot):
|
c.gasMeter.consumeGas(gasCost, reason = "sloadEIP2929")
|
||||||
db.accessList(c.msg.contractAddress, slot)
|
|
||||||
ColdSloadCost
|
|
||||||
else:
|
|
||||||
WarmStorageReadCost
|
|
||||||
c.gasMeter.consumeGas(gasCost, reason = "sloadEIP2929")
|
|
||||||
|
|
||||||
push: c.getStorage(slot)
|
push: c.getStorage(slot)
|
||||||
|
|
||||||
op sstoreEIP2929, inline = false, slot, newValue:
|
op sstoreEIP2929, inline = false, slot, newValue:
|
||||||
@ -1057,10 +1082,9 @@ op sstoreEIP2929, inline = false, slot, newValue:
|
|||||||
if c.gasMeter.gasRemaining <= SentryGasEIP2200:
|
if c.gasMeter.gasRemaining <= SentryGasEIP2200:
|
||||||
raise newException(OutOfGas, "Gas not enough to perform EIP2200 SSTORE")
|
raise newException(OutOfGas, "Gas not enough to perform EIP2200 SSTORE")
|
||||||
|
|
||||||
c.vmState.mutateStateDB:
|
let gasCost = c.accessGas(ColdSloadCost, 0, slot)
|
||||||
if not db.inAccessList(c.msg.contractAddress, slot):
|
if gasCost != 0:
|
||||||
db.accessList(c.msg.contractAddress, slot)
|
c.gasMeter.consumeGas(gasCost, reason = "sstoreEIP2929")
|
||||||
c.gasMeter.consumeGas(ColdSloadCost, reason = "sstoreEIP2929")
|
|
||||||
|
|
||||||
when evmc_enabled:
|
when evmc_enabled:
|
||||||
sstoreEvmc(c, slot, newValue)
|
sstoreEvmc(c, slot, newValue)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user