From 3c486023787830e446c7c30aab4f7328173faeb4 Mon Sep 17 00:00:00 2001 From: Domino Valdano <2644901+reductionista@users.noreply.github.com> Date: Tue, 14 Nov 2023 22:53:16 -0800 Subject: [PATCH] Handle edge case involving blocks not being found in the db If there is a backfill followed by an error, logs get written to the db but no blocks. This will make the logpoller (or backup log poller) rely on the chain next time instead of the db to determine lastFinalizedBlock, which could result in a gap in logs processed. Fixing this by writing the last block in the backfil to the db along with the logs. Its lastFinalizedBlock field will be set to its own block number + 1, so if the db crashes it should start by pulling the logs from that one. --- core/chains/evm/logpoller/log_poller.go | 2 +- core/chains/evm/logpoller/log_poller_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go index fb380f84b2c..1cf1cf42beb 100644 --- a/core/chains/evm/logpoller/log_poller.go +++ b/core/chains/evm/logpoller/log_poller.go @@ -679,7 +679,7 @@ func (lp *logPoller) backfill(ctx context.Context, start, end int64) error { } lp.lggr.Debugw("Backfill found logs", "from", from, "to", to, "logs", len(gethLogs), "blocks", blocks) - err = lp.orm.InsertLogs(convertLogs(gethLogs, blocks, lp.lggr, lp.ec.ConfiguredChainID()), pg.WithParentCtx(ctx)) + err = lp.orm.InsertLogsWithBlock(convertLogs(gethLogs, blocks, lp.lggr, lp.ec.ConfiguredChainID()), blocks[len(blocks)-1], pg.WithParentCtx(ctx)) if err != nil { lp.lggr.Warnw("Unable to insert logs, retrying", "err", err, "from", from, "to", to) return err diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go index 82447bdb5f4..6c4dd381b54 100644 --- a/core/chains/evm/logpoller/log_poller_test.go +++ b/core/chains/evm/logpoller/log_poller_test.go @@ -965,8 +965,8 @@ func TestLogPoller_PollAndSaveLogs(t *testing.T) { lgs, err = th.ORM.SelectLogsByBlockRange(11, 17) require.NoError(t, err) assert.Equal(t, 7, len(lgs)) - th.assertHaveCanonical(t, 15, 16) - th.assertDontHave(t, 11, 14) // Do not expect to save backfilled blocks. + th.assertHaveCanonical(t, 14, 16) // Should have last finalized block plus unfinalized blocks + th.assertDontHave(t, 11, 13) // Should not have older finalized blocks // Verify that a custom block timestamp will get written to db correctly also b, err = th.Client.BlockByNumber(testutils.Context(t), nil) @@ -1057,8 +1057,8 @@ func TestLogPoller_PollAndSaveLogsDeepReorg(t *testing.T) { require.NoError(t, err) assert.Equal(t, hexutil.MustDecode(`0x0000000000000000000000000000000000000000000000000000000000000002`), lgs[0].Data) th.assertHaveCanonical(t, 1, 1) - th.assertDontHave(t, 2, 5) // These blocks are backfilled - th.assertHaveCanonical(t, 6, 10) + th.assertDontHave(t, 2, 3) // These blocks are backfilled + th.assertHaveCanonical(t, 5, 10) }) } }