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
- 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}]
}
'
- Get Geth traces from public rpc node with the same request
- 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.