Skip to content

fix(validator): fast-reject reservations while halted#458

Merged
entrius merged 1 commit into
testfrom
fix/halt-fast-reject-reservations
Jun 8, 2026
Merged

fix(validator): fast-reject reservations while halted#458
entrius merged 1 commit into
testfrom
fix/halt-fast-reject-reservations

Conversation

@anderdc

@anderdc anderdc commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

What

When the system is halted, handle_swap_reserve now rejects the request immediately — before any provider/substrate work or extrinsic submission — instead of running the full handler and letting the contract reject the vote_reserve.

Why

A halt blocks reservations contract-side (vote_reserveSystemHalted revert). 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_reserve checks validator.bounds_cache.halted() first and reject_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).
  • Scope: reservations only (handle_miner_activate / vote_activate are low-volume and left as-is).

Tests

  • TestHaltFastReject: halted → rejected with no vote_reserve submitted, and short-circuits before read_miner_commitment.
  • Default bounds_cache.haltedFalse in the reserve test helper so existing reserve tests exercise the live path.
  • Full suite: 691 passed; ruff + format clean.

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.

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 entrius merged commit db9ab0d into test Jun 8, 2026
3 checks passed
@entrius entrius deleted the fix/halt-fast-reject-reservations branch June 8, 2026 23:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants