-
Notifications
You must be signed in to change notification settings - Fork 9
Description
Bug Report
Summary
The indexer crashes with a nil pointer dereference panic in checkContinuity() when an RPC call fails (e.g., HTTP 429 rate limit). Additionally, worker goroutines lack panic recovery, so any panic crashes the entire process instead of being handled gracefully.
Stack Trace
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0xb68bfc]
goroutine 227 [running]:
github.com/fystack/multichain-indexer/internal/worker.checkContinuity(...)
/app/internal/worker/regular.go:293
github.com/fystack/multichain-indexer/internal/worker.(*RegularWorker).processRegularBlocks(0x4000322600)
/app/internal/worker/regular.go:134 +0x57c
First observed: 2026-03-01T00:11:44Z
Trigger: Alchemy RPC returned HTTP 429 (monthly capacity limit exceeded) for block 74589534, causing a nil Block in the results.
Root Cause
1. Nil pointer dereference in checkContinuity (internal/worker/regular.go)
In processRegularBlocks(), the loop at line 145 skips results where res.Block == nil via continue. However, the continuity check at line 158-159 always references results[i-1]:
if i > 0 && rw.isReorgCheckRequired() {
if !checkContinuity(results[i-1], res) { // results[i-1].Block may be nil!If results[i-1] was a failed block (skipped via continue), its Block field is nil. checkContinuity then dereferences prev.Block.Hash → panic.
2. No panic recovery in worker goroutines
RegularWorker.Start()launchesgo rw.run(...)with norecover()—regular.go:65CatchupWorker.Start()launchesgo cw.runCatchup()with norecover()—catchup.go:72- Catchup parallel workers also lack recovery —
catchup.go:207
Any panic in these goroutines takes down the entire indexer process.
Fix Plan
Fix 1: Track the index of the last successfully processed result and use that for the continuity check instead of blindly using results[i-1].
Fix 2: Add defer recover() with error logging to all worker goroutines (BaseWorker.run, CatchupWorker.runCatchup, and catchup parallel workers) so a panic is caught, logged, and the worker can restart rather than crashing the process.
Impact
- Severity: Critical — crashes the entire indexer process
- Affected chains: EVM and BTC (chains with reorg detection enabled)
- Reproduction: Occurs when an RPC provider returns errors (429, timeout, etc.) for one block in a batch while other blocks succeed