Skip to content

net: window catch-up getdata to the serve cap - #272

Merged
reardencode merged 6 commits into
masterfrom
net/catchup-getdata-window
Aug 26, 2026
Merged

net: window catch-up getdata to the serve cap#272
reardencode merged 6 commits into
masterfrom
net/catchup-getdata-window

Conversation

@rearden-grok

@rearden-grok rearden-grok Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Overnight core-functional (sync_blocks 60s) stalled when a catch-up node asked the whole header path while the serving peer reconstructs at most 16 bodies (MAX_SERVE_BLOCKS). Extra hashes stayed in requested / note_asked_block and were never re-asked.

Node-to-node getdata is MSG_CMPCT_BLOCK. Accepting CmpctBlock also left the hash in requested, so drain's window stayed full even after the 16 bodies connected.

Writer fetch_sub on every Block/CmpctBlock wrapped serve_inflight 0 → usize::MAX when compact tip announce used queue_out (no matching fetch_add). Later reconstruct then saw the cap and skipped serve. Saturating-sub fixes the wrap. Counting announce on the same cap then starved getdata during a generate burst (feature_bip68_sequence activateCSV 432 blocks). Coinbase-only compact used to bail when the hub had no mempool.

  • Red: catchup_headers_getdata_stays_in_serve_window — 20 connecting headers must GetData 16, then the remaining 4 after those bodies connect (failed: got 20).
  • Green: first ask and drain_pending continuation share fetchable_header_path_bodies, truncated to MAX_SERVE_BLOCKS. Weaker / below-minwork paths stay header-only.
  • Red: catchup_compact_getdata_clears_requested_for_next_window — same 20-header catch-up answered with CmpctBlock (failed: requested still 16).
  • Green: compact fill / blocktxn / already-have drop the hash from requested. Compact ancestor getdata is also capped at 16. Serve-inflight cap test is unchanged.
  • Red: compact_tip_announce_must_not_wrap_serve_inflight — unpaired writer decrement after announce must leave inflight at 0.
  • Green: writer saturating-subs; announce still uses queue_out.
  • Red: compact_tip_announce_must_not_consume_serve_slots — 16 queued announces must leave inflight at 0 so a later MSG_CMPCT_BLOCK getdata still serves.
  • Green: announce does not fetch_add. Coinbase-only compact fills from prefilled txs without a mempool.

Overnight run: https://github.com/reardencode/rbitcoin/actions/runs/32941780319

Green core-functional: https://github.com/reardencode/rbitcoin/actions/runs/32995598334

Test plan

  • cargo test -p rbitcoin-net --lib catchup_headers_getdata
  • cargo test -p rbitcoin-net --lib catchup_compact_getdata
  • cargo test -p rbitcoin-net --lib compact_tip_announce
  • cargo test -p rbitcoin-net --lib coinbase_compact_fills_without_mempool
  • cargo test -p rbitcoin-net --lib (worktree)
  • CI required jobs + labeled core-functional

@rearden-grok rearden-grok Bot added the core-functional Run Core functional nightly.sh on this PR (inventory + release-pin warn) label Aug 26, 2026
@rearden-grok
rearden-grok Bot force-pushed the net/catchup-getdata-window branch from 1b19ad3 to 1b6b9f0 Compare August 26, 2026 15:24
@reardencode reardencode reopened this Aug 26, 2026
rearden-grok Bot and others added 4 commits August 26, 2026 09:11
Connecting headers of 20 asked GetData for the whole path. The peer
serves at most MAX_SERVE_BLOCKS (16), so extra hashes stuck in
requested and sync_blocks timed out (minchainwork 50, createmultisig
149, bip68 CSV).

Co-authored-by: Cursor <cursoragent@cursor.com>
Asking the whole header path left hashes in requested while the peer
reconstructed at most 16. First ask and drain continuation share
fetchable_header_path_bodies so leftover heights are re-asked after
the window connects.

Co-authored-by: Cursor <cursoragent@cursor.com>
Node-to-node getdata is MSG_CMPCT_BLOCK. Accepting CmpctBlock left
the hash in requested, so drain's serve window stayed full and the
rest of the header path was never asked.

Co-authored-by: Cursor <cursoragent@cursor.com>
MSG_CMPCT_BLOCK replies never left requested, so drain truncated
the next window to zero. Also cap compact ancestor getdata at
MAX_SERVE_BLOCKS like the headers path.

Co-authored-by: Cursor <cursoragent@cursor.com>
@rearden-grok
rearden-grok Bot force-pushed the net/catchup-getdata-window branch from 1b6b9f0 to 2196b85 Compare August 26, 2026 16:11
rearden-grok Bot and others added 2 commits August 26, 2026 10:19
Writer fetch_sub on every CmpctBlock wrapped 0 to usize::MAX when
tip announce used queue_out, so later reconstruct was skipped
(sync_blocks 60s). Count announce on the same counter, saturating-sub
on write, and fill coinbase-only compact without a mempool.

Co-authored-by: Cursor <cursoragent@cursor.com>
Counting tip announce on serve_inflight filled the reconstruct cap
during a generate burst, so later getdata was skipped (bip68
activateCSV sync_blocks). Announce uses queue_out; writer still
saturating-subs so an unpaired CmpctBlock cannot wrap the counter.

Co-authored-by: Cursor <cursoragent@cursor.com>
@reardencode
reardencode merged commit cd6dded into master Aug 26, 2026
13 checks passed
@rearden-grok
rearden-grok Bot deleted the net/catchup-getdata-window branch August 26, 2026 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core-functional Run Core functional nightly.sh on this PR (inventory + release-pin warn)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant