2021-04-08 14:52:10 +00:00
|
|
|
# Nimbus
|
2024-01-09 15:15:19 +00:00
|
|
|
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
2021-04-08 14:52:10 +00:00
|
|
|
# Licensed under either of
|
|
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0)
|
|
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
|
|
|
# http://opensource.org/licenses/MIT)
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except
|
|
|
|
# according to those terms.
|
|
|
|
|
2023-02-14 20:27:17 +00:00
|
|
|
{.push raises: [].}
|
|
|
|
|
2021-04-08 14:52:10 +00:00
|
|
|
import
|
2023-11-20 20:22:27 +00:00
|
|
|
std/[options, sets, strformat],
|
2024-01-22 09:11:37 +00:00
|
|
|
eth/keys,
|
|
|
|
../../stateless/[witness_from_tree, witness_types, multi_keys],
|
2023-12-12 19:12:56 +00:00
|
|
|
../db/ledger,
|
2022-12-02 04:35:41 +00:00
|
|
|
../common/[common, evmforks],
|
2023-08-27 06:13:37 +00:00
|
|
|
./interpreter/[op_codes, gas_costs],
|
2023-01-31 12:38:08 +00:00
|
|
|
./types
|
2021-07-27 11:28:05 +00:00
|
|
|
|
2022-01-18 16:19:32 +00:00
|
|
|
proc init(
|
2023-04-12 12:39:11 +00:00
|
|
|
self: BaseVMState;
|
2023-12-12 19:12:56 +00:00
|
|
|
ac: LedgerRef,
|
2023-04-12 12:39:11 +00:00
|
|
|
parent: BlockHeader;
|
2023-09-24 15:25:41 +00:00
|
|
|
blockCtx: BlockContext;
|
2023-04-12 12:39:11 +00:00
|
|
|
com: CommonRef;
|
2023-08-02 10:17:40 +00:00
|
|
|
tracer: TracerRef,
|
2024-05-30 09:03:54 +00:00
|
|
|
flags: set[VMFlag] = self.flags) =
|
2022-01-18 16:19:32 +00:00
|
|
|
## Initialisation helper
|
|
|
|
self.parent = parent
|
2023-09-24 15:25:41 +00:00
|
|
|
self.blockCtx = blockCtx
|
|
|
|
self.gasPool = blockCtx.gasLimit
|
2022-12-02 04:35:41 +00:00
|
|
|
self.com = com
|
2022-01-18 16:19:32 +00:00
|
|
|
self.tracer = tracer
|
2021-10-28 09:42:39 +00:00
|
|
|
self.stateDB = ac
|
2024-01-09 15:15:19 +00:00
|
|
|
self.flags = flags
|
2022-01-18 16:19:32 +00:00
|
|
|
|
2023-09-24 15:25:41 +00:00
|
|
|
func blockCtx(com: CommonRef, header: BlockHeader):
|
2024-05-30 09:03:54 +00:00
|
|
|
BlockContext =
|
2023-09-24 15:25:41 +00:00
|
|
|
BlockContext(
|
|
|
|
timestamp : header.timestamp,
|
|
|
|
gasLimit : header.gasLimit,
|
|
|
|
fee : header.fee,
|
|
|
|
prevRandao : header.prevRandao,
|
|
|
|
difficulty : header.difficulty,
|
|
|
|
coinbase : com.minerAddress(header),
|
|
|
|
excessBlobGas: header.excessBlobGas.get(0'u64),
|
|
|
|
)
|
|
|
|
|
2022-01-18 16:19:32 +00:00
|
|
|
# --------------
|
|
|
|
|
|
|
|
proc `$`*(vmState: BaseVMState): string
|
2023-01-31 12:38:08 +00:00
|
|
|
{.gcsafe, raises: [ValueError].} =
|
2022-01-18 16:19:32 +00:00
|
|
|
if vmState.isNil:
|
|
|
|
result = "nil"
|
|
|
|
else:
|
2022-12-02 04:35:41 +00:00
|
|
|
result = &"VMState:"&
|
|
|
|
&"\n blockNumber: {vmState.parent.blockNumber + 1}"
|
2022-01-18 16:19:32 +00:00
|
|
|
|
|
|
|
proc new*(
|
2023-09-24 15:25:41 +00:00
|
|
|
T: type BaseVMState;
|
|
|
|
parent: BlockHeader; ## parent header, account sync position
|
|
|
|
blockCtx: BlockContext;
|
|
|
|
com: CommonRef; ## block chain config
|
2024-05-30 09:03:54 +00:00
|
|
|
tracer: TracerRef = nil): T =
|
2022-01-18 16:19:32 +00:00
|
|
|
## Create a new `BaseVMState` descriptor from a parent block header. This
|
|
|
|
## function internally constructs a new account state cache rooted at
|
|
|
|
## `parent.stateRoot`
|
|
|
|
##
|
|
|
|
## This `new()` constructor and its variants (see below) provide a save
|
|
|
|
## `BaseVMState` environment where the account state cache is synchronised
|
|
|
|
## with the `parent` block header.
|
|
|
|
new result
|
|
|
|
result.init(
|
2024-05-29 11:06:49 +00:00
|
|
|
ac = LedgerRef.init(com.db, parent.stateRoot),
|
2023-09-24 15:25:41 +00:00
|
|
|
parent = parent,
|
|
|
|
blockCtx = blockCtx,
|
|
|
|
com = com,
|
|
|
|
tracer = tracer)
|
|
|
|
|
|
|
|
proc reinit*(self: BaseVMState; ## Object descriptor
|
|
|
|
parent: BlockHeader; ## parent header, account sync pos.
|
|
|
|
blockCtx: BlockContext
|
2024-05-30 09:03:54 +00:00
|
|
|
): bool =
|
2023-12-12 19:12:56 +00:00
|
|
|
## Re-initialise state descriptor. The `LedgerRef` database is
|
2022-01-18 16:19:32 +00:00
|
|
|
## re-initilaise only if its `rootHash` doe not point to `parent.stateRoot`,
|
|
|
|
## already. Accumulated state data are reset.
|
|
|
|
##
|
2023-12-12 19:12:56 +00:00
|
|
|
## This function returns `true` unless the `LedgerRef` database could be
|
2022-01-18 16:19:32 +00:00
|
|
|
## queries about its `rootHash`, i.e. `isTopLevelClean` evaluated `true`. If
|
|
|
|
## this function returns `false`, the function argument `self` is left
|
|
|
|
## untouched.
|
|
|
|
if self.stateDB.isTopLevelClean:
|
|
|
|
let
|
|
|
|
tracer = self.tracer
|
2022-12-02 04:35:41 +00:00
|
|
|
com = self.com
|
|
|
|
db = com.db
|
2022-01-18 16:19:32 +00:00
|
|
|
ac = if self.stateDB.rootHash == parent.stateRoot: self.stateDB
|
2024-05-29 11:06:49 +00:00
|
|
|
else: LedgerRef.init(db, parent.stateRoot)
|
2024-01-09 15:15:19 +00:00
|
|
|
flags = self.flags
|
2022-01-18 16:19:32 +00:00
|
|
|
self[].reset
|
|
|
|
self.init(
|
2023-09-24 15:25:41 +00:00
|
|
|
ac = ac,
|
|
|
|
parent = parent,
|
|
|
|
blockCtx = blockCtx,
|
|
|
|
com = com,
|
2024-01-09 15:15:19 +00:00
|
|
|
tracer = tracer,
|
|
|
|
flags = flags)
|
2022-01-18 16:19:32 +00:00
|
|
|
return true
|
|
|
|
# else: false
|
|
|
|
|
2023-09-24 15:25:41 +00:00
|
|
|
proc reinit*(self: BaseVMState; ## Object descriptor
|
|
|
|
parent: BlockHeader; ## parent header, account sync pos.
|
|
|
|
header: BlockHeader; ## header with tx environment data fields
|
2024-05-30 09:03:54 +00:00
|
|
|
): bool =
|
2022-01-18 16:19:32 +00:00
|
|
|
## Variant of `reinit()`. The `parent` argument is used to sync the accounts
|
|
|
|
## cache and the `header` is used as a container to pass the `timestamp`,
|
|
|
|
## `gasLimit`, and `fee` values.
|
|
|
|
##
|
|
|
|
## It requires the `header` argument properly initalised so that for PoA
|
|
|
|
## networks, the miner address is retrievable via `ecRecover()`.
|
2022-03-15 17:21:41 +00:00
|
|
|
result = self.reinit(
|
2023-09-24 15:25:41 +00:00
|
|
|
parent = parent,
|
|
|
|
blockCtx = self.com.blockCtx(header),
|
|
|
|
)
|
2022-01-18 16:19:32 +00:00
|
|
|
|
|
|
|
proc reinit*(self: BaseVMState; ## Object descriptor
|
|
|
|
header: BlockHeader; ## header with tx environment data fields
|
2024-05-30 09:03:54 +00:00
|
|
|
): bool =
|
2022-01-18 16:19:32 +00:00
|
|
|
## This is a variant of the `reinit()` function above where the field
|
|
|
|
## `header.parentHash`, is used to fetch the `parent` BlockHeader to be
|
|
|
|
## used in the `update()` variant, above.
|
2022-07-21 12:14:41 +00:00
|
|
|
var parent: BlockHeader
|
2022-12-02 04:35:41 +00:00
|
|
|
if self.com.db.getBlockHeader(header.parentHash, parent):
|
2022-07-21 12:14:41 +00:00
|
|
|
return self.reinit(
|
|
|
|
parent = parent,
|
2022-12-02 04:35:41 +00:00
|
|
|
header = header)
|
2022-01-18 16:19:32 +00:00
|
|
|
|
|
|
|
proc init*(
|
2023-08-02 10:17:40 +00:00
|
|
|
self: BaseVMState; ## Object descriptor
|
|
|
|
parent: BlockHeader; ## parent header, account sync position
|
|
|
|
header: BlockHeader; ## header with tx environment data fields
|
|
|
|
com: CommonRef; ## block chain config
|
2024-05-30 09:03:54 +00:00
|
|
|
tracer: TracerRef = nil) =
|
2022-01-18 16:19:32 +00:00
|
|
|
## Variant of `new()` constructor above for in-place initalisation. The
|
|
|
|
## `parent` argument is used to sync the accounts cache and the `header`
|
|
|
|
## is used as a container to pass the `timestamp`, `gasLimit`, and `fee`
|
|
|
|
## values.
|
|
|
|
##
|
|
|
|
## It requires the `header` argument properly initalised so that for PoA
|
|
|
|
## networks, the miner address is retrievable via `ecRecover()`.
|
2022-03-15 17:21:41 +00:00
|
|
|
self.init(
|
2024-05-29 11:06:49 +00:00
|
|
|
ac = LedgerRef.init(com.db, parent.stateRoot),
|
2023-09-24 15:25:41 +00:00
|
|
|
parent = parent,
|
|
|
|
blockCtx = com.blockCtx(header),
|
|
|
|
com = com,
|
|
|
|
tracer = tracer)
|
2022-01-18 16:19:32 +00:00
|
|
|
|
|
|
|
proc new*(
|
2023-08-02 10:17:40 +00:00
|
|
|
T: type BaseVMState;
|
|
|
|
parent: BlockHeader; ## parent header, account sync position
|
|
|
|
header: BlockHeader; ## header with tx environment data fields
|
|
|
|
com: CommonRef; ## block chain config
|
2024-05-30 09:03:54 +00:00
|
|
|
tracer: TracerRef = nil): T =
|
2022-01-18 16:19:32 +00:00
|
|
|
## This is a variant of the `new()` constructor above where the `parent`
|
|
|
|
## argument is used to sync the accounts cache and the `header` is used
|
|
|
|
## as a container to pass the `timestamp`, `gasLimit`, and `fee` values.
|
|
|
|
##
|
|
|
|
## It requires the `header` argument properly initalised so that for PoA
|
|
|
|
## networks, the miner address is retrievable via `ecRecover()`.
|
2021-04-08 14:52:10 +00:00
|
|
|
new result
|
2022-01-18 16:19:32 +00:00
|
|
|
result.init(
|
2023-08-02 10:17:40 +00:00
|
|
|
parent = parent,
|
|
|
|
header = header,
|
|
|
|
com = com,
|
|
|
|
tracer = tracer)
|
2022-01-18 16:19:32 +00:00
|
|
|
|
|
|
|
proc new*(
|
2023-08-02 10:17:40 +00:00
|
|
|
T: type BaseVMState;
|
|
|
|
header: BlockHeader; ## header with tx environment data fields
|
|
|
|
com: CommonRef; ## block chain config
|
|
|
|
tracer: TracerRef = nil): T
|
2023-01-31 12:38:08 +00:00
|
|
|
{.gcsafe, raises: [CatchableError].} =
|
2022-01-18 16:19:32 +00:00
|
|
|
## This is a variant of the `new()` constructor above where the field
|
|
|
|
## `header.parentHash`, is used to fetch the `parent` BlockHeader to be
|
|
|
|
## used in the `new()` variant, above.
|
|
|
|
BaseVMState.new(
|
2023-08-02 10:17:40 +00:00
|
|
|
parent = com.db.getBlockHeader(header.parentHash),
|
|
|
|
header = header,
|
|
|
|
com = com,
|
|
|
|
tracer = tracer)
|
2022-01-18 16:19:32 +00:00
|
|
|
|
2022-07-21 12:14:41 +00:00
|
|
|
proc init*(
|
2023-08-02 10:17:40 +00:00
|
|
|
vmState: BaseVMState;
|
|
|
|
header: BlockHeader; ## header with tx environment data fields
|
|
|
|
com: CommonRef; ## block chain config
|
2024-05-30 09:03:54 +00:00
|
|
|
tracer: TracerRef = nil): bool =
|
2022-07-21 12:14:41 +00:00
|
|
|
## Variant of `new()` which does not throw an exception on a dangling
|
|
|
|
## `BlockHeader` parent hash reference.
|
|
|
|
var parent: BlockHeader
|
2022-12-02 04:35:41 +00:00
|
|
|
if com.db.getBlockHeader(header.parentHash, parent):
|
2022-07-21 12:14:41 +00:00
|
|
|
vmState.init(
|
2023-08-02 10:17:40 +00:00
|
|
|
parent = parent,
|
|
|
|
header = header,
|
|
|
|
com = com,
|
|
|
|
tracer = tracer)
|
2022-07-21 12:14:41 +00:00
|
|
|
return true
|
|
|
|
|
2024-05-16 15:00:20 +00:00
|
|
|
proc coinbase*(vmState: BaseVMState): EthAddress =
|
2023-09-24 15:25:41 +00:00
|
|
|
vmState.blockCtx.coinbase
|
2021-04-08 14:52:10 +00:00
|
|
|
|
2024-05-16 15:00:20 +00:00
|
|
|
proc blockNumber*(vmState: BaseVMState): BlockNumber =
|
2021-04-08 14:52:10 +00:00
|
|
|
# it should return current block number
|
|
|
|
# and not head.blockNumber
|
2022-01-18 16:19:32 +00:00
|
|
|
vmState.parent.blockNumber + 1
|
2021-04-08 14:52:10 +00:00
|
|
|
|
2024-05-16 15:00:20 +00:00
|
|
|
proc difficultyOrPrevRandao*(vmState: BaseVMState): UInt256 =
|
2022-12-02 04:35:41 +00:00
|
|
|
if vmState.com.consensus == ConsensusType.POS:
|
2022-02-05 09:15:50 +00:00
|
|
|
# EIP-4399/EIP-3675
|
2023-09-24 15:25:41 +00:00
|
|
|
UInt256.fromBytesBE(vmState.blockCtx.prevRandao.data)
|
2022-02-05 09:15:50 +00:00
|
|
|
else:
|
2023-09-24 15:25:41 +00:00
|
|
|
vmState.blockCtx.difficulty
|
2021-04-08 14:52:10 +00:00
|
|
|
|
2024-05-16 15:00:20 +00:00
|
|
|
proc baseFee*(vmState: BaseVMState): UInt256 =
|
2023-09-24 15:25:41 +00:00
|
|
|
vmState.blockCtx.fee.get(0.u256)
|
2021-06-27 13:19:22 +00:00
|
|
|
|
2023-01-31 12:38:08 +00:00
|
|
|
method getAncestorHash*(
|
|
|
|
vmState: BaseVMState, blockNumber: BlockNumber):
|
|
|
|
Hash256 {.base, gcsafe, raises: [CatchableError].} =
|
2022-12-02 04:35:41 +00:00
|
|
|
let db = vmState.com.db
|
2024-05-16 15:00:20 +00:00
|
|
|
db.getBlockHash(blockNumber)
|
2022-12-02 04:35:41 +00:00
|
|
|
|
2021-04-08 14:52:10 +00:00
|
|
|
proc readOnlyStateDB*(vmState: BaseVMState): ReadOnlyStateDB {.inline.} =
|
2021-10-28 09:42:39 +00:00
|
|
|
ReadOnlyStateDB(vmState.stateDB)
|
2021-04-08 14:52:10 +00:00
|
|
|
|
|
|
|
template mutateStateDB*(vmState: BaseVMState, body: untyped) =
|
|
|
|
block:
|
2021-10-28 09:42:39 +00:00
|
|
|
var db {.inject.} = vmState.stateDB
|
2021-04-08 14:52:10 +00:00
|
|
|
body
|
|
|
|
|
|
|
|
proc getAndClearLogEntries*(vmState: BaseVMState): seq[Log] =
|
2023-03-20 11:51:09 +00:00
|
|
|
vmState.stateDB.getAndClearLogEntries()
|
2021-04-08 14:52:10 +00:00
|
|
|
|
2022-01-18 16:19:32 +00:00
|
|
|
proc status*(vmState: BaseVMState): bool =
|
2021-04-08 14:52:10 +00:00
|
|
|
ExecutionOK in vmState.flags
|
|
|
|
|
|
|
|
proc `status=`*(vmState: BaseVMState, status: bool) =
|
|
|
|
if status: vmState.flags.incl ExecutionOK
|
|
|
|
else: vmState.flags.excl ExecutionOK
|
|
|
|
|
2022-01-18 16:19:32 +00:00
|
|
|
proc generateWitness*(vmState: BaseVMState): bool =
|
2021-04-08 14:52:10 +00:00
|
|
|
GenerateWitness in vmState.flags
|
|
|
|
|
|
|
|
proc `generateWitness=`*(vmState: BaseVMState, status: bool) =
|
2024-01-09 15:15:19 +00:00
|
|
|
if status: vmState.flags.incl GenerateWitness
|
|
|
|
else: vmState.flags.excl GenerateWitness
|
2021-04-08 14:52:10 +00:00
|
|
|
|
2024-01-22 09:11:37 +00:00
|
|
|
proc buildWitness*(
|
|
|
|
vmState: BaseVMState,
|
2024-02-21 16:04:59 +00:00
|
|
|
mkeys: MultiKeysRef): seq[byte] {.raises: [CatchableError].} =
|
2021-10-28 09:42:39 +00:00
|
|
|
let rootHash = vmState.stateDB.rootHash
|
2022-04-08 04:54:11 +00:00
|
|
|
let flags = if vmState.fork >= FkSpurious: {wfEIP170} else: {}
|
2021-04-08 14:52:10 +00:00
|
|
|
|
2024-01-09 15:15:19 +00:00
|
|
|
# A valid block having no transactions should return an empty witness
|
|
|
|
if mkeys.keys.len() == 0:
|
|
|
|
return @[]
|
|
|
|
|
2021-04-08 14:52:10 +00:00
|
|
|
# build witness from tree
|
2023-08-04 11:10:09 +00:00
|
|
|
var wb = initWitnessBuilder(vmState.com.db, rootHash, flags)
|
2023-02-14 20:27:17 +00:00
|
|
|
wb.buildWitness(mkeys)
|
2023-02-16 11:40:07 +00:00
|
|
|
|
2024-01-22 09:11:37 +00:00
|
|
|
proc buildWitness*(
|
|
|
|
vmState: BaseVMState): seq[byte] {.raises: [CatchableError].} =
|
|
|
|
let mkeys = vmState.stateDB.makeMultiKeys()
|
|
|
|
buildWitness(vmState, mkeys)
|
|
|
|
|
2023-02-16 11:40:07 +00:00
|
|
|
func forkDeterminationInfoForVMState*(vmState: BaseVMState): ForkDeterminationInfo =
|
|
|
|
# FIXME-Adam: Is this timestamp right? Note that up above in blockNumber we add 1;
|
|
|
|
# should timestamp be adding 12 or something?
|
|
|
|
# Also, can I get the TD? Do I need to?
|
2023-09-24 15:25:41 +00:00
|
|
|
forkDeterminationInfo(vmState.blockNumber, vmState.blockCtx.timestamp)
|
2023-03-16 20:34:47 +00:00
|
|
|
|
2023-03-17 18:16:24 +00:00
|
|
|
func determineFork*(vmState: BaseVMState): EVMFork =
|
|
|
|
vmState.com.toEVMFork(vmState.forkDeterminationInfoForVMState)
|
2023-08-02 10:17:40 +00:00
|
|
|
|
|
|
|
func tracingEnabled*(vmState: BaseVMState): bool =
|
|
|
|
vmState.tracer.isNil.not
|
|
|
|
|
|
|
|
proc captureTxStart*(vmState: BaseVMState, gasLimit: GasInt) =
|
|
|
|
if vmState.tracingEnabled:
|
|
|
|
vmState.tracer.captureTxStart(gasLimit)
|
|
|
|
|
|
|
|
proc captureTxEnd*(vmState: BaseVMState, restGas: GasInt) =
|
|
|
|
if vmState.tracingEnabled:
|
|
|
|
vmState.tracer.captureTxEnd(restGas)
|
|
|
|
|
2023-08-25 09:07:20 +00:00
|
|
|
proc captureStart*(vmState: BaseVMState, comp: Computation,
|
2023-08-02 10:17:40 +00:00
|
|
|
sender: EthAddress, to: EthAddress,
|
|
|
|
create: bool, input: openArray[byte],
|
2023-08-25 09:07:20 +00:00
|
|
|
gasLimit: GasInt, value: UInt256) =
|
2023-08-02 10:17:40 +00:00
|
|
|
if vmState.tracingEnabled:
|
2023-08-25 09:07:20 +00:00
|
|
|
vmState.tracer.captureStart(comp, sender, to, create, input, gasLimit, value)
|
2023-08-02 10:17:40 +00:00
|
|
|
|
2023-08-25 09:07:20 +00:00
|
|
|
proc captureEnd*(vmState: BaseVMState, comp: Computation, output: openArray[byte],
|
2023-08-02 10:17:40 +00:00
|
|
|
gasUsed: GasInt, error: Option[string]) =
|
|
|
|
if vmState.tracingEnabled:
|
2023-08-25 09:07:20 +00:00
|
|
|
vmState.tracer.captureEnd(comp, output, gasUsed, error)
|
2023-08-02 10:17:40 +00:00
|
|
|
|
2023-08-25 09:07:20 +00:00
|
|
|
proc captureEnter*(vmState: BaseVMState, comp: Computation, op: Op,
|
2023-08-02 10:17:40 +00:00
|
|
|
sender: EthAddress, to: EthAddress,
|
2023-08-25 09:07:20 +00:00
|
|
|
input: openArray[byte], gasLimit: GasInt,
|
2023-08-02 10:17:40 +00:00
|
|
|
value: UInt256) =
|
|
|
|
if vmState.tracingEnabled:
|
2023-08-25 09:07:20 +00:00
|
|
|
vmState.tracer.captureEnter(comp, op, sender, to, input, gasLimit, value)
|
2023-08-02 10:17:40 +00:00
|
|
|
|
2023-08-25 09:07:20 +00:00
|
|
|
proc captureExit*(vmState: BaseVMState, comp: Computation, output: openArray[byte],
|
2023-08-02 10:17:40 +00:00
|
|
|
gasUsed: GasInt, error: Option[string]) =
|
|
|
|
if vmState.tracingEnabled:
|
2023-08-25 09:07:20 +00:00
|
|
|
vmState.tracer.captureExit(comp, output, gasUsed, error)
|
2023-08-02 10:17:40 +00:00
|
|
|
|
2023-08-25 09:07:20 +00:00
|
|
|
proc captureOpStart*(vmState: BaseVMState, comp: Computation, pc: int,
|
2023-08-02 10:17:40 +00:00
|
|
|
op: Op, gas: GasInt,
|
|
|
|
depth: int): int =
|
|
|
|
if vmState.tracingEnabled:
|
2023-08-27 06:13:37 +00:00
|
|
|
let fixed = vmState.gasCosts[op].kind == GckFixed
|
|
|
|
result = vmState.tracer.captureOpStart(comp, fixed, pc, op, gas, depth)
|
2023-08-02 10:17:40 +00:00
|
|
|
|
2023-08-27 06:13:37 +00:00
|
|
|
proc captureGasCost*(vmState: BaseVMState,
|
2023-08-25 09:07:20 +00:00
|
|
|
comp: Computation,
|
2023-08-27 06:13:37 +00:00
|
|
|
op: Op, gasCost: GasInt, gasRemaining: GasInt,
|
2023-08-23 09:29:33 +00:00
|
|
|
depth: int) =
|
2023-08-25 09:07:20 +00:00
|
|
|
if vmState.tracingEnabled:
|
2023-08-27 06:13:37 +00:00
|
|
|
let fixed = vmState.gasCosts[op].kind == GckFixed
|
|
|
|
vmState.tracer.captureGasCost(comp, fixed, op, gasCost, gasRemaining, depth)
|
2023-08-25 09:07:20 +00:00
|
|
|
|
|
|
|
proc captureOpEnd*(vmState: BaseVMState, comp: Computation, pc: int,
|
2023-08-02 10:17:40 +00:00
|
|
|
op: Op, gas: GasInt, refund: GasInt,
|
|
|
|
rData: openArray[byte],
|
|
|
|
depth: int, opIndex: int) =
|
|
|
|
if vmState.tracingEnabled:
|
2023-08-27 06:13:37 +00:00
|
|
|
let fixed = vmState.gasCosts[op].kind == GckFixed
|
|
|
|
vmState.tracer.captureOpEnd(comp, fixed, pc, op, gas, refund, rData, depth, opIndex)
|
2023-08-02 10:17:40 +00:00
|
|
|
|
2023-08-25 09:07:20 +00:00
|
|
|
proc captureFault*(vmState: BaseVMState, comp: Computation, pc: int,
|
2023-08-02 10:17:40 +00:00
|
|
|
op: Op, gas: GasInt, refund: GasInt,
|
|
|
|
rData: openArray[byte],
|
|
|
|
depth: int, error: Option[string]) =
|
|
|
|
if vmState.tracingEnabled:
|
2023-08-27 06:13:37 +00:00
|
|
|
let fixed = vmState.gasCosts[op].kind == GckFixed
|
|
|
|
vmState.tracer.captureFault(comp, fixed, pc, op, gas, refund, rData, depth, error)
|
2023-08-02 10:17:40 +00:00
|
|
|
|
2023-08-25 09:07:20 +00:00
|
|
|
proc capturePrepare*(vmState: BaseVMState, comp: Computation, depth: int) =
|
2023-08-02 10:17:40 +00:00
|
|
|
if vmState.tracingEnabled:
|
2023-08-25 09:07:20 +00:00
|
|
|
vmState.tracer.capturePrepare(comp, depth)
|