From c9f4fd1f9816d59bd5246b1eb044628cf1375d1d Mon Sep 17 00:00:00 2001 From: nischit Date: Tue, 28 Apr 2026 21:41:54 +0545 Subject: [PATCH] reorg fill missing blocks --- internal/committer/reorg.go | 39 ++++++++++++++++++++++++++++++++++++- internal/libs/clickhouse.go | 4 ++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/internal/committer/reorg.go b/internal/committer/reorg.go index f40a426..031d73d 100644 --- a/internal/committer/reorg.go +++ b/internal/committer/reorg.go @@ -108,7 +108,35 @@ func detectAndHandleReorgs(startBlock int64, endBlock int64) (int64, error) { // 1) Block verification: find reorg range from header continuity (existing behavior) reorgStartBlock := int64(-1) reorgEndBlock := int64(-1) + missingStartBlock := int64(-1) + missingEndBlock := int64(-1) + missingBlockCount := 0 + lastHeaderBlock := startBlock - 1 + + for i, blockHeader := range blockHeaders { + expectedBlockNumber := startBlock + int64(i) + if blockHeader == nil || blockHeader.Number == nil { + if missingStartBlock == -1 { + missingStartBlock = expectedBlockNumber + } + missingEndBlock = expectedBlockNumber + missingBlockCount++ + continue + } + lastHeaderBlock = blockHeader.Number.Int64() + } + if missingStartBlock > -1 { + log.Warn(). + Int64("missing_start_block", missingStartBlock). + Int64("missing_end_block", missingEndBlock). + Int("missing_block_count", missingBlockCount). + Msg("Reorg: missing block headers in ClickHouse; scheduling repair from RPC") + } + for i := 1; i < len(blockHeaders); i++ { + if blockHeaders[i] == nil || blockHeaders[i].Number == nil || blockHeaders[i-1] == nil || blockHeaders[i-1].Number == nil { + continue + } if blockHeaders[i].Number.Int64() != blockHeaders[i-1].Number.Int64()+1 { // non-sequential block numbers reorgStartBlock = blockHeaders[i-1].Number.Int64() @@ -131,7 +159,6 @@ func detectAndHandleReorgs(startBlock int64, endBlock int64) (int64, error) { } // set end to the last block if not set - lastHeaderBlock := blockHeaders[len(blockHeaders)-1].Number.Int64() if reorgEndBlock == -1 { // No header-based end detected; default to the last header for last-valid-block tracking. reorgEndBlock = lastHeaderBlock @@ -162,6 +189,16 @@ func detectAndHandleReorgs(startBlock int64, endBlock int64) (int64, error) { finalEnd = reorgEndBlock } + // missing ClickHouse block headers range + if missingStartBlock > -1 { + if finalStart == -1 || missingStartBlock < finalStart { + finalStart = missingStartBlock + } + if finalEnd == -1 || missingEndBlock > finalEnd { + finalEnd = missingEndBlock + } + } + // transactions range if txStart > -1 { if finalStart == -1 || txStart < finalStart { diff --git a/internal/libs/clickhouse.go b/internal/libs/clickhouse.go index 63baaea..68a01ba 100644 --- a/internal/libs/clickhouse.go +++ b/internal/libs/clickhouse.go @@ -193,6 +193,10 @@ func GetBlockHeadersForReorgCheck(chainId uint64, startBlockNumber uint64, endBl // just to make sure the blocks are in the correct order for _, block := range blocks { + if block.Number == nil { + log.Warn().Msg("GetBlockHeadersForReorgCheck: skipping block header with nil block number") + continue + } idx := block.Number.Uint64() - sb if idx >= length { log.Error().Msgf("Block number %s is out of range", block.Number.String())