From 7490f2312429064b1157696ce2952a1039d51426 Mon Sep 17 00:00:00 2001 From: Jordan Hrycaj Date: Tue, 14 Feb 2023 15:37:21 +0100 Subject: [PATCH] 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 --- nimbus.nimble | 2 +- nimbus/evm/computation.nim | 30 +++++--- nimbus/evm/evmc_api.nim | 75 ++++++++++++------- nimbus/evm/interpreter/gas_costs.nim | 20 +++-- .../op_handlers/oph_arithmetic.nim | 2 + .../interpreter/op_handlers/oph_blockdata.nim | 2 + .../evm/interpreter/op_handlers/oph_call.nim | 2 + .../interpreter/op_handlers/oph_create.nim | 2 + .../evm/interpreter/op_handlers/oph_defs.nim | 2 +- .../evm/interpreter/op_handlers/oph_dup.nim | 2 + .../interpreter/op_handlers/oph_envinfo.nim | 2 + .../evm/interpreter/op_handlers/oph_hash.nim | 2 + .../interpreter/op_handlers/oph_helpers.nim | 2 + .../evm/interpreter/op_handlers/oph_log.nim | 2 + .../interpreter/op_handlers/oph_memory.nim | 2 + .../evm/interpreter/op_handlers/oph_push.nim | 2 + .../evm/interpreter/op_handlers/oph_swap.nim | 2 + .../interpreter/op_handlers/oph_sysops.nim | 2 + nimbus/evm/interpreter_dispatch.nim | 32 +++++--- nimbus/evm/state_transactions.nim | 5 +- nimbus/evm/types.nim | 8 +- 21 files changed, 138 insertions(+), 62 deletions(-) diff --git a/nimbus.nimble b/nimbus.nimble index 6c1ca9dac..72ece0f5c 100644 --- a/nimbus.nimble +++ b/nimbus.nimble @@ -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 diff --git a/nimbus/evm/computation.nim b/nimbus/evm/computation.nim index 47ba4ad67..22d496723 100644 --- a/nimbus/evm/computation.nim +++ b/nimbus/evm/computation.nim @@ -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) # ------------------------------------------------------------------------------ diff --git a/nimbus/evm/evmc_api.nim b/nimbus/evm/evmc_api.nim index 663303099..ae83fca7a 100644 --- a/nimbus/evm/evmc_api.nim +++ b/nimbus/evm/evmc_api.nim @@ -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) diff --git a/nimbus/evm/interpreter/gas_costs.nim b/nimbus/evm/interpreter/gas_costs.nim index 55ff9cc52..60e2248a8 100644 --- a/nimbus/evm/interpreter/gas_costs.nim +++ b/nimbus/evm/interpreter/gas_costs.nim @@ -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 diff --git a/nimbus/evm/interpreter/op_handlers/oph_arithmetic.nim b/nimbus/evm/interpreter/op_handlers/oph_arithmetic.nim index 1810dc1a7..8dd48652e 100644 --- a/nimbus/evm/interpreter/op_handlers/oph_arithmetic.nim +++ b/nimbus/evm/interpreter/op_handlers/oph_arithmetic.nim @@ -25,6 +25,8 @@ import ./oph_defs, eth/common +{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn` + # ------------------------------------------------------------------------------ # Private, op handlers implementation # ------------------------------------------------------------------------------ diff --git a/nimbus/evm/interpreter/op_handlers/oph_blockdata.nim b/nimbus/evm/interpreter/op_handlers/oph_blockdata.nim index 3ff8fb478..879d35f63 100644 --- a/nimbus/evm/interpreter/op_handlers/oph_blockdata.nim +++ b/nimbus/evm/interpreter/op_handlers/oph_blockdata.nim @@ -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 diff --git a/nimbus/evm/interpreter/op_handlers/oph_call.nim b/nimbus/evm/interpreter/op_handlers/oph_call.nim index 9f7f8e40d..e61184198 100644 --- a/nimbus/evm/interpreter/op_handlers/oph_call.nim +++ b/nimbus/evm/interpreter/op_handlers/oph_call.nim @@ -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, diff --git a/nimbus/evm/interpreter/op_handlers/oph_create.nim b/nimbus/evm/interpreter/op_handlers/oph_create.nim index 28c52d58d..5e6908341 100644 --- a/nimbus/evm/interpreter/op_handlers/oph_create.nim +++ b/nimbus/evm/interpreter/op_handlers/oph_create.nim @@ -33,6 +33,8 @@ import stint, strformat +{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn` + when not defined(evmc_enabled): import ../../state, diff --git a/nimbus/evm/interpreter/op_handlers/oph_defs.nim b/nimbus/evm/interpreter/op_handlers/oph_defs.nim index 158ce8f07..7af3cf089 100644 --- a/nimbus/evm/interpreter/op_handlers/oph_defs.nim +++ b/nimbus/evm/interpreter/op_handlers/oph_defs.nim @@ -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 diff --git a/nimbus/evm/interpreter/op_handlers/oph_dup.nim b/nimbus/evm/interpreter/op_handlers/oph_dup.nim index 504fa8263..0446a2681 100644 --- a/nimbus/evm/interpreter/op_handlers/oph_dup.nim +++ b/nimbus/evm/interpreter/op_handlers/oph_dup.nim @@ -19,6 +19,8 @@ import ./oph_defs, ./oph_gen_handlers +{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn` + # ------------------------------------------------------------------------------ # Private helpers # ------------------------------------------------------------------------------ diff --git a/nimbus/evm/interpreter/op_handlers/oph_envinfo.nim b/nimbus/evm/interpreter/op_handlers/oph_envinfo.nim index 263db7f1a..10430fd72 100644 --- a/nimbus/evm/interpreter/op_handlers/oph_envinfo.nim +++ b/nimbus/evm/interpreter/op_handlers/oph_envinfo.nim @@ -29,6 +29,8 @@ import stint, strformat +{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn` + when not defined(evmc_enabled): import ../../state diff --git a/nimbus/evm/interpreter/op_handlers/oph_hash.nim b/nimbus/evm/interpreter/op_handlers/oph_hash.nim index 4ece368cb..16014bfeb 100644 --- a/nimbus/evm/interpreter/op_handlers/oph_hash.nim +++ b/nimbus/evm/interpreter/op_handlers/oph_hash.nim @@ -25,6 +25,8 @@ import ./oph_defs, eth/common +{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn` + # ------------------------------------------------------------------------------ # Private, op handlers implementation # ------------------------------------------------------------------------------ diff --git a/nimbus/evm/interpreter/op_handlers/oph_helpers.nim b/nimbus/evm/interpreter/op_handlers/oph_helpers.nim index d1354fb46..d1943101c 100644 --- a/nimbus/evm/interpreter/op_handlers/oph_helpers.nim +++ b/nimbus/evm/interpreter/op_handlers/oph_helpers.nim @@ -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: diff --git a/nimbus/evm/interpreter/op_handlers/oph_log.nim b/nimbus/evm/interpreter/op_handlers/oph_log.nim index 9f215ad91..6331af88b 100644 --- a/nimbus/evm/interpreter/op_handlers/oph_log.nim +++ b/nimbus/evm/interpreter/op_handlers/oph_log.nim @@ -31,6 +31,8 @@ import stint, strformat +{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn` + # ------------------------------------------------------------------------------ # Private, names & settings # ------------------------------------------------------------------------------ diff --git a/nimbus/evm/interpreter/op_handlers/oph_memory.nim b/nimbus/evm/interpreter/op_handlers/oph_memory.nim index a0d9f3026..88b6e8303 100644 --- a/nimbus/evm/interpreter/op_handlers/oph_memory.nim +++ b/nimbus/evm/interpreter/op_handlers/oph_memory.nim @@ -30,6 +30,8 @@ import stint, strformat +{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn` + when not defined(evmc_enabled): import ../../state, diff --git a/nimbus/evm/interpreter/op_handlers/oph_push.nim b/nimbus/evm/interpreter/op_handlers/oph_push.nim index 1e6edcb71..25a632270 100644 --- a/nimbus/evm/interpreter/op_handlers/oph_push.nim +++ b/nimbus/evm/interpreter/op_handlers/oph_push.nim @@ -20,6 +20,8 @@ import ./oph_defs, ./oph_gen_handlers +{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn` + # ------------------------------------------------------------------------------ # Private helpers # ------------------------------------------------------------------------------ diff --git a/nimbus/evm/interpreter/op_handlers/oph_swap.nim b/nimbus/evm/interpreter/op_handlers/oph_swap.nim index 7a8643523..d5614b9cc 100644 --- a/nimbus/evm/interpreter/op_handlers/oph_swap.nim +++ b/nimbus/evm/interpreter/op_handlers/oph_swap.nim @@ -20,6 +20,8 @@ import sequtils, strformat +{.push raises: [CatchableError].} # basically the annotation type of a `Vm2OpFn` + # ------------------------------------------------------------------------------ # Private, names & settings # ------------------------------------------------------------------------------ diff --git a/nimbus/evm/interpreter/op_handlers/oph_sysops.nim b/nimbus/evm/interpreter/op_handlers/oph_sysops.nim index 5ea4a51a1..0464d9c49 100644 --- a/nimbus/evm/interpreter/op_handlers/oph_sysops.nim +++ b/nimbus/evm/interpreter/op_handlers/oph_sysops.nim @@ -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, diff --git a/nimbus/evm/interpreter_dispatch.nim b/nimbus/evm/interpreter_dispatch.nim index e319eb614..f5f0086d3 100644 --- a/nimbus/evm/interpreter_dispatch.nim +++ b/nimbus/evm/interpreter_dispatch.nim @@ -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: diff --git a/nimbus/evm/state_transactions.nim b/nimbus/evm/state_transactions.nim index 49e8dfb75..aae2679f9 100644 --- a/nimbus/evm/state_transactions.nim +++ b/nimbus/evm/state_transactions.nim @@ -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() diff --git a/nimbus/evm/types.nim b/nimbus/evm/types.nim index 87960da16..35b0dd832 100644 --- a/nimbus/evm/types.nim +++ b/nimbus/evm/types.nim @@ -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