mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-16 07:14:15 +00:00
c0d52ba179
Both types are not safe and require validation/conversion from rpc implementer. This PR change it to safer types and delegate the conversion and validation to the rpc library.
131 lines
5.3 KiB
Nim
131 lines
5.3 KiB
Nim
# Nimbus
|
|
# Copyright (c) 2018-2023 Status Research & Development GmbH
|
|
# Licensed under either of
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
|
# at your option.
|
|
# This file may not be copied, modified, or distributed except according to
|
|
# those terms.
|
|
|
|
import
|
|
std/json,
|
|
json_rpc/rpcserver,
|
|
./rpc_utils,
|
|
./rpc_types,
|
|
../tracer, ../vm_types,
|
|
../common/common,
|
|
../beacon/web3_eth_conv,
|
|
web3/conversions
|
|
|
|
{.push raises: [].}
|
|
|
|
type
|
|
TraceOptions = object
|
|
disableStorage: Option[bool]
|
|
disableMemory: Option[bool]
|
|
disableStack: Option[bool]
|
|
disableState: Option[bool]
|
|
disableStateDiff: Option[bool]
|
|
|
|
proc isTrue(x: Option[bool]): bool =
|
|
result = x.isSome and x.get() == true
|
|
|
|
proc traceOptionsToFlags(options: Option[TraceOptions]): set[TracerFlags] =
|
|
if options.isSome:
|
|
let opts = options.get
|
|
if opts.disableStorage.isTrue: result.incl TracerFlags.DisableStorage
|
|
if opts.disableMemory.isTrue : result.incl TracerFlags.DisableMemory
|
|
if opts.disableStack.isTrue : result.incl TracerFlags.DisableStack
|
|
if opts.disableState.isTrue : result.incl TracerFlags.DisableState
|
|
if opts.disableStateDiff.isTrue: result.incl TracerFlags.DisableStateDiff
|
|
|
|
proc setupDebugRpc*(com: CommonRef, rpcsrv: RpcServer) =
|
|
let chainDB = com.db
|
|
|
|
rpcsrv.rpc("debug_traceTransaction") do(data: Web3Hash, options: Option[TraceOptions]) -> JsonNode:
|
|
## The traceTransaction debugging method will attempt to run the transaction in the exact
|
|
## same manner as it was executed on the network. It will replay any transaction that may
|
|
## have been executed prior to this one before it will finally attempt to execute the
|
|
## transaction that corresponds to the given hash.
|
|
##
|
|
## In addition to the hash of the transaction you may give it a secondary optional argument,
|
|
## which specifies the options for this specific call. The possible options are:
|
|
##
|
|
## * disableStorage: BOOL. Setting this to true will disable storage capture (default = false).
|
|
## * disableMemory: BOOL. Setting this to true will disable memory capture (default = false).
|
|
## * disableStack: BOOL. Setting this to true will disable stack capture (default = false).
|
|
## * disableState: BOOL. Setting this to true will disable state trie capture (default = false).
|
|
let
|
|
txHash = ethHash(data)
|
|
txDetails = chainDB.getTransactionKey(txHash)
|
|
blockHeader = chainDB.getBlockHeader(txDetails.blockNumber)
|
|
blockHash = chainDB.getBlockHash(txDetails.blockNumber)
|
|
blockBody = chainDB.getBlockBody(blockHash)
|
|
flags = traceOptionsToFlags(options)
|
|
|
|
result = traceTransaction(com, blockHeader, blockBody, txDetails.index, flags)
|
|
|
|
rpcsrv.rpc("debug_dumpBlockStateByNumber") do(quantityTag: BlockTag) -> JsonNode:
|
|
## Retrieves the state that corresponds to the block number and returns
|
|
## a list of accounts (including storage and code).
|
|
##
|
|
## quantityTag: integer of a block number, or the string "earliest",
|
|
## "latest" or "pending", as in the default block parameter.
|
|
let
|
|
header = chainDB.headerFromTag(quantityTag)
|
|
blockHash = chainDB.getBlockHash(header.blockNumber)
|
|
body = chainDB.getBlockBody(blockHash)
|
|
|
|
result = dumpBlockState(com, header, body)
|
|
|
|
rpcsrv.rpc("debug_dumpBlockStateByHash") do(data: Web3Hash) -> JsonNode:
|
|
## Retrieves the state that corresponds to the block number and returns
|
|
## a list of accounts (including storage and code).
|
|
##
|
|
## data: Hash of a block.
|
|
let
|
|
h = data.ethHash
|
|
header = chainDB.getBlockHeader(h)
|
|
blockHash = chainDB.getBlockHash(header.blockNumber)
|
|
body = chainDB.getBlockBody(blockHash)
|
|
|
|
result = dumpBlockState(com, header, body)
|
|
|
|
rpcsrv.rpc("debug_traceBlockByNumber") do(quantityTag: BlockTag, options: Option[TraceOptions]) -> JsonNode:
|
|
## The traceBlock method will return a full stack trace of all invoked opcodes of all transaction
|
|
## that were included included in this block.
|
|
##
|
|
## quantityTag: integer of a block number, or the string "earliest",
|
|
## "latest" or "pending", as in the default block parameter.
|
|
## options: see debug_traceTransaction
|
|
let
|
|
header = chainDB.headerFromTag(quantityTag)
|
|
blockHash = chainDB.getBlockHash(header.blockNumber)
|
|
body = chainDB.getBlockBody(blockHash)
|
|
flags = traceOptionsToFlags(options)
|
|
|
|
result = traceBlock(com, header, body, flags)
|
|
|
|
rpcsrv.rpc("debug_traceBlockByHash") do(data: Web3Hash, options: Option[TraceOptions]) -> JsonNode:
|
|
## The traceBlock method will return a full stack trace of all invoked opcodes of all transaction
|
|
## that were included included in this block.
|
|
##
|
|
## data: Hash of a block.
|
|
## options: see debug_traceTransaction
|
|
let
|
|
h = data.ethHash
|
|
header = chainDB.getBlockHeader(h)
|
|
blockHash = chainDB.getBlockHash(header.blockNumber)
|
|
body = chainDB.getBlockBody(blockHash)
|
|
flags = traceOptionsToFlags(options)
|
|
|
|
result = traceBlock(com, header, body, flags)
|
|
|
|
rpcsrv.rpc("debug_setHead") do(quantityTag: BlockTag) -> bool:
|
|
## Sets the current head of the local chain by block number.
|
|
## Note, this is a destructive action and may severely damage your chain.
|
|
## Use with extreme caution.
|
|
let
|
|
header = chainDB.headerFromTag(quantityTag)
|
|
result = chainDB.setHead(header)
|