66 lines
2.2 KiB
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
|