Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
obasekiosa opened this issue Sep 11, 2024 · 2 comments · May be fixed by #7479
Open

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

obasekiosa opened this issue Sep 11, 2024 · 2 comments · May be fixed by #7479
Assignees
Labels

Comments

@obasekiosa
Copy link
Contributor

obasekiosa commented Sep 11, 2024

Description

Comparing traces especially debug_traces 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 obasekiosa self-assigned this Sep 11, 2024
@obasekiosa
Copy link
Contributor Author

@MarekM25

@obasekiosa
Copy link
Contributor Author

obasekiosa commented Sep 27, 2024

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
2. Gather those traces (i.e dumps)
3. Call RPC and compare traces (i.e for Nethermind Automatic == Nethemind RPC ?)
4. 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

  • Nethermind's doesn't add the transaction hash to the transaction being traced.

  • Nethermind's doens't nest the trace of a transaction in a result field

  • Nethermind's doens't specify the total gas used by a transaction in long dec format, it does so as a long hex string.

  • Nethermind's doesn't omit the returnValue in the case of null return value, it returns as "0x" string instead.

  • Nethemind's adds the storage and error fields which geth doesn't. -- could ignore this.

Similarities.

  • Relative other of the each trace step is the same, i.e pc, op, gas, gasCost, dept ...
  • units/fromats for other fields are the same, i.e gas, gasCost, dept for each step in a trace.
  • After looking at a bunch of traces, the order, and value of the traces where the same for the same block trace.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
1 participant