Backport stall/reorg fixes onto v0.6.x - #468
Open
rearden-grok[bot] wants to merge 31 commits into
Open
Conversation
Inner strings like "invariant: io_uring undrained" lack "corrupt record", so from_err_str treated them as Cascade. Recover/halt need EngineFault. Pin each session-fault string on StoreError and the confirm reject map. Co-authored-by: Cursor <cursoragent@cursor.com>
A 5s spin used to return with leftover SQEs so callers dropped in-flight buffers. Every UringSession now uses DrainBudget: progress resets the zero-CQE clock, slow drains log, and zero completions for RBITCOIN_URING_DRAIN_HARD_SECS (default 120) abort. Tests hit HardCap as undrained instead of abort(). Co-authored-by: Cursor <cursoragent@cursor.com>
Class C leftover above tip is the same repair as open. Credit is a tip gap so a recovered batch of 144 does not mint a new recover. Exhausted does not repair. Drops only this thread's TLS ring. Co-authored-by: Cursor <cursoragent@cursor.com>
Write requeues the same BQ heights after a credited recover; lookup does the same instead of warning every 20s. Credit exhausted or a drain stall aborts and names RBITCOIN_IO=pread. Failed head drain re-notes the taken pending list. ibd: perf gains uring_recover, slow_drain, and lookup_faults. Co-authored-by: Cursor <cursoragent@cursor.com>
Operators saw 19h of undrained warnings under idle IO. Document the 120s hard-cap abort, 1000-height recover, Class C repair, and that there is no mid-run libc fallback. Co-authored-by: Cursor <cursoragent@cursor.com>
Darwin SessionBackend is Pool-only, so `_` in drain_all_pool was unreachable under -D warnings and failed macos CI. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep IoCtx public (0.6.0 surface). The 0.6.99 pick wanted pub(crate) and dropped with_thread_local from the same use. Co-authored-by: Cursor <cursoragent@cursor.com>
Assumed 100ms windows let EINTR spin hit the hard cap. note() now takes a real dt. submit_and_wait_one shares that budget. Session Drop waits then poisons without abort(). Session-fault match is any Corrupt io_uring message except Linux-only/unavailable. drop_thread_local is gone: poisoned TLS already reopens. Co-authored-by: Cursor <cursoragent@cursor.com>
Lookup must not clear strong bits while write sets them before the fence. In-process recover no longer runs Class C repair. Two threads cannot both pass the tip-gap check. Co-authored-by: Cursor <cursoragent@cursor.com>
ConsensusError::is_uring_session_fault covers leftover cqe and submit failed. Head insert returns the taken batch on Err so write does not clone the drain list on the success path. Co-authored-by: Cursor <cursoragent@cursor.com>
One helper returns Option recover. Write classify takes that Option. Lookup EngineFault skips emit when ready has no hash. Load stamp/pin and scripts requeue on credited recover. Tip connect retries instead of note_invalid_block. Co-authored-by: Cursor <cursoragent@cursor.com>
Open still repairs leftover strong. In-process recover does not. Lookup 8 consecutive Io dequeues BQ; session-fault recover does not. Co-authored-by: Cursor <cursoragent@cursor.com>
WaitOneWindow::Enter is only built from io_uring enter errors. IOCP wait_one_cqe had no callers after the timeout drain loop. Both failed -D warnings on macos/windows CI. Co-authored-by: Cursor <cursoragent@cursor.com>
Write, load, scripts, lookup, and tip-connect each matched Recovered vs Exhausted. Credit/abort lives on Query; IBD requeue sites share one helper. Lookup's 8-strike halt no longer carries recover arms. Co-authored-by: Cursor <cursoragent@cursor.com>
Explicit drain_all stays fail-closed. A hard cap while a drain guard is live poisons and returns Corrupt in tests; it does not abort.
…rain Class C can commit, then post_commit or tx.head drain session-fault. height_of_hash matching is not write-finished; post_commit is idempotent.
Write session-fault requeues even when has_block so annotate+drain can finish. Load recover clears speculative create FKs inline; sync_body_hwm max would not roll next_tx_start down.
The guard drops before SQE buffers. Fail-open on hard cap frees those buffers while the kernel still owns the SQEs. Session Drop stays fail-open; it does not own buffers.
Keep 0.6.0 with_thread_local / IoCtx public. Changelog drain stall is credit-only (Class C leftover waits for open repair). Co-authored-by: Cursor <cursoragent@cursor.com>
Session-fault after Class C is connected: take recover credit and call finish_post_commit_hashes in place. Requeue is stale vs tip and dropped by lookup. Annotate only hashes whose height_of_hash matches; multi-list repeat of the same spend_fk is Skip.
Core treats nHeight < coinbaseHeight + 100 including the creating block. Structural spentness skipped NULL creates, so a later tx in the same block could spend the coinbase. Co-authored-by: Cursor <cursoragent@cursor.com>
claim_ready treated H ≤ taken_hi as in-hand. Only BadPrev rewound it, so merkle/cascade/engine-fault left densify with hole=0 and no getdata. Cancelled still leaves the high-water. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
NULL create_fk already means same-block on the existing spends walk. Notate this block's coinbase txid once and reject there, instead of a second spends.iter() pass. Co-authored-by: Cursor <cursoragent@cursor.com>
Assemble already maps this block's txids and refuses child-before-parent when pj >= ti. Parent index 0 is the coinbase, so maturity is the same lookup — no second spends walk and no extra coinbase txid hash. Co-authored-by: Cursor <cursoragent@cursor.com>
A reconstructed compact on a held equal-work sibling can fail bad-txnmrklroot after accept_branch wraps Mutated as ConnectFailed. That marked the header hash invalid, so the later honest getdata and every peer advertising the winning chain were banned (mainnet 966501). Drop the mutated body and keep the hash acceptable; true consensus rejects still mark BLOCK_FAILED. Co-authored-by: Cursor <cursoragent@cursor.com>
BIP152 allows a unique short-id or blocktxn fill to assemble the wrong txs under the compact header. We treated a full slot fill as a block and offered it to accept_branch (reorg then bad-txnmrklroot). FinishBlock before Ok so the peer path getdata instead. Co-authored-by: Cursor <cursoragent@cursor.com>
DisconnectTip collects every create list to rewrite it. IBD megakeys can stamp extent_n past the 64MiB bulk-pread cap; treating that as Corrupt blocked equal-work sibling rewind. Walk the linked chain instead, and pin SH+tweaks disconnect together. Co-authored-by: Cursor <cursoragent@cursor.com>
v0.6.0 has no rbitcoin_query::testutil. Backported tests open a tiny-head Query (or ChainHub) with Query::open_or_create so they compile on this line. Co-authored-by: Cursor <cursoragent@cursor.com>
create_tiny and WriteIoBackend annotate args are master-only. The extent unlink pin uses ScriptHashTable::create; the 441 annotate pin uses SpendAnnBackend::Pwrite. Co-authored-by: Cursor <cursoragent@cursor.com>
Backport of master #469. False parent edges can cycle the header child map; iterative DFS re-pushed gray nodes forever so IBD sat on "resume seed walk start". Skip on-stack nodes and log graph n= before rewind (so SH unlink can run). Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Backport onto
v0.6.x(schema 20, still 0.6.0) of the tip-follow stall and reorg fixes that landed on master after 0.6.0. This is not a 0.6.1 cut.drain_allwaits for CQEs; 120s zero-CQE abort; one recover credit per 1000 heights; EngineFault; already-at-height still finishes post-commit; IBD session-fault resume finishes annotate+drain on the write thread; load recoverclear_allafternote_lookup_ok.coinbase immature; IBDlookup_taken_hirewind on post-lookup confirm reject.Ok(empty missing → getdata); merkle/bad-txnmrklrootis not cachedBLOCK_FAILED.extent_nexceeds the 64 MiB span-pread cap (equal-work sibling rewind after compact reconstruct).on_stack) nodes so aprev_fkcycle cannot spin IBD onresume seed walk start; loggraph n=before most-work rewind so SH unlink can run.pull_request.branches: [master, main]so PRs targetingv0.6.x(and stacked topics) getrefs/pull/N/mergeSARIF. Workflow YAML is a local commit (22abf3e2); App token cannot push.github/workflows/*— operator must pushbackport/0.6.x-stalls.Left on master (not needed for these incidents, or 0.6.0-incompatible):
try_reconstruct<T: Borrow<Transaction>>and the pre-ground 48-bit wtxid collision journey (a8c5dcee). Unit pinsunique_shortid_wrong_body/apply_blocktxn_wrong_body/mutated_compact_child_of_held_sibling_is_not_block_failedare here.spent.idxdrop / X-01confirm_stats.0.6.x adapters:
Query::open_or_createinstead ofrbitcoin_query::testutil; SCHEMA.md keeps schema-20 Mode 10 linked-walk wording.Test plan
cargo test -p rbitcoin-store --lib extent_span_over_cap_still_unlinkscargo test -p rbitcoin-query --lib disconnect_tip_unlinks_megakey/uring_recovercargo test -p rbitcoin-consensus --lib accept_rejects_same_block_coinbase/already_at_height_retries_post_commitmutated_compact_child_of_held_sibling_is_not_block_failedpost_lookup_reject_rewinds_taken_hicargo test -p rbitcoin-query --lib resume_subtree_score_prev_fk_cycle_terminatesfmt,deny,clippy,ast-grep,test,windows,macos,multinode,coverage)