fix(validator): fast-reject reservations while halted#458
Merged
Conversation
The contract blocks vote_reserve during a halt (SystemHalted revert), but the validator currently still runs the full handler and submits the doomed extrinsic. During a halt that turns into a retry storm: miners re-request, each failed reserve burns a round-trip, and the writes contend for the hotkey's nonce/write path — starving confirm/timeout votes for in-flight swaps. Check bounds_cache.halted() at the top of handle_swap_reserve and reject immediately, before any provider/substrate work or extrinsic submission. halted() fails open, so an RPC blip falls through to the contract's own rejection rather than refusing a valid reserve.
entrius
approved these changes
Jun 8, 2026
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.
What
When the system is halted,
handle_swap_reservenow rejects the request immediately — before any provider/substrate work or extrinsic submission — instead of running the full handler and letting the contract reject thevote_reserve.Why
A halt blocks reservations contract-side (
vote_reserve→SystemHaltedrevert). Today the validator still does the full handler work and submits the doomed extrinsic anyway. During a halt that becomes a retry storm: miners re-request, each rejected reserve burns a full round-trip, and those writes contend for the validator hotkey's nonce/write path — starving the confirm/timeout votes for in-flight swaps (the failure mode behind the 3728/3729 slashes).Rejecting at the source removes the storm: no doomed extrinsics, no chain spam, and confirm/timeout votes for in-flight swaps run unobstructed during a halt (those aren't halt-gated and are supposed to keep resolving).
How
handle_swap_reservechecksvalidator.bounds_cache.halted()first andreject_synapse(...)returns before proof/balance/commitment reads or any vote.bounds_cache.halted()is cached (short TTL) and fails open — on an RPC blip it returns not-halted, so we never wrongly refuse a valid reserve; worst case we fall through to the contract's own rejection (today's behavior).handle_miner_activate/vote_activateare low-volume and left as-is).Tests
TestHaltFastReject: halted → rejected with novote_reservesubmitted, and short-circuits beforeread_miner_commitment.bounds_cache.halted→Falsein the reserve test helper so existing reserve tests exercise the live path.Notes
Separate from #457 (the write-lock nonce fix). This PR alone neutralizes the halt-induced flood at the source; #457 fixes the underlying nonce collision generally. They're complementary.