mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-12 05:14:14 +00:00
re-integrated/added EIP2929 handlers
This commit is contained in:
parent
716bd64419
commit
7436e516fd
@ -66,6 +66,7 @@ else:
|
|||||||
msg*: Message
|
msg*: Message
|
||||||
code*: CodeStream
|
code*: CodeStream
|
||||||
returnData*: seq[byte]
|
returnData*: seq[byte]
|
||||||
|
fork*: Fork
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Kludge END
|
# Kludge END
|
||||||
|
@ -19,6 +19,7 @@ const
|
|||||||
import
|
import
|
||||||
../../../errors,
|
../../../errors,
|
||||||
./oph_defs,
|
./oph_defs,
|
||||||
|
./oph_helpers,
|
||||||
sequtils,
|
sequtils,
|
||||||
strformat,
|
strformat,
|
||||||
stint
|
stint
|
||||||
@ -35,13 +36,20 @@ when not breakCircularDependency:
|
|||||||
../../v2memory,
|
../../v2memory,
|
||||||
../../v2state,
|
../../v2state,
|
||||||
../gas_meter,
|
../gas_meter,
|
||||||
|
../v2gas_costs,
|
||||||
../utils/v2utils_numeric,
|
../utils/v2utils_numeric,
|
||||||
eth/common
|
eth/common
|
||||||
|
|
||||||
else:
|
else:
|
||||||
import macros
|
import macros
|
||||||
|
|
||||||
var blindGasCosts: array[Op,int]
|
var
|
||||||
|
GasBalance = 0
|
||||||
|
GasExtCode = 42
|
||||||
|
GasExtCodeHash = 7
|
||||||
|
blindGasCosts: array[Op,int]
|
||||||
|
blindAddress: EthAddress
|
||||||
|
gasFees: array[Fork,array[0..123,int]]
|
||||||
|
|
||||||
# copied from stack.nim
|
# copied from stack.nim
|
||||||
macro genTupleType(len: static[int], elemType: untyped): untyped =
|
macro genTupleType(len: static[int], elemType: untyped): untyped =
|
||||||
@ -50,7 +58,7 @@ else:
|
|||||||
|
|
||||||
# function stubs from stack.nim (to satisfy compiler logic)
|
# function stubs from stack.nim (to satisfy compiler logic)
|
||||||
proc push[T](x: Stack; n: T) = discard
|
proc push[T](x: Stack; n: T) = discard
|
||||||
proc popAddress(x: var Stack): UInt256 = 0.u256
|
proc popAddress(x: var Stack): EthAddress = blindAddress
|
||||||
proc popInt(x: var Stack, n: static[int]): auto =
|
proc popInt(x: var Stack, n: static[int]): auto =
|
||||||
var rc: genTupleType(n, UInt256)
|
var rc: genTupleType(n, UInt256)
|
||||||
return rc
|
return rc
|
||||||
@ -62,6 +70,7 @@ else:
|
|||||||
proc getCode[T](c: Computation, address: T): seq[byte] = @[]
|
proc getCode[T](c: Computation, address: T): seq[byte] = @[]
|
||||||
proc getGasPrice(c: Computation): Uint256 = 0.u256
|
proc getGasPrice(c: Computation): Uint256 = 0.u256
|
||||||
proc getOrigin(c: Computation): Uint256 = 0.u256
|
proc getOrigin(c: Computation): Uint256 = 0.u256
|
||||||
|
proc getCodeHash[T](c: Computation, address: T): Uint256 = 0.u256
|
||||||
|
|
||||||
# function stubs from v2utils_numeric.nim
|
# function stubs from v2utils_numeric.nim
|
||||||
func cleanMemRef(x: UInt256): int = 0
|
func cleanMemRef(x: UInt256): int = 0
|
||||||
@ -117,12 +126,25 @@ const
|
|||||||
k.cpt.stack.push:
|
k.cpt.stack.push:
|
||||||
k.cpt.msg.contractAddress
|
k.cpt.msg.contractAddress
|
||||||
|
|
||||||
|
# ------------------
|
||||||
|
|
||||||
balanceOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
balanceOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||||
## 0x31, Get balance of the given account.
|
## 0x31, Get balance of the given account.
|
||||||
let address = k.cpt.stack.popAddress
|
let address = k.cpt.stack.popAddress
|
||||||
k.cpt.stack.push:
|
k.cpt.stack.push:
|
||||||
k.cpt.getBalance(address)
|
k.cpt.getBalance(address)
|
||||||
|
|
||||||
|
balanceEIP2929Op: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||||
|
## 0x31, EIP292: Get balance of the given account for Berlin and later
|
||||||
|
let address = k.cpt.stack.popAddress()
|
||||||
|
|
||||||
|
k.cpt.gasEip2929AccountCheck(
|
||||||
|
address, gasFees[k.cpt.fork][GasBalance])
|
||||||
|
k.cpt.stack.push:
|
||||||
|
k.cpt.getBalance(address)
|
||||||
|
|
||||||
|
# ------------------
|
||||||
|
|
||||||
originOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
originOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||||
## 0x32, Get execution origination address.
|
## 0x32, Get execution origination address.
|
||||||
k.cpt.stack.push:
|
k.cpt.stack.push:
|
||||||
@ -204,7 +226,9 @@ const
|
|||||||
gasPriceOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
gasPriceOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||||
## 0x3A, Get price of gas in current environment.
|
## 0x3A, Get price of gas in current environment.
|
||||||
k.cpt.stack.push:
|
k.cpt.stack.push:
|
||||||
k.cpt.getGasPrice
|
k.cpt.getGasPrice()
|
||||||
|
|
||||||
|
# -----------
|
||||||
|
|
||||||
extCodeSizeOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
extCodeSizeOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||||
## 0x3b, Get size of an account's code
|
## 0x3b, Get size of an account's code
|
||||||
@ -212,6 +236,16 @@ const
|
|||||||
k.cpt.stack.push:
|
k.cpt.stack.push:
|
||||||
k.cpt.getCodeSize(address)
|
k.cpt.getCodeSize(address)
|
||||||
|
|
||||||
|
extCodeSizeEIP2929Op: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||||
|
## 0x3b, Get size of an account's code
|
||||||
|
let address = k.cpt.stack.popAddress()
|
||||||
|
|
||||||
|
k.cpt.gasEip2929AccountCheck(
|
||||||
|
address, gasFees[k.cpt.fork][GasExtCode])
|
||||||
|
k.cpt.stack.push:
|
||||||
|
k.cpt.getCodeSize(address)
|
||||||
|
|
||||||
|
# -----------
|
||||||
|
|
||||||
extCodeCopyOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
extCodeCopyOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||||
## 0x3c, Copy an account's code to memory.
|
## 0x3c, Copy an account's code to memory.
|
||||||
@ -229,6 +263,25 @@ const
|
|||||||
k.cpt.memory.writePaddedResult(codeBytes, memPos, codePos, len)
|
k.cpt.memory.writePaddedResult(codeBytes, memPos, codePos, len)
|
||||||
|
|
||||||
|
|
||||||
|
extCodeCopyEIP2929Op: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||||
|
## 0x3c, Copy an account's code to memory.
|
||||||
|
let address = k.cpt.stack.popAddress()
|
||||||
|
|
||||||
|
let (memStartPos, codeStartPos, size) = k.cpt.stack.popInt(3)
|
||||||
|
let (memPos, codePos, len) = (memStartPos.cleanMemRef,
|
||||||
|
codeStartPos.cleanMemRef, size.cleanMemRef)
|
||||||
|
k.cpt.gasMeter.consumeGas(
|
||||||
|
k.cpt.gasCosts[ExtCodeCopy].m_handler(k.cpt.memory.len, memPos, len),
|
||||||
|
reason = "ExtCodeCopy fee")
|
||||||
|
|
||||||
|
k.cpt.gasEip2929AccountCheck(
|
||||||
|
address, gasFees[k.cpt.fork][GasExtCode])
|
||||||
|
|
||||||
|
let codeBytes = k.cpt.getCode(address)
|
||||||
|
k.cpt.memory.writePaddedResult(codeBytes, memPos, codePos, len)
|
||||||
|
|
||||||
|
# -----------
|
||||||
|
|
||||||
returnDataSizeOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
returnDataSizeOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||||
## 0x3d, Get size of output data from the previous call from the
|
## 0x3d, Get size of output data from the previous call from the
|
||||||
## current environment.
|
## current environment.
|
||||||
@ -256,6 +309,24 @@ const
|
|||||||
"length")
|
"length")
|
||||||
k.cpt.memory.writePaddedResult(k.cpt.returnData, memPos, copyPos, len)
|
k.cpt.memory.writePaddedResult(k.cpt.returnData, memPos, copyPos, len)
|
||||||
|
|
||||||
|
# ---------------
|
||||||
|
|
||||||
|
extCodeHashOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||||
|
## 0x3f, Returns the keccak256 hash of a contract’s code
|
||||||
|
let address = k.cpt.stack.popAddress()
|
||||||
|
k.cpt.stack.push:
|
||||||
|
k.cpt.getCodeHash(address)
|
||||||
|
|
||||||
|
extCodeHashEIP2929Op: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||||
|
## 0x3f, EIP2929: Returns the keccak256 hash of a contract’s code
|
||||||
|
let address = k.cpt.stack.popAddress()
|
||||||
|
|
||||||
|
k.cpt.gasEip2929AccountCheck(
|
||||||
|
address, gasFees[k.cpt.fork][GasExtCodeHash])
|
||||||
|
|
||||||
|
k.cpt.stack.push:
|
||||||
|
k.cpt.getCodeHash(address)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public, op exec table entries
|
# Public, op exec table entries
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@ -271,12 +342,19 @@ const
|
|||||||
post: vm2OpIgnore)),
|
post: vm2OpIgnore)),
|
||||||
|
|
||||||
(opCode: Balance, ## 0x31, Balance
|
(opCode: Balance, ## 0x31, Balance
|
||||||
forks: Vm2OpAllForks,
|
forks: Vm2OpAllForks - Vm2OpBerlinAndLater,
|
||||||
info: "Get balance of the given account",
|
info: "Get balance of the given account",
|
||||||
exec: (prep: vm2OpIgnore,
|
exec: (prep: vm2OpIgnore,
|
||||||
run: balanceOp,
|
run: balanceOp,
|
||||||
post: vm2OpIgnore)),
|
post: vm2OpIgnore)),
|
||||||
|
|
||||||
|
(opCode: Balance, ## 0x31, Balance for Berlin and later
|
||||||
|
forks: Vm2OpBerlinAndLater,
|
||||||
|
info: "EIP2929: Get balance of the given account",
|
||||||
|
exec: (prep: vm2OpIgnore,
|
||||||
|
run: balanceEIP2929Op,
|
||||||
|
post: vm2OpIgnore)),
|
||||||
|
|
||||||
(opCode: Origin, ## 0x32, Origination address
|
(opCode: Origin, ## 0x32, Origination address
|
||||||
forks: Vm2OpAllForks,
|
forks: Vm2OpAllForks,
|
||||||
info: "Get execution origination address",
|
info: "Get execution origination address",
|
||||||
@ -342,19 +420,33 @@ const
|
|||||||
post: vm2OpIgnore)),
|
post: vm2OpIgnore)),
|
||||||
|
|
||||||
(opCode: ExtCodeSize, ## 0x3b, Account code size
|
(opCode: ExtCodeSize, ## 0x3b, Account code size
|
||||||
forks: Vm2OpAllForks,
|
forks: Vm2OpAllForks - Vm2OpBerlinAndLater,
|
||||||
info: "Get size of an account's code",
|
info: "Get size of an account's code",
|
||||||
exec: (prep: vm2OpIgnore,
|
exec: (prep: vm2OpIgnore,
|
||||||
run: extCodeSizeOp,
|
run: extCodeSizeOp,
|
||||||
post: vm2OpIgnore)),
|
post: vm2OpIgnore)),
|
||||||
|
|
||||||
|
(opCode: ExtCodeSize, ## 0x3b, Account code size for Berlin and later
|
||||||
|
forks: Vm2OpBerlinAndLater,
|
||||||
|
info: "EIP2929: Get size of an account's code",
|
||||||
|
exec: (prep: vm2OpIgnore,
|
||||||
|
run: extCodeSizeEIP2929Op,
|
||||||
|
post: vm2OpIgnore)),
|
||||||
|
|
||||||
(opCode: ExtCodeCopy, ## 0x3c, Account code copy to memory.
|
(opCode: ExtCodeCopy, ## 0x3c, Account code copy to memory.
|
||||||
forks: Vm2OpAllForks,
|
forks: Vm2OpAllForks - Vm2OpBerlinAndLater,
|
||||||
info: "Copy an account's code to memory",
|
info: "Copy an account's code to memory",
|
||||||
exec: (prep: vm2OpIgnore,
|
exec: (prep: vm2OpIgnore,
|
||||||
run: extCodeCopyOp,
|
run: extCodeCopyOp,
|
||||||
post: vm2OpIgnore)),
|
post: vm2OpIgnore)),
|
||||||
|
|
||||||
|
(opCode: ExtCodeCopy, ## 0x3c, Account Code-copy for Berlin and later
|
||||||
|
forks: Vm2OpBerlinAndLater,
|
||||||
|
info: "EIP2929: Copy an account's code to memory",
|
||||||
|
exec: (prep: vm2OpIgnore,
|
||||||
|
run: extCodeCopyEIP2929Op,
|
||||||
|
post: vm2OpIgnore)),
|
||||||
|
|
||||||
(opCode: ReturnDataSize, ## 0x3d, Previous call output data size
|
(opCode: ReturnDataSize, ## 0x3d, Previous call output data size
|
||||||
forks: Vm2OpAllForks,
|
forks: Vm2OpAllForks,
|
||||||
info: "Get size of output data from the previous call " &
|
info: "Get size of output data from the previous call " &
|
||||||
@ -368,6 +460,20 @@ const
|
|||||||
info: "Copy output data from the previous call to memory",
|
info: "Copy output data from the previous call to memory",
|
||||||
exec: (prep: vm2OpIgnore,
|
exec: (prep: vm2OpIgnore,
|
||||||
run: returnDataCopyOp,
|
run: returnDataCopyOp,
|
||||||
|
post: vm2OpIgnore)),
|
||||||
|
|
||||||
|
(opCode: ExtCodeHash, ## 0x3f, Contract hash
|
||||||
|
forks: Vm2OpAllForks - Vm2OpBerlinAndLater,
|
||||||
|
info: "Returns the keccak256 hash of a contract’s code",
|
||||||
|
exec: (prep: vm2OpIgnore,
|
||||||
|
run: extCodeHashOp,
|
||||||
|
post: vm2OpIgnore)),
|
||||||
|
|
||||||
|
(opCode: ExtCodeHash, ## 0x3f, Contract hash for berlin and later
|
||||||
|
forks: Vm2OpBerlinAndLater,
|
||||||
|
info: "EIP2929: Returns the keccak256 hash of a contract’s code",
|
||||||
|
exec: (prep: vm2OpIgnore,
|
||||||
|
run: extCodeHashEIP2929Op,
|
||||||
post: vm2OpIgnore))]
|
post: vm2OpIgnore))]
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -35,11 +35,34 @@ const
|
|||||||
|
|
||||||
when not breakCircularDependency:
|
when not breakCircularDependency:
|
||||||
import
|
import
|
||||||
../../v2types
|
../../../db/accounts_cache,
|
||||||
|
../../v2state,
|
||||||
|
../../v2types,
|
||||||
|
../gas_meter,
|
||||||
|
../v2gas_costs,
|
||||||
|
eth/common
|
||||||
|
|
||||||
else:
|
else:
|
||||||
const
|
const
|
||||||
emvcStatic = 1
|
emvcStatic = 1
|
||||||
|
ColdAccountAccessCost = 2
|
||||||
|
WarmStorageReadCost = 3
|
||||||
|
|
||||||
|
type
|
||||||
|
GasInt = int
|
||||||
|
|
||||||
|
# function stubs from v2state.nim
|
||||||
|
template mutateStateDB(vmState: BaseVMState, body: untyped) =
|
||||||
|
block:
|
||||||
|
var db {.inject.} = vmState.accountDb
|
||||||
|
body
|
||||||
|
|
||||||
|
# function stubs from accounts_cache.nim:
|
||||||
|
func inAccessList[A,B](ac: A; address: B): bool = false
|
||||||
|
proc accessList[A,B](ac: var A, address: B) = discard
|
||||||
|
|
||||||
|
# function stubs from gas_meter.nim
|
||||||
|
proc consumeGas(gasMeter: var GasMeter; amount: int; reason: string) = discard
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Kludge END
|
# Kludge END
|
||||||
@ -63,6 +86,20 @@ proc asText(id, name: string): NimNode {.compileTime.} =
|
|||||||
# Public
|
# Public
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
proc gasEip2929AccountCheck*(c: Computation;
|
||||||
|
address: EthAddress, prevCost = 0.GasInt) =
|
||||||
|
c.vmState.mutateStateDB:
|
||||||
|
let gasCost = if not db.inAccessList(address):
|
||||||
|
db.accessList(address)
|
||||||
|
ColdAccountAccessCost
|
||||||
|
else:
|
||||||
|
WarmStorageReadCost
|
||||||
|
|
||||||
|
c.gasMeter.consumeGas(
|
||||||
|
gasCost - prevCost,
|
||||||
|
reason = "gasEIP2929AccountCheck")
|
||||||
|
|
||||||
|
|
||||||
template checkInStaticContext*(c: Computation) =
|
template checkInStaticContext*(c: Computation) =
|
||||||
## Verify static context in handler function, raise an error otherwise
|
## Verify static context in handler function, raise an error otherwise
|
||||||
if emvcStatic == c.msg.flags:
|
if emvcStatic == c.msg.flags:
|
||||||
|
@ -36,7 +36,6 @@ when not breakCircularDependency:
|
|||||||
../../stack,
|
../../stack,
|
||||||
../../v2computation,
|
../../v2computation,
|
||||||
../../v2memory,
|
../../v2memory,
|
||||||
../../v2state,
|
|
||||||
../../v2types,
|
../../v2types,
|
||||||
../gas_meter,
|
../gas_meter,
|
||||||
../utils/v2utils_numeric,
|
../utils/v2utils_numeric,
|
||||||
|
@ -39,12 +39,15 @@ when not breakCircularDependency:
|
|||||||
../gas_meter,
|
../gas_meter,
|
||||||
../utils/v2utils_numeric,
|
../utils/v2utils_numeric,
|
||||||
../v2gas_costs,
|
../v2gas_costs,
|
||||||
eth/common,
|
eth/common
|
||||||
times
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
import macros
|
import macros
|
||||||
|
|
||||||
|
const
|
||||||
|
ColdSloadCost = 42
|
||||||
|
WarmStorageReadCost = 43
|
||||||
|
|
||||||
var blindGasCosts: array[Op,int]
|
var blindGasCosts: array[Op,int]
|
||||||
|
|
||||||
# copied from stack.nim
|
# copied from stack.nim
|
||||||
@ -79,7 +82,10 @@ else:
|
|||||||
|
|
||||||
# function stubs from v2state.nim
|
# function stubs from v2state.nim
|
||||||
proc readOnlyStateDB(x: BaseVMState): ReadOnlyStateDB = x.accountDb
|
proc readOnlyStateDB(x: BaseVMState): ReadOnlyStateDB = x.accountDb
|
||||||
template mutateStateDB(vmState: BaseVMState, body: untyped) = discard
|
template mutateStateDB(vmState: BaseVMState, body: untyped) =
|
||||||
|
block:
|
||||||
|
var db {.inject.} = vmState.accountDb
|
||||||
|
body
|
||||||
|
|
||||||
# function stubs from gas_meter.nim
|
# function stubs from gas_meter.nim
|
||||||
proc refundGas(gasMeter: var GasMeter; amount: int) = discard
|
proc refundGas(gasMeter: var GasMeter; amount: int) = discard
|
||||||
@ -99,6 +105,11 @@ else:
|
|||||||
# function stubs from state_db.nim
|
# function stubs from state_db.nim
|
||||||
proc getCommittedStorage[A,B](x: A; y: B; z: Uint256): Uint256 = 0.u256
|
proc getCommittedStorage[A,B](x: A; y: B; z: Uint256): Uint256 = 0.u256
|
||||||
|
|
||||||
|
# function stubs from accounts_cache.nim:
|
||||||
|
func inAccessList[A,B](ac: A; address: B; slot: UInt256): bool = false
|
||||||
|
proc accessList[A,B](ac: var A; address: B; slot: UInt256) = discard
|
||||||
|
proc setStorage[A,B](ac: var A; address: B, slot, value: UInt256) = discard
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Kludge END
|
# Kludge END
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@ -195,6 +206,7 @@ const
|
|||||||
k.cpt.memory.extend(memPos, 1)
|
k.cpt.memory.extend(memPos, 1)
|
||||||
k.cpt.memory.write(memPos, [value.toByteArrayBE[31]])
|
k.cpt.memory.write(memPos, [value.toByteArrayBE[31]])
|
||||||
|
|
||||||
|
# -------
|
||||||
|
|
||||||
sloadOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
sloadOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||||
## 0x54, Load word from storage.
|
## 0x54, Load word from storage.
|
||||||
@ -202,6 +214,22 @@ const
|
|||||||
k.cpt.stack.push:
|
k.cpt.stack.push:
|
||||||
k.cpt.getStorage(slot)
|
k.cpt.getStorage(slot)
|
||||||
|
|
||||||
|
sloadEIP2929Op: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||||
|
## 0x54, EIP2929: Load word from storage for Berlin and later
|
||||||
|
let (slot) = k.cpt.stack.popInt(1)
|
||||||
|
|
||||||
|
k.cpt.vmState.mutateStateDB:
|
||||||
|
let gasCost = if not db.inAccessList(k.cpt.msg.contractAddress, slot):
|
||||||
|
db.accessList(k.cpt.msg.contractAddress, slot)
|
||||||
|
ColdSloadCost
|
||||||
|
else:
|
||||||
|
WarmStorageReadCost
|
||||||
|
k.cpt.gasMeter.consumeGas(gasCost, reason = "sloadEIP2929")
|
||||||
|
k.cpt.stack.push:
|
||||||
|
k.cpt.getStorage(slot)
|
||||||
|
|
||||||
|
# -------
|
||||||
|
|
||||||
sstoreOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
sstoreOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||||
## 0x55, Save word to storage.
|
## 0x55, Save word to storage.
|
||||||
let (slot, newValue) = k.cpt.stack.popInt(2)
|
let (slot, newValue) = k.cpt.stack.popInt(2)
|
||||||
@ -251,6 +279,26 @@ const
|
|||||||
sstoreNetGasMeteringImpl(k.cpt, slot, newValue)
|
sstoreNetGasMeteringImpl(k.cpt, slot, newValue)
|
||||||
|
|
||||||
|
|
||||||
|
sstoreEIP2929Op: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||||
|
## 0x55, EIP2929: sstore for Berlin and later
|
||||||
|
let (slot, newValue) = k.cpt.stack.popInt(2)
|
||||||
|
checkInStaticContext(k.cpt)
|
||||||
|
|
||||||
|
# Minimum gas required to be present for an SSTORE call, not consumed
|
||||||
|
const SentryGasEIP2200 = 2300
|
||||||
|
|
||||||
|
if k.cpt.gasMeter.gasRemaining <= SentryGasEIP2200:
|
||||||
|
raise newException(OutOfGas, "Gas not enough to perform EIP2200 SSTORE")
|
||||||
|
|
||||||
|
k.cpt.vmState.mutateStateDB:
|
||||||
|
if not db.inAccessList(k.cpt.msg.contractAddress, slot):
|
||||||
|
db.accessList(k.cpt.msg.contractAddress, slot)
|
||||||
|
k.cpt.gasMeter.consumeGas(ColdSloadCost, reason = "sstoreEIP2929")
|
||||||
|
|
||||||
|
sstoreNetGasMeteringImpl(k.cpt, slot, newValue)
|
||||||
|
|
||||||
|
# -------
|
||||||
|
|
||||||
jumpOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
jumpOp: Vm2OpFn = proc (k: Vm2Ctx) =
|
||||||
## 0x56, Alter the program counter
|
## 0x56, Alter the program counter
|
||||||
let (jumpTarget) = k.cpt.stack.popInt(1)
|
let (jumpTarget) = k.cpt.stack.popInt(1)
|
||||||
@ -360,12 +408,19 @@ const
|
|||||||
post: vm2OpIgnore)),
|
post: vm2OpIgnore)),
|
||||||
|
|
||||||
(opCode: Sload, ## 0x54, Load word from storage
|
(opCode: Sload, ## 0x54, Load word from storage
|
||||||
forks: Vm2OpAllForks,
|
forks: Vm2OpAllForks - Vm2OpBerlinAndLater,
|
||||||
info: "Load word from storage",
|
info: "Load word from storage",
|
||||||
exec: (prep: vm2OpIgnore,
|
exec: (prep: vm2OpIgnore,
|
||||||
run: sloadOp,
|
run: sloadOp,
|
||||||
post: vm2OpIgnore)),
|
post: vm2OpIgnore)),
|
||||||
|
|
||||||
|
(opCode: Sload, ## 0x54, sload for Berlin and later
|
||||||
|
forks: Vm2OpBerlinAndLater,
|
||||||
|
info: "EIP2929: sload for Berlin and later",
|
||||||
|
exec: (prep: vm2OpIgnore,
|
||||||
|
run: sloadEIP2929Op,
|
||||||
|
post: vm2OpIgnore)),
|
||||||
|
|
||||||
(opCode: Sstore, ## 0x55, Save word
|
(opCode: Sstore, ## 0x55, Save word
|
||||||
forks: Vm2OpAllForks - Vm2OpConstantinopleAndLater,
|
forks: Vm2OpAllForks - Vm2OpConstantinopleAndLater,
|
||||||
info: "Save word to storage",
|
info: "Save word to storage",
|
||||||
@ -381,12 +436,19 @@ const
|
|||||||
post: vm2OpIgnore)),
|
post: vm2OpIgnore)),
|
||||||
|
|
||||||
(opCode: Sstore, ## 0x55, sstore for Istanbul and later
|
(opCode: Sstore, ## 0x55, sstore for Istanbul and later
|
||||||
forks: Vm2OpIstanbulAndLater,
|
forks: Vm2OpIstanbulAndLater - Vm2OpBerlinAndLater,
|
||||||
info: "EIP2200: sstore for Istanbul and later",
|
info: "EIP2200: sstore for Istanbul and later",
|
||||||
exec: (prep: vm2OpIgnore,
|
exec: (prep: vm2OpIgnore,
|
||||||
run: sstoreEIP2200Op,
|
run: sstoreEIP2200Op,
|
||||||
post: vm2OpIgnore)),
|
post: vm2OpIgnore)),
|
||||||
|
|
||||||
|
(opCode: Sstore, ## 0x55, sstore for Berlin and later
|
||||||
|
forks: Vm2OpBerlinAndLater,
|
||||||
|
info: "EIP2929: sstore for Istanbul and later",
|
||||||
|
exec: (prep: vm2OpIgnore,
|
||||||
|
run: sstoreEIP2929Op,
|
||||||
|
post: vm2OpIgnore)),
|
||||||
|
|
||||||
(opCode: Jump, ## 0x56, Jump
|
(opCode: Jump, ## 0x56, Jump
|
||||||
forks: Vm2OpIstanbulAndLater,
|
forks: Vm2OpIstanbulAndLater,
|
||||||
info: "Alter the program counter",
|
info: "Alter the program counter",
|
||||||
|
@ -124,8 +124,8 @@ opHandler sarOp, Op.Sar
|
|||||||
opHandler sha3, Op.Sha3
|
opHandler sha3, Op.Sha3
|
||||||
opHandler address, Op.Address
|
opHandler address, Op.Address
|
||||||
|
|
||||||
opHandler balance, Op.Balance, FkFrontier
|
opHandler balance, Op.Balance, FkFrontier
|
||||||
opHandler balanceEIP2929, Op.Balance
|
opHandler balanceEIP2929, Op.Balance
|
||||||
|
|
||||||
opHandler origin, Op.Origin
|
opHandler origin, Op.Origin
|
||||||
opHandler caller, Op.Caller
|
opHandler caller, Op.Caller
|
||||||
@ -145,6 +145,10 @@ opHandler extCodeCopyEIP2929, Op.ExtCodeCopy
|
|||||||
|
|
||||||
opHandler returnDataSize, Op.ReturnDataSize
|
opHandler returnDataSize, Op.ReturnDataSize
|
||||||
opHandler returnDataCopy, Op.ReturnDataCopy
|
opHandler returnDataCopy, Op.ReturnDataCopy
|
||||||
|
|
||||||
|
opHandler extCodeHash, Op.ExtCodeHash, FkFrontier
|
||||||
|
opHandler extCodeHashEIP2929, Op.ExtCodeHash
|
||||||
|
|
||||||
opHandler blockhash, Op.Blockhash
|
opHandler blockhash, Op.Blockhash
|
||||||
opHandler coinbase, Op.Coinbase
|
opHandler coinbase, Op.Coinbase
|
||||||
opHandler timestamp, Op.Timestamp
|
opHandler timestamp, Op.Timestamp
|
||||||
@ -158,13 +162,13 @@ opHandler mload, Op.Mload
|
|||||||
opHandler mstore, Op.Mstore
|
opHandler mstore, Op.Mstore
|
||||||
opHandler mstore8, Op.Mstore8
|
opHandler mstore8, Op.Mstore8
|
||||||
|
|
||||||
opHandler sload, Op.Sload, FkFrontier
|
opHandler sload, Op.Sload, FkFrontier
|
||||||
opHandler sloadEIP2929, Op.Sload
|
opHandler sloadEIP2929, Op.Sload
|
||||||
|
|
||||||
opHandler sstore, Op.Sstore, FkFrontier
|
opHandler sstore, Op.Sstore, FkFrontier
|
||||||
opHandler sstoreEIP1283, Op.Sstore, FkConstantinople
|
opHandler sstoreEIP1283, Op.Sstore, FkConstantinople
|
||||||
opHandler sstoreEIP2200, Op.Sstore, FkIstanbul
|
opHandler sstoreEIP2200, Op.Sstore, FkIstanbul
|
||||||
opHandler sstoreEIP2929, Op.Sstore
|
opHandler sstoreEIP2929, Op.Sstore
|
||||||
|
|
||||||
opHandler jump, Op.Jump
|
opHandler jump, Op.Jump
|
||||||
opHandler jumpI, Op.JumpI
|
opHandler jumpI, Op.JumpI
|
||||||
@ -545,16 +549,6 @@ op selfDestructEip161, inline = false:
|
|||||||
c.selfDestruct(beneficiary)
|
c.selfDestruct(beneficiary)
|
||||||
|
|
||||||
# Constantinople's new opcodes
|
# Constantinople's new opcodes
|
||||||
#################################
|
|
||||||
|
|
||||||
op extCodeHash, inline = true:
|
|
||||||
let address = c.stack.popAddress()
|
|
||||||
push: c.getCodeHash(address)
|
|
||||||
|
|
||||||
op extCodeHashEIP2929, inline = true:
|
|
||||||
let address = c.stack.popAddress()
|
|
||||||
c.gasEip2929AccountCheck(address, gasFees[c.fork][GasExtCodeHash])
|
|
||||||
push: c.getCodeHash(address)
|
|
||||||
|
|
||||||
op selfDestructEIP2929, inline = false:
|
op selfDestructEIP2929, inline = false:
|
||||||
checkInStaticContext(c)
|
checkInStaticContext(c)
|
||||||
@ -577,60 +571,3 @@ op selfDestructEIP2929, inline = false:
|
|||||||
|
|
||||||
c.gasMeter.consumeGas(gasCost, reason = "SELFDESTRUCT EIP161")
|
c.gasMeter.consumeGas(gasCost, reason = "SELFDESTRUCT EIP161")
|
||||||
c.selfDestruct(beneficiary)
|
c.selfDestruct(beneficiary)
|
||||||
|
|
||||||
# ---------------------------------------------------
|
|
||||||
|
|
||||||
op balanceEIP2929x, inline = true:
|
|
||||||
## 0x31, Get balance of the given account.
|
|
||||||
let address = c.stack.popAddress()
|
|
||||||
|
|
||||||
c.gasEip2929AccountCheck(address, gasFees[c.fork][GasBalance])
|
|
||||||
push: c.getBalance(address)
|
|
||||||
|
|
||||||
op extCodeSizeEIP2929x, inline = true:
|
|
||||||
## 0x3b, Get size of an account's code
|
|
||||||
let address = c.stack.popAddress()
|
|
||||||
c.gasEip2929AccountCheck(address, gasFees[c.fork][GasExtCode])
|
|
||||||
push: c.getCodeSize(address)
|
|
||||||
|
|
||||||
op extCodeCopyEIP2929x, inline = true:
|
|
||||||
## 0x3c, Copy an account's code to memory.
|
|
||||||
let address = c.stack.popAddress()
|
|
||||||
let (memStartPos, codeStartPos, size) = c.stack.popInt(3)
|
|
||||||
let (memPos, codePos, len) = (memStartPos.cleanMemRef, codeStartPos.cleanMemRef, size.cleanMemRef)
|
|
||||||
|
|
||||||
c.gasMeter.consumeGas(
|
|
||||||
c.gasCosts[ExtCodeCopy].m_handler(c.memory.len, memPos, len),
|
|
||||||
reason="ExtCodeCopy fee")
|
|
||||||
|
|
||||||
c.gasEip2929AccountCheck(address, gasFees[c.fork][GasExtCode])
|
|
||||||
|
|
||||||
let codeBytes = c.getCode(address)
|
|
||||||
c.memory.writePaddedResult(codeBytes, memPos, codePos, len)
|
|
||||||
|
|
||||||
op sloadEIP2929x, inline = true, slot:
|
|
||||||
## 0x54, Load word from storage.
|
|
||||||
c.vmState.mutateStateDB:
|
|
||||||
let gasCost = if not db.inAccessList(c.msg.contractAddress, slot):
|
|
||||||
db.accessList(c.msg.contractAddress, slot)
|
|
||||||
ColdSloadCost
|
|
||||||
else:
|
|
||||||
WarmStorageReadCost
|
|
||||||
c.gasMeter.consumeGas(gasCost, reason = "sloadEIP2929")
|
|
||||||
|
|
||||||
push: c.getStorage(slot)
|
|
||||||
|
|
||||||
op sstoreEIP2929x, inline = false, slot, newValue:
|
|
||||||
checkInStaticContext(c)
|
|
||||||
const SentryGasEIP2200 = 2300 # Minimum gas required to be present for an SSTORE call, not consumed
|
|
||||||
|
|
||||||
if c.gasMeter.gasRemaining <= SentryGasEIP2200:
|
|
||||||
raise newException(OutOfGas, "Gas not enough to perform EIP2200 SSTORE")
|
|
||||||
|
|
||||||
c.vmState.mutateStateDB:
|
|
||||||
if not db.inAccessList(c.msg.contractAddress, slot):
|
|
||||||
db.accessList(c.msg.contractAddress, slot)
|
|
||||||
c.gasMeter.consumeGas(ColdSloadCost, reason = "sstoreEIP2929")
|
|
||||||
|
|
||||||
block:
|
|
||||||
sstoreNetGasMeteringImpl(c, slot, newValue)
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user