Go-ethereum: Missing trie node errors when calling contract method with past block number

Created on 18 Feb 2018  路  5Comments  路  Source: ethereum/go-ethereum

Since updating to 1.8.0, calling contract methods at past block numbers results in errors such as missing trie node f424a914a3fabb903dbc7c1d78db44508db8e31315d4009e377c4193757b9c9d (path ). Calling the same method at the latest block works as expected.

I have tested with both --gcmode=archive and --gcmode=full and got the same result. In both cases a new (fast) sync was done.

Calls were made via web3 1.0.0.beta.27 over websockets.

System information

Geth version: 1.8.0-stable
OS & Version: Ubuntu 16.04
Commit hash: 5f54075760748ae7f249bf735565924ea885c477

Most helpful comment

The --gcmode doesn't matter here. The issue is that when you fast-sync, you don't have all historic states. After a fast-sync is complete, you will start to do an "archiving" sync, block by block sync, _from that point on_ .

So, your old setup had an earlier "pivot point" than your new setup, and thus had the full state for everything after that pivot point. Your new setup does not have that. It's an effect of doing a new fast-sync, not because you upgrade to 1.8.0.

All 5 comments

The --gcmode doesn't matter here. The issue is that when you fast-sync, you don't have all historic states. After a fast-sync is complete, you will start to do an "archiving" sync, block by block sync, _from that point on_ .

So, your old setup had an earlier "pivot point" than your new setup, and thus had the full state for everything after that pivot point. Your new setup does not have that. It's an effect of doing a new fast-sync, not because you upgrade to 1.8.0.

Same as https://github.com/ethereum/go-ethereum/issues/16471
@holiman Does it mean that to request contract data on past blocks on a fresh node we are forced to run a full sync (--gcmode=archive --syncmode=full) instead of a fast sync (--gcmode=archive --syncmode=fast) ?

@Deams51 I think the answer of your question is yes.

Not quite, but almost. Say you want to do a trace on block B. Now there are a couple of cases:

  1. You did a fast-sync, pivot block P where P <= B.
  2. You did a fast-sync, pivot block P where P > B.
  3. You did a full-sync, with pruning
  4. You did a full-sync, without pruning (--gcmode=archive)

Here's what happens:

  1. Geth will regenerate the desired state by replaying blocks from the closest point in time before B where it has full state. This defaults to 128 blocks max, but you can specify more in the actual call ... "reexec":1000 .. } to the tracer.
  2. Sorry, can't be done without replaying from genesis.
  3. Same as 1)
  4. Does not need to replay anything, can immediately load up the state and serve the request.

There is one other option available to you, which may or may not suit your needs. That is to use Evmlab.

docker pull holiman/evmlab && docker run -it holiman/evmlab

There you can use the reproducer. The reproducer will incrementally fetch data from infura until it has all the information required to create the trace locally on an evm which is bundled with the image. It will create a custom genesis containing the state that the transaction touches (balances, code, nonce etc).

Added this to the docs: https://github.com/ethereum/go-ethereum/wiki/Tracing:-Introduction#pruning

Was this page helpful?
0 / 5 - 0 ratings

Related issues

carver picture carver  路  3Comments

362228416 picture 362228416  路  3Comments

cheershendtco picture cheershendtco  路  3Comments

VenusHu picture VenusHu  路  3Comments

aakilfernandes picture aakilfernandes  路  3Comments