more VM tracing
The existing vmState tracing is plugged into chronicles, at the TRACE level, to facilitate state test debugging. Some useful chronicles defines are added to "tests/nim.cfg" to simplify the compile-and-run command for individual tests.
This commit is contained in:
parent
d633bb9ebf
commit
f91e69f7c7
|
@ -13,6 +13,9 @@ import
|
||||||
../vm_types, ../errors, precompiles,
|
../vm_types, ../errors, precompiles,
|
||||||
./stack, ./computation, terminal # Those are only needed for logging
|
./stack, ./computation, terminal # Those are only needed for logging
|
||||||
|
|
||||||
|
logScope:
|
||||||
|
topics = "vm opcode"
|
||||||
|
|
||||||
func invalidInstruction*(computation: var BaseComputation) {.inline.} =
|
func invalidInstruction*(computation: var BaseComputation) {.inline.} =
|
||||||
raise newException(ValueError, "Invalid instruction, received an opcode not implemented in the current fork.")
|
raise newException(ValueError, "Invalid instruction, received an opcode not implemented in the current fork.")
|
||||||
|
|
||||||
|
@ -186,7 +189,9 @@ proc opTableToCaseStmt(opTable: array[Op, NimNode], computation: NimNode): NimNo
|
||||||
for op, opImpl in opTable.pairs:
|
for op, opImpl in opTable.pairs:
|
||||||
let branchStmt = block:
|
let branchStmt = block:
|
||||||
if op == Stop:
|
if op == Stop:
|
||||||
quote do: break
|
quote do:
|
||||||
|
trace "op: Stop"
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
let asOp = quote do: Op(`op`) # TODO: unfortunately when passing to runtime, ops are transformed into int
|
let asOp = quote do: Op(`op`) # TODO: unfortunately when passing to runtime, ops are transformed into int
|
||||||
if BaseGasCosts[op].kind == GckFixed:
|
if BaseGasCosts[op].kind == GckFixed:
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
import
|
import
|
||||||
json, strutils, nimcrypto, eth_common, stint,
|
json, strutils,
|
||||||
|
chronicles, nimcrypto, eth_common, stint,
|
||||||
../vm_types, memory, stack, ../db/[db_chain, state_db],
|
../vm_types, memory, stack, ../db/[db_chain, state_db],
|
||||||
eth_trie/hexary, ./message, ranges/typedranges
|
eth_trie/hexary, ./message, ranges/typedranges
|
||||||
|
|
||||||
|
logScope:
|
||||||
|
topics = "vm opcode"
|
||||||
|
|
||||||
proc initTracer*(tracer: var TransactionTracer, flags: set[TracerFlags] = {}) =
|
proc initTracer*(tracer: var TransactionTracer, flags: set[TracerFlags] = {}) =
|
||||||
tracer.trace = newJObject()
|
tracer.trace = newJObject()
|
||||||
|
|
||||||
|
@ -47,7 +51,7 @@ proc traceOpCodeEnded*(tracer: var TransactionTracer, c: BaseComputation) =
|
||||||
let j = tracer.trace["structLogs"].elems[^1]
|
let j = tracer.trace["structLogs"].elems[^1]
|
||||||
|
|
||||||
# TODO: figure out how to get storage
|
# TODO: figure out how to get storage
|
||||||
# when contract excecution interrupted by exception
|
# when contract execution interrupted by exception
|
||||||
if TracerFlags.DisableStorage notin tracer.flags:
|
if TracerFlags.DisableStorage notin tracer.flags:
|
||||||
var storage = newJObject()
|
var storage = newJObject()
|
||||||
var stateDB = c.vmState.chaindb.getStateDb(c.vmState.blockHeader.stateRoot, readOnly = true)
|
var stateDB = c.vmState.chaindb.getStateDb(c.vmState.blockHeader.stateRoot, readOnly = true)
|
||||||
|
@ -62,6 +66,8 @@ proc traceOpCodeEnded*(tracer: var TransactionTracer, c: BaseComputation) =
|
||||||
j["returnValue"] = returnValue
|
j["returnValue"] = returnValue
|
||||||
tracer.trace["returnValue"] = returnValue
|
tracer.trace["returnValue"] = returnValue
|
||||||
|
|
||||||
|
trace "Op", json = j.pretty()
|
||||||
|
|
||||||
proc traceError*(tracer: var TransactionTracer, c: BaseComputation) =
|
proc traceError*(tracer: var TransactionTracer, c: BaseComputation) =
|
||||||
let j = tracer.trace["structLogs"].elems[^1]
|
let j = tracer.trace["structLogs"].elems[^1]
|
||||||
|
|
||||||
|
@ -72,3 +78,5 @@ proc traceError*(tracer: var TransactionTracer, c: BaseComputation) =
|
||||||
|
|
||||||
j["error"] = %(c.error.info)
|
j["error"] = %(c.error.info)
|
||||||
tracer.trace["failed"] = %true
|
tracer.trace["failed"] = %true
|
||||||
|
|
||||||
|
trace "Error", json = j.pretty()
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
-d:chronicles_line_numbers
|
||||||
|
-d:"chronicles_sinks=textblocks"
|
||||||
|
|
|
@ -9,7 +9,7 @@ import
|
||||||
unittest, strformat, strutils, tables, json, ospaths, times,
|
unittest, strformat, strutils, tables, json, ospaths, times,
|
||||||
byteutils, ranges/typedranges, nimcrypto/[keccak, hash], options,
|
byteutils, ranges/typedranges, nimcrypto/[keccak, hash], options,
|
||||||
rlp, eth_trie/db, eth_common,
|
rlp, eth_trie/db, eth_common,
|
||||||
eth_keys,
|
eth_keys, chronicles,
|
||||||
./test_helpers,
|
./test_helpers,
|
||||||
../nimbus/[constants, errors],
|
../nimbus/[constants, errors],
|
||||||
../nimbus/[vm_state, vm_types, vm_state_transactions],
|
../nimbus/[vm_state, vm_types, vm_state_transactions],
|
||||||
|
@ -24,7 +24,11 @@ suite "generalstate json tests":
|
||||||
|
|
||||||
|
|
||||||
proc testFixtureIndexes(header: BlockHeader, pre: JsonNode, transaction: Transaction, sender: EthAddress, expectedHash: string, testStatusIMPL: var TestStatus, fork: Fork) =
|
proc testFixtureIndexes(header: BlockHeader, pre: JsonNode, transaction: Transaction, sender: EthAddress, expectedHash: string, testStatusIMPL: var TestStatus, fork: Fork) =
|
||||||
var vmState = newBaseVMState(header, newBaseChainDB(newMemoryDb()))
|
when enabledLogLevel <= TRACE:
|
||||||
|
let tracerFlags = {TracerFlags.EnableTracing}
|
||||||
|
else:
|
||||||
|
let tracerFlags: set[TracerFlags] = {}
|
||||||
|
var vmState = newBaseVMState(header, newBaseChainDB(newMemoryDb()), tracerFlags)
|
||||||
vmState.mutateStateDB:
|
vmState.mutateStateDB:
|
||||||
setupStateDB(pre, db)
|
setupStateDB(pre, db)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue