NethermindEth / nethermind

A robust execution client for Ethereum node operators.

Home Page:https://nethermind.io/nethermind-client

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Difference between Geth and Nethermind traces

yerke26 opened this issue · comments

Description
Difference between traces found in verifyProofAndRegister transaction:
Geth traces:

          {
               "depth": 4,
               "error": "CallOrCreate",
               "gas": 8521524,
               "gasCost": 8388377,
               "op": "STATICCALL",
               "pc": 14860
           },
           {
               "depth": 4,
               "gas": 133147,
               "gasCost": 0,
               "op": "PUSH2",
               "pc": 14861
           },
           {
               "depth": 4,
               "gas": 8521221,
               "gasCost": 10,
               "op": "JUMPI",
               "pc": 14864
           },

Nethermind traces:

           {
                "pc": 14860,
                "op": "STATICCALL",
                "gas": 8521524,
                "gasCost": 300,
                "depth": 4,
                "error": null,
                "storage": {}
            },
            {
                "pc": 14861,
                "op": "PUSH2",
                "gas": 8521224,
                "gasCost": 3,
                "depth": 4,
                "error": null,
                "storage": {}
            },
            {
                "pc": 14864,
                "op": "JUMPI",
                "gas": 8521221,
                "gasCost": 10,
                "depth": 4,
                "error": null,
                "storage": {}
            },

gasCost for "PUSH2" operation differ, in Geth it is 0, while in Nethermind it is 3. This difference occurs for 63 "PUSH2" operations. One of the cases attached above.
Steps to Reproduce

  1. Get Nethermind traces:
curl --location '38.154.254.162:8545' \
--header 'Content-Type: application/json' \
--data '{
    "jsonrpc": "2.0",
    "id": 0,
    "method": "debug_traceTransaction",
    "params": ["0x94b6144609e9f664976bb841dbcea0eaf06d15a6a03e23736cd9d7688192c023", {"disableStack": true, "disableStorage" : true, "enableMemory" : false}]
}
'
  1. Get Geth traces from public rpc node with the same request
  2. Run the following python script in order to see the differences:
import json

with open('gethTraces.json', 'r') as file:
    json_data = file.read()
geth_traces = json.loads(json_data)

with open('nethermindTraces.json', 'r') as file:
    json_data = file.read()
nth_traces = json.loads(json_data)

geth_gas_cost = []
geth_gas = []
geth_pc = []
nth_gas_cost = []
nth_gas = []
nth_pc = []

for log in geth_traces["result"]["structLogs"]:
    op = log["op"]
    gas_cost = log["gasCost"]
    gas = log["gas"]
    pc = log["pc"]
    if op == 'PUSH2':
        geth_gas_cost.append(gas_cost)
        geth_gas.append(gas)
        geth_pc.append(pc)

for log in nth_traces["result"]["structLogs"]:
    op = log["op"]
    gas_cost = log["gasCost"]
    gas = log["gas"]
    pc = log["pc"]
    if op == 'PUSH2':
        nth_gas_cost.append(gas_cost)
        nth_gas.append(gas)
        nth_pc.append(pc)

for i in range(len(geth_traces)):
    if geth_gas[i] != nth_gas[i]:
        print("Difference: %d", i + 1)
        print("Geth: op = PUSH2, gas = %d, gas_cost = %d, pc = %d", geth_gas[i], geth_gas_cost[i], geth_pc[i])
        print("Nethermind: op = PUSH2, gas = %d, gas_cost = %d, pc = %d", nth_gas[i], nth_gas_cost[i], nth_pc[i])
        print()

Expected behavior
Geth traces are the correct one

Cost of PUSH2 is 3: https://ethereum.org/en/developers/docs/evm/opcodes/ So looks like Geth tracers are incorrect.