From 0b0d478966ef39c8513ecdb219b04f0d02045f32 Mon Sep 17 00:00:00 2001 From: jangko Date: Wed, 30 Aug 2023 20:38:32 +0700 Subject: [PATCH] Allow EVM dispatcher to use different GasCostKind for each fork Why? Some opcodes such as labeled EIP-2929 changed their behavior from fixed gas cost to dynamic gas cost. This changes together with #1715 and #1717 will make the new EVM tracer to produce trace result identical to geth. --- nimbus/evm/interpreter/gas_costs.nim | 25 ++++++++++++++++++++++++ nimbus/evm/interpreter/op_dispatcher.nim | 3 ++- tools/evmstate/evmstate.nim | 21 +++++++++++++------- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/nimbus/evm/interpreter/gas_costs.nim b/nimbus/evm/interpreter/gas_costs.nim index 981d5a63a..04f2c1c5f 100644 --- a/nimbus/evm/interpreter/gas_costs.nim +++ b/nimbus/evm/interpreter/gas_costs.nim @@ -866,6 +866,31 @@ gasCosts(FkBerlin, berlin, BerlinGasCosts) gasCosts(FkLondon, london, LondonGasCosts) gasCosts(FkShanghai, shanghai, ShanghaiGasCosts) +type + OpGck* = array[Op, GasCostKind] + +func opGck(gc: GasCosts): OpGck {.compileTime.} = + for op, x in gc: + result[op] = x.kind + +# Map fork to GasCostKind +# used in op_dispatcher.nim +const forkToGck*: array[EVMFork, OpGck] = [ + opGck BaseGasCosts , # FkFrontier + opGck HomesteadGasCosts , # FkHomestead + opGck TangerineGasCosts , # kTangerine + opGck SpuriousGasCosts , # FkSpurious + opGck SpuriousGasCosts , # FkByzantium + opGck ConstantinopleGasCosts, # FkConstantinople + opGck SpuriousGasCosts , # FkPetersburg + opGck IstanbulGasCosts , # FkIstanbul + opGck BerlinGasCosts , # FkBerlin + opGck LondonGasCosts , # FkLondon + opGck LondonGasCosts , # FkParis + opGck ShanghaiGasCosts , # FkShanghai + opGck ShanghaiGasCosts , # FkCancun + ] + proc forkToSchedule*(fork: EVMFork): GasCosts = if fork < FkHomestead: BaseGasCosts diff --git a/nimbus/evm/interpreter/op_dispatcher.nim b/nimbus/evm/interpreter/op_dispatcher.nim index 67678a293..b84bba784 100644 --- a/nimbus/evm/interpreter/op_dispatcher.nim +++ b/nimbus/evm/interpreter/op_dispatcher.nim @@ -83,12 +83,13 @@ proc toCaseStmt(forkArg, opArg, k: NimNode): NimNode = var forkCaseSubExpr = nnkCaseStmt.newTree(branchOnFork) for fork in EVMFork: let asFork = quote do: EVMFork(`fork`) + let gcTable = forkToGck[fork] let branchStmt = block: if op == Stop: quote do: handleStopDirective(`k`) - elif BaseGasCosts[op].kind == GckFixed: + elif gcTable[op] == GckFixed: quote do: handleFixedGasCostsDirective(`asFork`,`asOp`,`k`) else: diff --git a/tools/evmstate/evmstate.nim b/tools/evmstate/evmstate.nim index 0a10ed0da..d31abf6a2 100644 --- a/tools/evmstate/evmstate.nim +++ b/tools/evmstate/evmstate.nim @@ -212,13 +212,20 @@ proc runExecution(ctx: var StateContext, conf: StateConf, pre: JsonNode): StateR if conf.jsonEnabled: writeRootHashToStderr(vmState) - let rc = vmState.processTransaction( - ctx.tx, sender, ctx.header, fork) - if rc.isOk: - gasUsed = rc.value - - let miner = ctx.header.coinbase - coinbaseStateClearing(vmState, miner, fork) + try: + let rc = vmState.processTransaction( + ctx.tx, sender, ctx.header, fork) + if rc.isOk: + gasUsed = rc.value + + let miner = ctx.header.coinbase + coinbaseStateClearing(vmState, miner, fork) + except CatchableError as ex: + echo "FATAL: ", ex.msg + quit(QuitFailure) + except AssertionDefect as ex: + echo "FATAL: ", ex.msg + quit(QuitFailure) proc toTracerFlags(conf: Stateconf): set[TracerFlags] = result = {