mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-23 17:28:27 +00:00
Silence some compiler gossip -- part 6, evm (#1462)
* Silence some compiler gossip -- part 6, evm details: Adding some missing exception annotation * Update evmc cases why: were previously missing * Increase Windows stack needed to run EVMC unit tests why: After annotating functions to trace exceptions some unit tests started to fail on Windows without clear error report. EVMC works recursively and now there seems to be a stack problem reported by the nim compiler. Increasing the NIM stack ass sugessted by NIM (using -d:nimCallDepthLimit=###) had some effect but no clear solution. Note that this patch set unrolls some NIM compiler settings
This commit is contained in:
parent
28129d1df2
commit
7490f23124
@ -55,7 +55,7 @@ proc test(path: string, name: string, params = "", lang = "c") =
|
||||
# Also, the command passed to NimScript `exec` on Windows is not a shell script.
|
||||
# Instead, we can set stack size at link time.
|
||||
const (buildOption, runPrefix) =
|
||||
(" -d:windowsNoSetStack --passL:-Wl,--stack," & $(stackLimitKiB * 1024), "")
|
||||
(" -d:windowsNoSetStack --passL:-Wl,--stack," & $(stackLimitKiB * 2048), "")
|
||||
|
||||
buildBinary name, (path & "/"), params & buildOption
|
||||
exec runPrefix & "build/" & name
|
||||
|
@ -22,6 +22,8 @@ import
|
||||
export
|
||||
common
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
logScope:
|
||||
topics = "vm computation"
|
||||
|
||||
@ -113,7 +115,8 @@ template getGasPrice*(c: Computation): GasInt =
|
||||
else:
|
||||
c.vmState.txGasPrice
|
||||
|
||||
proc getBlockHash*(c: Computation, number: UInt256): Hash256 =
|
||||
proc getBlockHash*(c: Computation, number: UInt256): Hash256
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
when evmc_enabled:
|
||||
let
|
||||
blockNumber = c.host.getTxContext().block_number.u256
|
||||
@ -243,17 +246,18 @@ proc snapshot*(c: Computation) =
|
||||
proc commit*(c: Computation) =
|
||||
c.vmState.stateDB.commit(c.savePoint)
|
||||
|
||||
proc dispose*(c: Computation) {.inline.} =
|
||||
proc dispose*(c: Computation) =
|
||||
c.vmState.stateDB.safeDispose(c.savePoint)
|
||||
c.savePoint = nil
|
||||
|
||||
proc rollback*(c: Computation) =
|
||||
c.vmState.stateDB.rollback(c.savePoint)
|
||||
|
||||
proc setError*(c: Computation, msg: string, burnsGas = false) {.inline.} =
|
||||
proc setError*(c: Computation, msg: string, burnsGas = false) =
|
||||
c.error = Error(info: msg, burnsGas: burnsGas)
|
||||
|
||||
proc writeContract*(c: Computation) =
|
||||
proc writeContract*(c: Computation)
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
template withExtra(tracer: untyped, args: varargs[untyped]) =
|
||||
tracer args, newContract=($c.msg.contractAddress),
|
||||
blockNumber=c.vmState.blockNumber,
|
||||
@ -328,7 +332,8 @@ proc merge*(c, child: Computation) =
|
||||
c.selfDestructs.incl child.selfDestructs
|
||||
c.touchedAccounts.incl child.touchedAccounts
|
||||
|
||||
proc execSelfDestruct*(c: Computation, beneficiary: EthAddress) =
|
||||
proc execSelfDestruct*(c: Computation, beneficiary: EthAddress)
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
c.vmState.mutateStateDB:
|
||||
let
|
||||
localBalance = c.getBalance(c.msg.contractAddress)
|
||||
@ -351,7 +356,7 @@ proc execSelfDestruct*(c: Computation, beneficiary: EthAddress) =
|
||||
# Register the account to be deleted
|
||||
c.selfDestructs.incl(c.msg.contractAddress)
|
||||
|
||||
proc addLogEntry*(c: Computation, log: Log) {.inline.} =
|
||||
proc addLogEntry*(c: Computation, log: Log) =
|
||||
c.logEntries.add(log)
|
||||
|
||||
proc getGasRefund*(c: Computation): GasInt =
|
||||
@ -362,19 +367,22 @@ proc refundSelfDestruct*(c: Computation) =
|
||||
let cost = gasFees[c.fork][RefundSelfDestruct]
|
||||
c.gasMeter.refundGas(cost * c.selfDestructs.len)
|
||||
|
||||
proc tracingEnabled*(c: Computation): bool {.inline.} =
|
||||
proc tracingEnabled*(c: Computation): bool =
|
||||
TracerFlags.EnableTracing in c.vmState.tracer.flags
|
||||
|
||||
proc traceOpCodeStarted*(c: Computation, op: Op): int {.inline.} =
|
||||
proc traceOpCodeStarted*(c: Computation, op: Op): int
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
c.vmState.tracer.traceOpCodeStarted(c, op)
|
||||
|
||||
proc traceOpCodeEnded*(c: Computation, op: Op, lastIndex: int) {.inline.} =
|
||||
proc traceOpCodeEnded*(c: Computation, op: Op, lastIndex: int)
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
c.vmState.tracer.traceOpCodeEnded(c, op, lastIndex)
|
||||
|
||||
proc traceError*(c: Computation) {.inline.} =
|
||||
proc traceError*(c: Computation)
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
c.vmState.tracer.traceError(c)
|
||||
|
||||
proc prepareTracer*(c: Computation) {.inline.} =
|
||||
proc prepareTracer*(c: Computation) =
|
||||
c.vmState.tracer.prepare(c.msg.depth)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
import evmc/evmc, ./evmc_helpers, eth/common, ../constants
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
type
|
||||
# we are not using EVMC original signature here
|
||||
# because we want to trick the compiler
|
||||
@ -46,32 +48,33 @@ type
|
||||
gas_refund* : int64
|
||||
output_data* : ptr byte
|
||||
output_size* : uint
|
||||
release* : proc(result: var nimbus_result) {.cdecl, gcsafe.}
|
||||
release* : proc(result: var nimbus_result)
|
||||
{.cdecl, gcsafe, raises: [CatchableError].}
|
||||
create_address*: EthAddress
|
||||
padding* : array[4, byte]
|
||||
|
||||
nimbus_host_interface* = object
|
||||
account_exists*: proc(context: evmc_host_context, address: EthAddress): bool {.cdecl, gcsafe.}
|
||||
get_storage*: proc(context: evmc_host_context, address: EthAddress, key: ptr evmc_uint256be): evmc_uint256be {.cdecl, gcsafe.}
|
||||
account_exists*: proc(context: evmc_host_context, address: EthAddress): bool {.cdecl, gcsafe, raises: [CatchableError].}
|
||||
get_storage*: proc(context: evmc_host_context, address: EthAddress, key: ptr evmc_uint256be): evmc_uint256be {.cdecl, gcsafe, raises: [CatchableError].}
|
||||
set_storage*: proc(context: evmc_host_context, address: EthAddress,
|
||||
key, value: ptr evmc_uint256be): evmc_storage_status {.cdecl, gcsafe.}
|
||||
get_balance*: proc(context: evmc_host_context, address: EthAddress): evmc_uint256be {.cdecl, gcsafe.}
|
||||
get_code_size*: proc(context: evmc_host_context, address: EthAddress): uint {.cdecl, gcsafe.}
|
||||
get_code_hash*: proc(context: evmc_host_context, address: EthAddress): Hash256 {.cdecl, gcsafe.}
|
||||
key, value: ptr evmc_uint256be): evmc_storage_status {.cdecl, gcsafe, raises: [CatchableError].}
|
||||
get_balance*: proc(context: evmc_host_context, address: EthAddress): evmc_uint256be {.cdecl, gcsafe, raises: [CatchableError].}
|
||||
get_code_size*: proc(context: evmc_host_context, address: EthAddress): uint {.cdecl, gcsafe, raises: [CatchableError].}
|
||||
get_code_hash*: proc(context: evmc_host_context, address: EthAddress): Hash256 {.cdecl, gcsafe, raises: [CatchableError].}
|
||||
copy_code*: proc(context: evmc_host_context, address: EthAddress,
|
||||
code_offset: int, buffer_data: ptr byte,
|
||||
buffer_size: int): int {.cdecl, gcsafe.}
|
||||
selfdestruct*: proc(context: evmc_host_context, address, beneficiary: EthAddress) {.cdecl, gcsafe.}
|
||||
call*: proc(context: evmc_host_context, msg: ptr nimbus_message): nimbus_result {.cdecl, gcsafe.}
|
||||
get_tx_context*: proc(context: evmc_host_context): nimbus_tx_context {.cdecl, gcsafe.}
|
||||
get_block_hash*: proc(context: evmc_host_context, number: int64): Hash256 {.cdecl, gcsafe.}
|
||||
buffer_size: int): int {.cdecl, gcsafe, raises: [CatchableError].}
|
||||
selfdestruct*: proc(context: evmc_host_context, address, beneficiary: EthAddress) {.cdecl, gcsafe, raises: [CatchableError].}
|
||||
call*: proc(context: evmc_host_context, msg: ptr nimbus_message): nimbus_result {.cdecl, gcsafe, raises: [CatchableError].}
|
||||
get_tx_context*: proc(context: evmc_host_context): nimbus_tx_context {.cdecl, gcsafe, raises: [CatchableError].}
|
||||
get_block_hash*: proc(context: evmc_host_context, number: int64): Hash256 {.cdecl, gcsafe, raises: [CatchableError].}
|
||||
emit_log*: proc(context: evmc_host_context, address: EthAddress,
|
||||
data: ptr byte, data_size: uint,
|
||||
topics: ptr evmc_bytes32, topics_count: uint) {.cdecl, gcsafe.}
|
||||
topics: ptr evmc_bytes32, topics_count: uint) {.cdecl, gcsafe, raises: [CatchableError].}
|
||||
access_account*: proc(context: evmc_host_context,
|
||||
address: EthAddress): evmc_access_status {.cdecl, gcsafe.}
|
||||
address: EthAddress): evmc_access_status {.cdecl, gcsafe, raises: [CatchableError].}
|
||||
access_storage*: proc(context: evmc_host_context, address: EthAddress,
|
||||
key: var evmc_bytes32): evmc_access_status {.cdecl, gcsafe.}
|
||||
key: var evmc_bytes32): evmc_access_status {.cdecl, gcsafe, raises: [CatchableError].}
|
||||
|
||||
proc nim_host_get_interface*(): ptr nimbus_host_interface {.importc, cdecl.}
|
||||
proc nim_host_create_context*(vmstate: pointer, msg: ptr evmc_message): evmc_host_context {.importc, cdecl.}
|
||||
@ -90,36 +93,45 @@ proc init*(x: var HostContext, host: ptr nimbus_host_interface, context: evmc_ho
|
||||
proc init*(x: typedesc[HostContext], host: ptr nimbus_host_interface, context: evmc_host_context): HostContext =
|
||||
result.init(host, context)
|
||||
|
||||
proc getTxContext*(ctx: HostContext): nimbus_tx_context {.inline.} =
|
||||
proc getTxContext*(ctx: HostContext): nimbus_tx_context
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
ctx.host.get_tx_context(ctx.context)
|
||||
|
||||
proc getBlockHash*(ctx: HostContext, number: UInt256): Hash256 =
|
||||
proc getBlockHash*(ctx: HostContext, number: UInt256): Hash256
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
ctx.host.get_block_hash(ctx.context, number.truncate(int64))
|
||||
|
||||
proc accountExists*(ctx: HostContext, address: EthAddress): bool {.inline.} =
|
||||
proc accountExists*(ctx: HostContext, address: EthAddress): bool
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
ctx.host.account_exists(ctx.context, address)
|
||||
|
||||
proc getStorage*(ctx: HostContext, address: EthAddress, key: UInt256): UInt256 =
|
||||
proc getStorage*(ctx: HostContext, address: EthAddress, key: UInt256): UInt256
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
var key = toEvmc(key)
|
||||
UInt256.fromEvmc ctx.host.get_storage(ctx.context, address, key.addr)
|
||||
|
||||
proc setStorage*(ctx: HostContext, address: EthAddress,
|
||||
key, value: UInt256): evmc_storage_status {.inline.} =
|
||||
key, value: UInt256): evmc_storage_status
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
var
|
||||
key = toEvmc(key)
|
||||
value = toEvmc(value)
|
||||
ctx.host.set_storage(ctx.context, address, key.addr, value.addr)
|
||||
|
||||
proc getBalance*(ctx: HostContext, address: EthAddress): UInt256 {.inline.} =
|
||||
proc getBalance*(ctx: HostContext, address: EthAddress): UInt256
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
UInt256.fromEvmc ctx.host.get_balance(ctx.context, address)
|
||||
|
||||
proc getCodeSize*(ctx: HostContext, address: EthAddress): uint {.inline.} =
|
||||
proc getCodeSize*(ctx: HostContext, address: EthAddress): uint
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
ctx.host.get_code_size(ctx.context, address)
|
||||
|
||||
proc getCodeHash*(ctx: HostContext, address: EthAddress): Hash256 {.inline.} =
|
||||
proc getCodeHash*(ctx: HostContext, address: EthAddress): Hash256
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
ctx.host.get_code_hash(ctx.context, address)
|
||||
|
||||
proc copyCode*(ctx: HostContext, address: EthAddress, codeOffset: int = 0): seq[byte] =
|
||||
proc copyCode*(ctx: HostContext, address: EthAddress, codeOffset: int = 0): seq[byte]
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
let size = ctx.getCodeSize(address).int
|
||||
if size - codeOffset > 0:
|
||||
result = newSeq[byte](size - codeOffset)
|
||||
@ -127,22 +139,27 @@ proc copyCode*(ctx: HostContext, address: EthAddress, codeOffset: int = 0): seq[
|
||||
codeOffset, result[0].addr, result.len)
|
||||
doAssert(read == result.len)
|
||||
|
||||
proc selfdestruct*(ctx: HostContext, address, beneficiary: EthAddress) {.inline.} =
|
||||
proc selfdestruct*(ctx: HostContext, address, beneficiary: EthAddress)
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
ctx.host.selfdestruct(ctx.context, address, beneficiary)
|
||||
|
||||
proc emitLog*(ctx: HostContext, address: EthAddress, data: openArray[byte],
|
||||
topics: ptr evmc_bytes32, topicsCount: int) {.inline.} =
|
||||
topics: ptr evmc_bytes32, topicsCount: int)
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
ctx.host.emit_log(ctx.context, address, if data.len > 0: data[0].unsafeAddr else: nil,
|
||||
data.len.uint, topics, topicsCount.uint)
|
||||
|
||||
proc call*(ctx: HostContext, msg: nimbus_message): nimbus_result {.inline.} =
|
||||
proc call*(ctx: HostContext, msg: nimbus_message): nimbus_result
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
ctx.host.call(ctx.context, msg.unsafeAddr)
|
||||
|
||||
proc accessAccount*(ctx: HostContext,
|
||||
address: EthAddress): evmc_access_status {.inline.} =
|
||||
address: EthAddress): evmc_access_status
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
ctx.host.access_account(ctx.context, address)
|
||||
|
||||
proc accessStorage*(ctx: HostContext, address: EthAddress,
|
||||
key: UInt256): evmc_access_status {.inline.} =
|
||||
key: UInt256): evmc_access_status
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
var key = toEvmc(key)
|
||||
ctx.host.access_storage(ctx.context, address, key)
|
||||
|
@ -104,11 +104,14 @@ type
|
||||
of GckFixed:
|
||||
cost*: GasInt
|
||||
of GckDynamic:
|
||||
d_handler*: proc(value: UInt256): GasInt {.nimcall, gcsafe.}
|
||||
d_handler*: proc(value: UInt256): GasInt
|
||||
{.nimcall, gcsafe, raises: [CatchableError].}
|
||||
of GckMemExpansion:
|
||||
m_handler*: proc(currentMemSize, memOffset, memLength: GasNatural): GasInt {.nimcall, gcsafe.}
|
||||
m_handler*: proc(currentMemSize, memOffset, memLength: GasNatural): GasInt
|
||||
{.nimcall, gcsafe, raises: [CatchableError].}
|
||||
of GckComplex:
|
||||
c_handler*: proc(value: UInt256, gasParams: GasParams): GasResult {.nimcall, gcsafe.}
|
||||
c_handler*: proc(value: UInt256, gasParams: GasParams): GasResult
|
||||
{.nimcall, gcsafe, raises: [CatchableError].}
|
||||
# We use gasCost/gasRefund for:
|
||||
# - Properly log and order cost and refund (for Sstore especially)
|
||||
# - Allow to use unsigned integer in the future
|
||||
@ -531,13 +534,16 @@ template gasCosts(fork: EVMFork, prefix, ResultGasCostsName: untyped) =
|
||||
func fixed(gasFeeKind: static[GasFeeKind]): GasCost =
|
||||
GasCost(kind: GckFixed, cost: static(FeeSchedule[gasFeeKind]))
|
||||
|
||||
func dynamic(handler: proc(value: UInt256): GasInt {.nimcall, gcsafe.}): GasCost =
|
||||
GasCost(kind: GckDynamic, d_handler: handler)
|
||||
func dynamic(handler: proc(value: UInt256): GasInt
|
||||
{.nimcall, gcsafe, raises: [CatchableError].}): GasCost =
|
||||
GasCost(kind: GckDynamic, d_handler: handler)
|
||||
|
||||
func memExpansion(handler: proc(currentMemSize, memOffset, memLength: GasNatural): GasInt {.nimcall, gcsafe.}): GasCost =
|
||||
func memExpansion(handler: proc(currentMemSize, memOffset, memLength: GasNatural): GasInt
|
||||
{.nimcall, gcsafe, raises: [CatchableError].}): GasCost =
|
||||
GasCost(kind: GckMemExpansion, m_handler: handler)
|
||||
|
||||
func complex(handler: proc(value: UInt256, gasParams: GasParams): GasResult {.nimcall, gcsafe.}): GasCost =
|
||||
func complex(handler: proc(value: UInt256, gasParams: GasParams): GasResult
|
||||
{.nimcall, gcsafe, raises: [CatchableError].}): GasCost =
|
||||
GasCost(kind: GckComplex, c_handler: handler)
|
||||
|
||||
# Returned value
|
||||
|
@ -25,6 +25,8 @@ import
|
||||
./oph_defs,
|
||||
eth/common
|
||||
|
||||
{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn`
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Private, op handlers implementation
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -19,6 +19,8 @@ import
|
||||
../op_codes,
|
||||
./oph_defs
|
||||
|
||||
{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn`
|
||||
|
||||
when not defined(evmc_enabled):
|
||||
import ../../state
|
||||
|
||||
|
@ -30,6 +30,8 @@ import
|
||||
eth/common/eth_types,
|
||||
stint
|
||||
|
||||
{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn`
|
||||
|
||||
when not defined(evmc_enabled):
|
||||
import
|
||||
../../state,
|
||||
|
@ -33,6 +33,8 @@ import
|
||||
stint,
|
||||
strformat
|
||||
|
||||
{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn`
|
||||
|
||||
when not defined(evmc_enabled):
|
||||
import
|
||||
../../state,
|
||||
|
@ -24,7 +24,7 @@ type
|
||||
|
||||
Vm2OpFn* = ## general op handler, return codes are passed
|
||||
## back via argument descriptor ``k``
|
||||
proc(k: var Vm2Ctx) {.gcsafe.}
|
||||
proc(k: var Vm2Ctx) {.gcsafe, raises: [CatchableError].}
|
||||
|
||||
|
||||
Vm2OpHanders* = tuple ## three step op code execution, typically
|
||||
|
@ -19,6 +19,8 @@ import
|
||||
./oph_defs,
|
||||
./oph_gen_handlers
|
||||
|
||||
{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn`
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Private helpers
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -29,6 +29,8 @@ import
|
||||
stint,
|
||||
strformat
|
||||
|
||||
{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn`
|
||||
|
||||
when not defined(evmc_enabled):
|
||||
import ../../state
|
||||
|
||||
|
@ -25,6 +25,8 @@ import
|
||||
./oph_defs,
|
||||
eth/common
|
||||
|
||||
{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn`
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Private, op handlers implementation
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -22,6 +22,8 @@ import
|
||||
macros,
|
||||
stint
|
||||
|
||||
{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn`
|
||||
|
||||
when defined(evmc_enabled):
|
||||
import ../../evmc_api, ../../evmc_helpers, evmc/evmc
|
||||
else:
|
||||
|
@ -31,6 +31,8 @@ import
|
||||
stint,
|
||||
strformat
|
||||
|
||||
{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn`
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Private, names & settings
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -30,6 +30,8 @@ import
|
||||
stint,
|
||||
strformat
|
||||
|
||||
{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn`
|
||||
|
||||
when not defined(evmc_enabled):
|
||||
import
|
||||
../../state,
|
||||
|
@ -20,6 +20,8 @@ import
|
||||
./oph_defs,
|
||||
./oph_gen_handlers
|
||||
|
||||
{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn`
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Private helpers
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -20,6 +20,8 @@ import
|
||||
sequtils,
|
||||
strformat
|
||||
|
||||
{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn`
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Private, names & settings
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -27,6 +27,8 @@ import
|
||||
eth/common,
|
||||
stint
|
||||
|
||||
{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn`
|
||||
|
||||
when not defined(evmc_enabled):
|
||||
import
|
||||
../../state,
|
||||
|
@ -21,6 +21,8 @@ import
|
||||
"."/[message, precompiles, state, types],
|
||||
./interpreter/[op_dispatcher, gas_costs]
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
logScope:
|
||||
topics = "vm opcode"
|
||||
|
||||
@ -34,7 +36,8 @@ const
|
||||
# Private functions
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc selectVM(c: Computation, fork: EVMFork, shouldPrepareTracer: bool) {.gcsafe.} =
|
||||
proc selectVM(c: Computation, fork: EVMFork, shouldPrepareTracer: bool)
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
## Op code execution handler main loop.
|
||||
var desc: Vm2Ctx
|
||||
desc.cpt = c
|
||||
@ -127,7 +130,8 @@ proc afterExecCall(c: Computation) =
|
||||
c.rollback()
|
||||
|
||||
|
||||
proc beforeExecCreate(c: Computation): bool =
|
||||
proc beforeExecCreate(c: Computation): bool
|
||||
{.gcsafe, raises: [ValueError].} =
|
||||
c.vmState.mutateStateDB:
|
||||
let nonce = db.getNonce(c.msg.sender)
|
||||
if nonce+1 < nonce:
|
||||
@ -159,7 +163,8 @@ proc beforeExecCreate(c: Computation): bool =
|
||||
|
||||
return false
|
||||
|
||||
proc afterExecCreate(c: Computation) =
|
||||
proc afterExecCreate(c: Computation)
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
if c.isSuccess:
|
||||
# This can change `c.isSuccess`.
|
||||
c.writeContract()
|
||||
@ -175,14 +180,16 @@ proc afterExecCreate(c: Computation) =
|
||||
c.rollback()
|
||||
|
||||
|
||||
proc beforeExec(c: Computation): bool =
|
||||
proc beforeExec(c: Computation): bool
|
||||
{.gcsafe, raises: [ValueError].} =
|
||||
if not c.msg.isCreate:
|
||||
c.beforeExecCall()
|
||||
false
|
||||
else:
|
||||
c.beforeExecCreate()
|
||||
|
||||
proc afterExec(c: Computation) =
|
||||
proc afterExec(c: Computation)
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
if not c.msg.isCreate:
|
||||
c.afterExecCall()
|
||||
else:
|
||||
@ -192,7 +199,8 @@ proc afterExec(c: Computation) =
|
||||
# Public functions
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc executeOpcodes*(c: Computation, shouldPrepareTracer: bool = true) =
|
||||
proc executeOpcodes*(c: Computation, shouldPrepareTracer: bool = true)
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
let fork = c.fork
|
||||
|
||||
block:
|
||||
@ -204,8 +212,10 @@ proc executeOpcodes*(c: Computation, shouldPrepareTracer: bool = true) =
|
||||
(c.continuation)()
|
||||
c.selectVM(fork, shouldPrepareTracer)
|
||||
except CatchableError as e:
|
||||
c.setError(
|
||||
&"Opcode Dispatch Error msg={e.msg}, depth={c.msg.depth}", true)
|
||||
let
|
||||
msg = e.msg
|
||||
depth = $c.msg.depth
|
||||
c.setError("Opcode Dispatch Error msg=" & msg & ", depth=" & depth, true)
|
||||
|
||||
if c.isError() and c.continuation.isNil:
|
||||
if c.tracingEnabled: c.traceError()
|
||||
@ -213,7 +223,8 @@ proc executeOpcodes*(c: Computation, shouldPrepareTracer: bool = true) =
|
||||
|
||||
when vm_use_recursion:
|
||||
# Recursion with tiny stack frame per level.
|
||||
proc execCallOrCreate*(c: Computation) =
|
||||
proc execCallOrCreate*(c: Computation)
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
defer: c.dispose()
|
||||
if c.beforeExec():
|
||||
return
|
||||
@ -236,7 +247,8 @@ when vm_use_recursion:
|
||||
c.afterExec()
|
||||
|
||||
else:
|
||||
proc execCallOrCreate*(cParam: Computation) =
|
||||
proc execCallOrCreate*(cParam: Computation)
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
var (c, before, shouldPrepareTracer) = (cParam, true, true)
|
||||
defer:
|
||||
while not c.isNil:
|
||||
|
@ -22,6 +22,8 @@ import
|
||||
./state,
|
||||
./types
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
proc setupTxContext*(vmState: BaseVMState, origin: EthAddress, gasPrice: GasInt, forkOverride=none(EVMFork)) =
|
||||
## this proc will be called each time a new transaction
|
||||
## is going to be executed
|
||||
@ -56,7 +58,8 @@ proc postExecComputation(c: Computation) =
|
||||
|
||||
c.vmState.status = c.isSuccess
|
||||
|
||||
proc execComputation*(c: Computation) =
|
||||
proc execComputation*(c: Computation)
|
||||
{.gcsafe, raises: [CatchableError].} =
|
||||
c.preExecComputation()
|
||||
c.execCallOrCreate()
|
||||
c.postExecComputation()
|
||||
|
@ -17,6 +17,8 @@ import
|
||||
../db/accounts_cache,
|
||||
../common/[common, evmforks]
|
||||
|
||||
{.push raises: [].}
|
||||
|
||||
when defined(evmc_enabled):
|
||||
import
|
||||
./evmc_api
|
||||
@ -99,7 +101,7 @@ type
|
||||
else:
|
||||
parent*, child*: Computation
|
||||
pendingAsyncOperation*: Future[void]
|
||||
continuation*: proc() {.gcsafe.}
|
||||
continuation*: proc() {.gcsafe, raises: [CatchableError].}
|
||||
|
||||
Error* = ref object
|
||||
info*: string
|
||||
@ -132,7 +134,9 @@ type
|
||||
flags*: MsgFlags
|
||||
|
||||
LazyDataSource* = ref object of RootObj
|
||||
ifNecessaryGetStorage*: proc(c: Computation, slot: UInt256): Future[void] {.gcsafe.}
|
||||
ifNecessaryGetStorage*:
|
||||
proc(c: Computation, slot: UInt256): Future[void]
|
||||
{.gcsafe, raises: [CatchableError].}
|
||||
|
||||
AsyncOperationFactory* = ref object of RootObj
|
||||
lazyDataSource*: LazyDataSource
|
||||
|
Loading…
x
Reference in New Issue
Block a user