#35837 rpc: fail scanblocks when block filter range is unavailable

ReviewabilityReviewsAgreementSize
#35837 MicSm rpc: fail scanblocks when block filter range is unavailableReady0Blocked22 + 59 tests
  • Stop scanblocks from silently omitting unindexed blocks and returning incomplete match results
  • Fail with an explicit error when reading block filters fails, alerting callers to incomplete scans
  • Author needs to address open review objections regarding functional tests and error handling
  • Concept approval for preventing silent failures when reading block filters (maflcko, fjahr)
  • Unaddressed objection: functional test relies on races and mines excessive blocks (fjahr)
  • Questions whether to return partial results instead of erroring when a range is missing (fjahr)
  • Concern that checking index readiness at scan start may misclassify errors on long scans (fjahr)
  • 22 lines added or modified outside tests
  • 59 lines added or modified in tests
  • 13 lines removed in total
  • 2 files, 1 commits
RPC / REST / ZMQ#2 of 55
P1 · bug fix
  • P1 because it prevents silent data gaps that cause callers to miss transactions in unindexed ranges
  • Eliminating misleading success responses prevents fund safety and correctness risks for filter users
Reviewability: ReadyStalePaused
Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets
Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs.
Size: lines added or modified outside tests, then in tests; greener = smaller.

Goal

Updates the scanblocks RPC to throw an error when reading block filters fails instead of silently ignoring the failure. The RPC now returns a 'still in the process of being indexed' error if the block filter index has not caught up to the chain tip, and an internal error if the index is already synced.

Problem: When scanblocks queries a block range that has not yet been indexed—such as right after startup while the block filter index catches up in the background—LookupFilterRange fails. The RPC ignored the failure, advanced the block pointer past the chunk, and returned a completed status with an incomplete match list, leaving callers unable to tell whether blocks had no matches or were simply skipped.

Evidence of importance:

  • PR description: 'The result is a silent gap: a caller gets a relevant_blocks list that looks fine but is missing any match in the unindexed range, with no way to distinguish "no matches" from "range was never scanned".'
  • Diff in src/rpc/blockchain.cpp shows LookupFilterRange failure previously had no error handling branch and fell through to start_index = end_range.

Reviewability

Ready

Nothing known that would invalidate a review now.

Waiting on (from the thread read):

  • author: address review feedback on functional test determinism, block count, and scan error handling 2026-11-01

Agreement

Blocked

objection that needs a change, nobody has replied (fjahr)

Thread notes: The author confirmed they are working on addressing review feedback in response to an inquiry. All open review claims remain pending changes or answers.

Objections, suggestions, and questions:

ReviewerTypeHarm, request, or questionStatusMust beAuthor repliedQuote
maflcko (member)suggestion, styleRemove the external link to the AI tool from the PR descriptionanswered · author replied 'done' in c:5194105480 and updated the descriptionansweredyes2026-07-30: 'However, I think the link to the tool can be removed and this can just say "I found this regression while reviewing the RPC with an AI-assisted tool".'
Status from: 2026-08-05: MicSm: 'done'
fjahr (member)objection, approachFailing scans unconditionally when the index is behind the tip breaks scans for ranges that are already available.fixed · fix pushed · author updated to mirror getblockfilter and only fail when the requested range is unavailablechangedyes2026-07-30: 'There we don't fail unconditionally if the index isn't synced. We only fail if we the range isn't available.'
Status from: 2026-08-04: MicSm: 'You're right - thanks. getblockfilter does not fail merely because index is behind the tip, so it fails when the request'
fjahr (member)suggestion, maintenanceRemove the redundant wait for the index to sync right before deleting it.openansweredno2026-09-17: 'This doesn't make sense, you are waiting for the index to be synced just to delete it without doing anything else.'
fjahr (member)objection, maintenanceThe functional test mines an excessive number of blocks.openchangedno2026-09-17: 'No normal functional test should require mining this many blocks.'
fjahr (member)objection, correctnessThe functional test relies on races and is non-deterministic.openchangedno2026-09-17: 'And we don't leave the actual testing to chance. The test either needs to work deterministically or it is of no use for us, with maybe some very rare exceptions.'
fjahr (member)objection, correctnessIndex readiness checked before the scan begins may become outdated by the end of a long scan, leading to misclassified errors.openansweredno2026-09-17: 'This status may be outdated at the end of a long scan.'
fjahr (member)question, interfaceWhy throw an error when a filter range is unavailable instead of returning a partial result?openansweredno2026-09-17: 'Why throw here instead of returning a partial result?'

Support:

  • maflcko (member) (Concept ACK, 2026-07-30) [read]: Fixes silent ignore of LookupFilterRange failures
  • fjahr (member) (Concept ACK, 2026-09-17) [read]: Concept ACK on handling this but the test needs a lot of work

Participants:

  • fjahr (member, objection, 15 statements 2026-07-30 to 2026-09-17): Concept ACK on the fix, but objected to unconditional failure on unsynced index (fixed), criticized test determinism and excessive blocks, and questioned cached index status and throwing vs partial re
  • maflcko (member, support, 1 statements 2026-07-30 to 2026-07-30): Concept ACK on addressing silent LookupFilterRange failures; suggested removing tool link in description
  • sedited (member, neutral, 1 statements 2026-10-30 to 2026-10-30): asked if the author is still working on the PR

Files

59 lines under test/bench/ci.

  • test/functional/rpc_scanblocks.py +59/-0
  • src/rpc/blockchain.cpp +22/-13

Card

The short text the ranking pass compares across PRs.

Throws an RPC error in scanblocks when reading a block filter range fails, rather than silently skipping the affected chunk and reporting completed: true. When the block filter index is still syncing behind the active chain tip, callers touching unindexed blocks previously received partial results that silently omitted matching transactions. The RPC now returns an indexing-in-progress error if the index has not finished syncing or an internal error if already synced, matching getblockfilter behavior.

Data

dossier JSON · extract JSON · model ledger, generated 2026-11-02T01:10, confidence high, input hash 0765aa81ae5ce6c9
thread read through 2026-11-01 (21 statements), head 55abc8b820
labels: RPC/REST/ZMQ

Categories

RPC / REST / ZMQ

P1 · bug fix

Fixes a silent correctness bug where scanblocks ignores LookupFilterRange errors and returns incomplete match results as successful. As noted in the description, 'The result is a silent gap: a caller gets a relevant_blocks list that looks fine but is missing any match in the unindexed range', creating fund-safety and correctness risks for applications relying on filter scanning.

Membership: Matches RPC/REST/ZMQ label and modifies RPC method implementation in src/rpc/blockchain.cpp.

Factors: security/stability 1, bug 2, performance 0, user value 2, leverage 0