filecoin-project / lotus

Reference implementation of the Filecoin protocol, written in Go
https://lotus.filecoin.io/
Other
2.83k stars 1.25k forks source link

Option to back-fill events by re-execution of messages #11744

Open rvagg opened 6 months ago

rvagg commented 6 months ago

Checklist

Lotus component

What is the motivation behind this feature request? Is your feature request related to a problem? Please describe.

lotus-shed indexes backfill-events will walk through specified epochs and extract events from the AMT referenced by receipt.EventsRoot and put them in the index for you. But, it can't do anything if you haven't been recording the events in your blockstore.

If both Fevm.EnableEthRPC (existing config option, defaults to false) or Events.EnableActorEventsAPI (new with 1.26.0, defaults to false) are set to false then EnableStoringEvents isn't set, which prevents both decoding and storing of events on FVM execution.

Because the current backfill operation relies on ChainGetEvents which itself relies on being able to load the event AMT from its root CID on the message receipt from the blockstore. Which won't be there if you haven't configured Fevm.EnableEthRPC=true or Events.EnableActorEventsAPI=true.

Describe the solution you'd like

We have a StateCompute API call which should be able re-execute arbitrary tipsets as long as we have both the previous state and the message. It can be seen used in lotus shed compute-state-range and lotus-shed mismatches.

In theory you should be able to do a two-step events index backfill by running this and then running lotus-shed indexes backfill-events. This needs investigation but it's not clear to me at the time of writing that the chain.consensus.TipSetExecutor#ApplyBlocks code I pointed to above gets involved at all in the StateCompute path, it may use an alternative executor. In which case we may need to either come up with a new StateCompute, or get it to turn on ReturnEvents by default and then persist events like TipSetExecutor does.

The ideal, however, is to provide an option to lotus-shed indexes backfill-events to be able to re-execute tipsets where the events were not collected.

Describe alternatives you've considered

Document a two-step process. of using two separate lotus-shed operations—but I'm not sure this will actually work as it is today.

Additional context

No response

Stebalien commented 6 months ago

See

https://github.com/filecoin-project/lotus/blob/2e75f3b796dd1396baa37d73ea99dc3407b4da8d/node/impl/full/eth_utils.go#L737-L750

For how I'm doing this in the Eth API.

Stebalien commented 6 months ago

In terms of automatically backfilling, we can:

  1. Spin up N backfill goroutines (we can do this in parallel).
  2. Try to backfill based on the events we have.
  3. If we find that we don't have the events associated with a message receipt, re-execute that tipset and try again.
akaladarshi commented 1 month ago

Hey @rjan90,

Is this issue available? Let me know if the solution mentioned in the issue is feasible or if there are any other pointers.

rvagg commented 1 month ago

This issue is coupled with https://github.com/filecoin-project/lotus/issues/11007; we've been discussing that we probably need to ditch the lotus-shed command entirely since it's broken (e.g. see this).

But it might not be a bad idea to bite off this as separate piece of work that can be pulled in to an automatic backfilling (in #11007) later. So making it work in lotus-shed to start with would probably be helpful.

@akaladarshi the code pointer referenced above by stebalien is 👌 for doing this. You could experience this problem if you synced a lotus node from a recent snapshot (mainnet or calibnet), let it run and sync, and then try and run lotus-shed indexes backfill-events with appropriate arguments to point to your lotus node and some appropriate epochs. Even if you turn on events and restart lotus so that it's collecting events from that point forward, you won't be able to backfill past events because the events data structure never gets persisted in the blockstore.