Skip to content

fix: align miner timeout cushion with validator extension runway#356

Merged
LandynDev merged 3 commits into
testfrom
fix/unify-cushion-blocks
May 21, 2026
Merged

fix: align miner timeout cushion with validator extension runway#356
LandynDev merged 3 commits into
testfrom
fix/unify-cushion-blocks

Conversation

@anderdc
Copy link
Copy Markdown
Collaborator

@anderdc anderdc commented May 20, 2026

Summary

Aligns the miner-side fulfillment cushion with the validator extension flow and removes the env override that let operators silently misconfigure it.

Today DEFAULT_MINER_TIMEOUT_CUSHION_BLOCKS = 5, but validators refuse to propose a timeout extension once current + CHALLENGE_WINDOW_BLOCKS >= deadline (optimistic_extensions.py:202) and won't reliably land one until current + EXTEND_THRESHOLD_BLOCKS of runway exists (forward.py:293). With cushion=5, a miner could start fulfilling at remaining=6 — inside the validator's no-rescue window. If dest-chain inclusion drags, the extension flow that's supposed to save the swap can't propose, and the miner eats a slash on a swap that was meant to be rescued.

What changed

  • MINER_TIMEOUT_CUSHION_BLOCKS pinned to EXTEND_THRESHOLD_BLOCKS (= forward step + challenge window = 18). The miner now stops starting new fulfillments exactly where the validator can no longer rescue them.
  • Env override removed. The right value is system-determined (validator runway), not operator preference. Drops load_timeout_cushion_blocks(), the hot-reload helper, os import in fulfillment.py, and the MINER_TIMEOUT_CUSHION_BLOCKS line from .env.example and README.md. Operators who genuinely need a different value edit constants.py.
  • Test updates: env-override tests replaced with constant-based boundary tests in test_fulfillment.py.

Scope notes

Originally the PR also added a user-side cushion in post-tx / resume-reservation, but on review those gates only ever fired post-facto (funds already sent) or in niche resume-after-long-interruption cases. The auto-send paths in alw swap now fire seconds after reserve, so a cushion there never gates anything real. Dropped the helper, constant, wire-ins, and tests — the miner-side change is the only one doing real safety work.

Test plan

  • pytest tests/test_fulfillment.py tests/test_probe_pending_reservation.py — 18/18 pass
  • Constants align: MINER_TIMEOUT_CUSHION_BLOCKS == EXTEND_THRESHOLD_BLOCKS == 18
  • No stale references to DEFAULT_MINER_TIMEOUT_CUSHION_BLOCKS, load_timeout_cushion_blocks, or USER_POST_TX_CUSHION_BLOCKS anywhere
  • Manual: spin up a miner with the old MINER_TIMEOUT_CUSHION_BLOCKS env var set, confirm it's silently ignored and miner uses 18-block cushion from constants.

anderdc added 2 commits May 20, 2026 18:23
Both the miner-side fulfillment cushion and the user-side reservation
post-tx flow gated on deadlines without referencing the validator's
extension propose runway. Result: a miner could start fulfilling at
remaining=6, and a user could broadcast confirm at remaining=1, both
landing inside the window where validators refuse to propose an
extension (current + CHALLENGE_WINDOW >= deadline). When dest inclusion
dragged or the source tx hadn't confirmed yet, there was no rescue path.

Changes:
- Pin both cushions to EXTEND_THRESHOLD_BLOCKS (= forward step +
  challenge window). MINER_TIMEOUT_CUSHION_BLOCKS goes from 5 to 18;
  USER_POST_TX_CUSHION_BLOCKS is new.
- Drop the MINER_TIMEOUT_CUSHION_BLOCKS env override and the
  load_timeout_cushion_blocks hot-reload helper. The right value is
  system-determined (validator runway), not operator preference;
  miners who need a different value edit constants.py directly.
- Add safe_reservation_remaining helper used by post-tx and resume
  to abort with a clear message when runway is inside the cushion.
- Remove the env-override tests; replace with constant-based boundary
  tests in test_fulfillment.py.
- Drop MINER_TIMEOUT_CUSHION_BLOCKS from .env.example and README;
  .env.example keeps a one-line deprecation note.
The note is noise for the 99% of operators who never set the env var
in the first place. Anyone still setting it sees no effect and can find
the constant in constants.py.
@anderdc anderdc force-pushed the fix/unify-cushion-blocks branch from 33d8ee4 to de32a02 Compare May 20, 2026 23:25
The auto-send paths fire near-instantly after reserve (1-2 blocks elapsed
out of 50), so the user-side cushion virtually never gates anything
real:
- alw swap now --auto: send happens seconds after reserve; cushion never fires
- alw swap now (manual): cushion at post-tx is post-facto, funds already sent
- resume-reservation --send near deadline: niche edge case
- resume-reservation manual: same as post-tx, funds already sent

Removes USER_POST_TX_CUSHION_BLOCKS, safe_reservation_remaining helper,
the post_tx.py / resume.py wire-ins, and the test file. Keeps the
miner-side alignment (the real safety win in the extension-rescue path)
and the env-override removal.
@anderdc anderdc changed the title fix: align miner + user CLI cushions with validator extension runway fix: align miner timeout cushion with validator extension runway May 20, 2026
@LandynDev LandynDev merged commit 2698acc into test May 21, 2026
3 checks passed
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