Skip to content

Commit

Permalink
Implement plugable EVM tracer
Browse files Browse the repository at this point in the history
available tracers:
- Legacy tracer
- new Json tracer
  • Loading branch information
jangko committed Aug 3, 2023
1 parent b6337e9 commit 4d207e4
Show file tree
Hide file tree
Showing 17 changed files with 752 additions and 439 deletions.
45 changes: 30 additions & 15 deletions nimbus/evm/computation.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import
".."/[db/accounts_cache, constants],
"."/[code_stream, memory, message, stack, state],
"."/[transaction_tracer, types],
"."/[types],
./interpreter/[gas_meter, gas_costs, op_codes],
../common/[common, evmforks],
../utils/utils,
Expand Down Expand Up @@ -386,22 +386,37 @@ proc refundSelfDestruct*(c: Computation) =
c.gasMeter.refundGas(cost * num)

proc tracingEnabled*(c: Computation): bool =
TracerFlags.EnableTracing in c.vmState.tracer.flags

proc traceOpCodeStarted*(c: Computation, op: Op): int
{.gcsafe, raises: [CatchableError].} =
c.vmState.tracer.traceOpCodeStarted(c, op)

proc traceOpCodeEnded*(c: Computation, op: Op, lastIndex: int)
{.gcsafe, raises: [CatchableError].} =
c.vmState.tracer.traceOpCodeEnded(c, op, lastIndex)

proc traceError*(c: Computation)
{.gcsafe, raises: [CatchableError].} =
c.vmState.tracer.traceError(c)
c.vmState.tracingEnabled

proc traceOpCodeStarted*(c: Computation, op: Op): int {.gcsafe, raises: [].} =
c.vmState.captureOpStart(
c.code.pc - 1,
op,
c.gasMeter.gasRemaining,
c.msg.depth + 1)

proc traceOpCodeEnded*(c: Computation, op: Op, opIndex: int) {.gcsafe, raises: [].} =
c.vmState.captureOpEnd(
c.code.pc - 1,
op,
c.gasMeter.gasRemaining,
c.gasMeter.gasRefunded,
c.returnData,
c.msg.depth + 1,
opIndex)

proc traceError*(c: Computation) {.gcsafe, raises: [].} =
c.vmState.captureFault(
c.code.pc - 1,
c.instr,
c.gasMeter.gasRemaining,
c.gasMeter.gasRefunded,
c.returnData,
c.msg.depth + 1,
some(c.error.info))

proc prepareTracer*(c: Computation) =
c.vmState.tracer.prepare(c.msg.depth)
c.vmState.capturePrepare(c.msg.depth)

# ------------------------------------------------------------------------------
# End
Expand Down
33 changes: 32 additions & 1 deletion nimbus/evm/interpreter_dispatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,30 @@ proc afterExecCreate(c: Computation)
else:
c.rollback()


const
MsgKindToOp: array[CallKind, Op] = [
CALL,
DELEGATECALL,
CALLCODE,
CREATE,
CREATE2
]

func msgToOp(msg: Message): Op =
if emvcStatic == msg.flags:
return STATICCALL
MsgKindToOp[msg.kind]

proc beforeExec(c: Computation): bool
{.gcsafe, raises: [ValueError].} =

if c.msg.depth > 0:
c.vmState.captureEnter(msgToOp(c.msg),
c.msg.sender, c.msg.contractAddress,
c.msg.data, c.msg.gas,
c.msg.value)

if not c.msg.isCreate:
c.beforeExecCall()
false
Expand All @@ -181,11 +203,20 @@ proc beforeExec(c: Computation): bool

proc afterExec(c: Computation)
{.gcsafe, raises: [CatchableError].} =

if not c.msg.isCreate:
c.afterExecCall()
else:
c.afterExecCreate()

if c.msg.depth > 0:
let gasUsed = c.msg.gas - c.gasMeter.gasRemaining
let error = if c.isError:
some(c.error.info)
else:
none(string)
c.vmState.captureExit(c.output, gasUsed, error)

# ------------------------------------------------------------------------------
# Public functions
# ------------------------------------------------------------------------------
Expand Down Expand Up @@ -306,7 +337,7 @@ proc asyncExecCallOrCreate*(c: Computation): Future[void] {.async.} =
defer: c.dispose()

await ifNecessaryGetCode(c.vmState, c.msg.contractAddress)

if c.beforeExec():
return
c.executeOpcodes()
Expand Down
Loading

0 comments on commit 4d207e4

Please sign in to comment.