erigon icon indicating copy to clipboard operation
erigon copied to clipboard

Crash when calling db.getState in tracer

Open samczsun opened this issue 2 years ago • 1 comments

System information

Erigon version: ./erigon --version

OS & Version: Windows/Linux/OSX

Commit hash :

Expected behaviour

The tracer doesn't crash

Actual behaviour

The tracer crashes

Steps to reproduce the behaviour

curl --request POST \
     --url rpc \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
     "id": 1,
     "jsonrpc": "2.0",
     "method": "debug_traceTransaction",
     "params": [
          "0x3711f336c774d03d9f63c0dad7f167a8fbd705431263e9b8006bc4a4de6befc9",
          {
               "tracer": "{\n    value: null,\n    fault: function(obj, log, db) {},\n    step: function(log, db) {\n        if (log.op.toString() == \"SLOAD\") this.value = db.getState(log.contract.getAddress(), toWord( log.stack.peek(0).toString(16)))\n    },\n    result: function(ctx, db) {\n        return this.value;\n    }\n}",
               "timeout": "10s"
          }
     ]
}'

Backtrace

[EROR] [09-27|21:13:06.218] RPC method debug_traceTransaction crashed: interface conversion: interface {} is int64, not []uint8
[service.go:217 panic.go:884 runtime.go:2161 panic.go:884 vm.go:512 panic.go:884 iface.go:262 jsvm.go:97 tracer.go:61 tracer.go:228 jsvm.go:63 value.go:584 value.go:381 runtime.go:1754 vm.go:2658 vm.go:2630 vm.go:402 func.go:172 func.go:180 func.go:140 runtime.go:2166 vm.go:518 runtime.go:2165 jsvm.go:200 tracer.go:553 tracer.go:637 interpreter.go:321 evm.go:67 evm.go:236 instructions.go:723 interpreter.go:326 evm.go:67 evm.go:357 instructions.go:787 interpreter.go:326 evm.go:67 evm.go:236 state_transition.go:423 state_transition.go:232 tracing.go:145 tracing.go:189 value.go:584 value.go:368 service.go:222 handler.go:511 handler.go:444 handler.go:392 handler.go:223 handler.go:316 asm_amd64.s:1594]
[EROR] [09-27|21:13:12.937] RPC method debug_traceTransaction crashed: interface conversion: interface {} is int64, not []uint8

samczsun avatar Oct 13 '22 00:10 samczsun

I'm not sure the above PR actually fixes the issue? It seems to me that, for some reason, Erigon is pushing an int64 value on to the stack so that when this line is reached, the conversion from int64 to []byte causes a panic: https://github.com/ledgerwatch/erigon/blob/dcf6216591c16d1d618e83879c83b4924827d103/eth/tracers/tracer.go#L228

However, I don't think the tracer I posted above is using toWord incorrectly (although perhaps I'm wrong), so this patch would only silently break code that tries to use db.getState(addr, toWord(slot)).

I tried debugging how this might be the case but the only thing strange I noticed was that here, the this value is never popped off the JSVM stack. Could this be causing a desync between the JSVM stack and the goja stack? https://github.com/ledgerwatch/erigon/blob/dcf6216591c16d1d618e83879c83b4924827d103/eth/tracers/jsvm.go#L59-L69

Here's an even simpler tracer. I think this should definitely not crash and return a non-zero value.

{
   "jsonrpc":"2.0",
   "method":"debug_traceTransaction",
   "id":0,
   "params":[
      "0x78ec21f19f1a13a99c1d1d01dbab8e2fc19931c1f74304f9ea505e57a895210c",
      {
         "tracer":"{ value: null, fault: function(obj, log, db) {}, step: function(log, db) { this.value = db.getState(toAddress(\"dac17f958d2ee523a2206206994597c13d831ec7\"), toWord(\"061468b6783f2d92b83dee025a93bf7059411421b55f0f4cb6bb10b2412d870c\")) },  result: function(ctx, db) { return this.value; }}"
      }
   ]
}

samczsun avatar Oct 18 '22 07:10 samczsun

This issue is stale because it has been open for 40 days with no activity. Remove stale label or comment, or this will be closed in 7 days.

github-actions[bot] avatar Nov 28 '22 02:11 github-actions[bot]

This issue was closed because it has been stalled for 7 days with no activity.

github-actions[bot] avatar Dec 06 '22 02:12 github-actions[bot]