feat: in-flight transaction tracker for the txpool and batch sealer - #120
feat: in-flight transaction tracker for the txpool and batch sealer#120bronxyz wants to merge 3 commits into
Conversation
Security Scan - CodeSeverity: HIGH, CRITICAL No vulnerabilities found View scan results |
b01daa0 to
8b580d3
Compare
- saturate the diagnostic nonce span: range.max - range.min + 1 overflowed at nonce u64::MAX, and under overflow-checks + panic=abort one crafted batch pairing nonce 0 with u64::MAX from a single sender aborted every node that logs the range - a whole-network halt; regression nonce_span_saturates_at_the_max_nonce - pin the workspace metrics facade to 0.24, the version reth's prometheus recorder registers against: the entry is uninherited today, but the first crate to adopt it at 0.23 would bind a second global and its gauge!/counter! would silently no-op (the facade-version trap this repo has hit before)
- add InFlightTracker: records hashes sent to the mempool but not yet observed mined, so a sealing or forwarding round skips the hashes it already has outstanding - arm per role behind a capability handle (SealMarks/ForwardMarks); sealing wipes its set each round, forwarding keeps its marks across the epoch boundary so the resend backoff survives - gate release on a base wait plus capped exponential backoff plus a minimum execution-anchor advance; AckedStale marks are terminal and never released by the TTL sweep - compute each metric delta under the same write lock that applies it, so marked - reconcile - ttl - clear equals the live set and the gauge under any interleaving (proptest drives concurrent writers) - snapshot and restore marks across a restart through a versioned MarkBackup, applied lazily at the next matching-role arm with rebased clocks - no production caller yet: this lands the tracker ahead of the builder and forwarder that will consume it
- WorkerTxPool owns the InFlightTracker, exposes is_in_flight, and reconciles marks against the pending sub-pool on each canonical update - build_batch skips a hash still in flight, so a stuck inclusion backlog is not re-sealed batch after batch - on quorum the sealer marks the batch in flight instead of evicting it, so the txs stay pending and RPC-visible until execution drains them - the "anything to seal?" guard scans for a non-in-flight tx, so retained marks do not spin the builder on empty batches - mark through the armed SealMarks capability, since the direct mark_in_flight helper is test-only - add a failing-first regression that a sealed batch is not re-proposed while it is in flight - retarget four builder tests that asserted drain-on-quorum to the new contract: sealed txs stay pending and marked in flight until execution - scope is the pool and sealer only; the builder pipeline refactor and the observer forwarder that will also consume the tracker are deferred
8b580d3 to
689f3fc
Compare
|
Claude finished @bronxyz's task in 3m 48s —— View job PR Review: feature/txpool in-flight tracker coreTasks:
OverviewThe latest commit ( None of the previously flagged issues have been resolved. The same two merge-blockers remain, plus a new severity upgrade on the stale-comment finding. Bug:
|
| Severity | Finding | Status |
|---|---|---|
| Bug | MarkBackup::version never checked — stale backups restored silently |
Still present |
| Bug | release_dropped never called — nonce-drop marks only clear via 60s TTL |
Still present |
| Bug | update_canonical_state_async added but process_canon_state_update still calls sync version — blocks async runtime |
Severity upgrade |
| Design | SealMarks::mark hardcodes anchor: 0 — implicit dep on min_anchor_advance: 0 |
Still present |
| Design | stash_restore silently drops a prior stash |
Still present |
| Perf | reconcile_in_flight is O(all pending txs) on every canonical update |
Still present |
| Nit | arm_sealing/arm_forwarding missing #[must_use] |
Still present |
| Nit | on_released calls gauge.sub(0) in no-op paths |
Still present |
The wiring in this commit is correct. I'd want the version-validation bug, the release_dropped gap, and the sync-vs-async call site resolved before merging. The anchor=0 issue is lower priority but worth fixing while the sealing-mark code is being touched.
- `MARK_BACKUP_VERSION` was written but never read on restore; bcs is positional, so a reshaped backup could decode into wrong marks instead of being refused - `#[must_use]` on `SealMarks`/`ForwardMarks`: dropping the handle silently discards the capability the arm minted; one test was doing exactly that - addresses the PR #120 (feature/txpool-in-flight-tracker-core) review: unchecked `MarkBackup::version` and the missing `#[must_use]` on the arm handles
Summary
InFlightTracker: the txpool records hashes sealed into a batch but not yet observed mined, so the next sealing round skips them instead of re-sealing a stuck backlog batch after batch. Marks are armed per role behind a capability handle (SealMarks/ForwardMarks), released by a reconcile against the pending sub-pool plus a backoff-gated sweep, and snapshot/restored across restarts through a versionedMarkBackup.u64::MAX(overflow-checks + panic=abort turned one crafted batch into a whole-network halt), and the workspacemetricsfacade is pinned to 0.24 so a crate adopting 0.23 cannot bind a second global whose macros silently no-op.Stack 1/9 of the txpool in-flight tracker and observer-forwarder series. The builder pipeline and the forwarder that also consume the tracker land in later PRs; this one scopes to the pool and sealer.
Surface areas touched
eth_*,rayls_*, faucet)rayls-contracts/)etc/, scripts, Docker, compose).github/workflows/,Makefile)doc/, in-crate READMEs, root docs)Breaking / compatibility
None. No wire or storage format changes; the mark backup file is new and only read when present.
Test plan
nonce_span_saturates_at_the_max_noncefails on the pre-fix span arithmetic.marked - reconcile - ttl - clearequals the live set and the gauge.make checkon the stack tip; CI (fmt,clippy, workspace tests) on this branch.