NethermindEth / nethermind

A robust execution client for Ethereum node operators.
https://nethermind.io/nethermind-client
GNU General Public License v3.0
1.27k stars 437 forks source link

Make nethermind trace format/structure uniform across modules and with geth #7408

Open obasekiosa opened 2 months ago

obasekiosa commented 2 months ago

Description

Comparing traces especially debugtraces between nethermind and geth should be as direct as possible, seeing as debug endpoints are defined by geth it'd be a good idea to have nethermind debug_trace_block be in the same format as geth's.

Steps to Reproduce/Extra Info

There are at least two ways to get execution traces/bad blocks from nethermind client.

  1. set Init.AutoDump config to either Parity|Geth|All
  2. call the [debug_]trace_block api for the respective block. (Requires the debug and trace module enabled i.e JsonRpc.EnabledModules config).

Note: Traces can be particularly large and require some ram to display/format in a more readable format by most text editors/formatting services.

Actual behavior using a webservice like tracoor and say some random hash of 0x60354ac24a83666dca2fde27f728c6b80a0c3b67ebb54e66438a5558d60754a3.

You'd notice that the format/fields, structure and units (hex/dec) for representing similar fields across clients differ on netherimind vs geth.

Expected behavior

The goal on resolving this issue is to ensure the automatic traces produced (Init.AutoDump ) match the nethermind client debug_trace_block rpc call [which also match that of geth's] which matches the trace_block call of the trace module. With debug_trace_block [geth's] being the source of truth.

Any extra fields introduced by nethermind should be left in place as is or maybe moved around depending, in such cases discuss below. Relative order should also be made to match.

obasekiosa commented 2 months ago

@MarekM25

obasekiosa commented 1 month ago

The idea behind the investigation was to check if

Automatic traces == RPC Nethermind traces == Geth client (no trace module geth, just debug module).

The RPC in question is the the debug_traceBlock RPC _Note that changing the format for just this api might not make so much sense without changing that of the other debug_trace* api's in termis of units and value formats. i.e hex to dec_

For perspective, Automatic traces are the traces dumped when an error occurs. Which happens here

The format of the traces we are concerned about is the geth format. This is used in the debug_* api, and when the dump options is set to also display Geth.

steps to reproduce 1.Run node with a bug that you introduced in EVM with Init.AutoDump and/or debug module enable

  1. Gather those traces (i.e dumps)
  2. Call RPC and compare traces (i.e for Nethermind Automatic == Nethemind RPC ?)
  3. for Nethemind RPC == Geth RPC comparison get traces from geth client (see issue description on how to do that).

For quickly Comparing traces on *unix simply use the diff tool (can be memory intensive so maybe split file into pieces first to format and get a sense of what it looks like, can do this using programming language of choice. First read in chucks and find valid json terminating xters i.e "}" and "]" split on those). Using text editors/ide seemed to crash a lot or freeze.

The geth format as shown from a GETH client is

[
    {
        "txHash":  <string of hex value of hash e,g "0xfa696615b3e0bdaf676ba3cbe90b4dc4caf1a086540ba003e61d80b3547cb3a3">,
        "result": {
            "gas": <long in dec format>,
            "failed": <boolean>,
            "returnValue": <hex string>,
            "structLogs": [
                {
                    "pc": <long in dec fromat>,
                    "op": <all caps string for op code eg "PUSH20">,
                    "gas": <long in dec format>,
                    "gasCost": <long in dec fromat>,
                    "depth": <long in dec format>
                },
                ...
            ]
        }
    },
    ...
]

While netherminds was

[
    {
        "gas": <string of long in hex format e.g "0x1cd1d">,
        "failed": <boolean>,
        "returnValue": <string int in hex format e.g "0x">,
        "structLogs": [
            {
                "pc": <long in dec format>,
                "op":  <all caps string for op code eg "PUSH20">,
                "gas": <long in dec format>,
                "gasCost": <long in dec format>,
                "depth": <long in dec format>,
                "error": <string>,
                "storage": <map>
            },
            ...
        ]
    },
    ...
]

Things to note.

Differences

Similarities.

Also more, Auto Dump - Automatic traces

setting --Init.AutoDump to All or Geth gets these traces.

On inspecting the code, you'll notice both the dubug module and the code block for auto dumping using geth dump options use the exact same tracer and converter. this Implies (much faster that) Automatic traces == RPC Nethermind traces