nimbus-eth1/nimbus/transaction/host_trace.nim

66 lines
2.2 KiB
Nim

# Nimbus - Services available to EVM code that is run for a transaction
#
# Copyright (c) 2021 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import macros, strformat, stew/byteutils, stint, ./host_types
const show_tx_calls = false
# Don't use both types in the overload, as Nim <= 1.2.x gives "ambiguous call".
#func `$`(n: HostKey | HostValue): string = toHex(n)
func `$`(n: HostKey): string = toHex(n)
func `$`(address: HostAddress): string = toHex(address)
func `$`(txc: EvmcTxContext): string = &"gas_price={txc.tx_gas_price.fromEvmc}"
func `$`(n: typeof(EvmcMessage().sender)): string = $n.fromEvmc
func `$`(n: typeof(EvmcMessage().value)): string = $n.fromEvmc
func `$`(host: TransactionHost): string = &"(fork={host.vmState.fork} message=${host.msg})"
macro show*(fn: untyped): auto =
if not show_tx_calls:
return fn
var args: seq[NimNode] = newSeq[NimNode]()
var types: seq[NimNode] = newSeq[NimNode]()
for i in 1 ..< fn.params.len:
let idents = fn.params[i]
for j in 0 ..< idents.len-2:
args.add idents[j]
types.add idents[^2]
let procName = $fn.name
let msgVar = genSym(nskLet, "msg")
var msgExpr = quote do:
"tx." & `procName`
var skip = 0
for i in 1 ..< args.len:
if i == skip:
continue
var arg = args[i]
let argNameString = " " & $arg & "="
if (types[i].repr == "ptr byte" or types[i].repr == "ptr HostTopic") and
(i < args.len-1 and types[i+1].repr == "HostSize"):
skip = i+1
arg = newPar(args[i], args[i+1])
msgExpr = quote do:
`msgExpr` & `argNameString` & $(`arg`)
let call = newCall(fn.name, args)
let wrapFn = newProc(name = fn.name)
wrapFn.params = fn.params.copy
wrapFn.body.add fn
if fn.params[0].kind == nnkEmpty:
wrapFn.body.add quote do:
echo `msgExpr`
`call`
else:
wrapFn.body.add quote do:
let `msgVar` = `msgExpr`
let res = `call`
echo `msgVar` & " -> result=" & $res
res
return wrapFn