Skip to content

fix(cycles): icp cycles buy gives up after five minutes without word of the order - #830

Open
raymondk wants to merge 1 commit into
mainfrom
cycles-buy/06-wait-clock
Open

raymondk wants to merge 1 commit into
mainfrom
cycles-buy/06-wait-clock

Conversation

@raymondk

@raymondk raymondk commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

The wait polled the gateway every three seconds, and its limits did not hold while the gateway was out of reach. A single poll had only the HTTP client's limit, six minutes, so a connection that stalled rather than dropped held the live line at "Waiting for payment" that long. The give-up rule counted a hundred consecutive failed polls: five minutes on a network that refuses at once, but about ten hours on one that stalls. And the hour limit was checked only after a successful poll, so it never fired while the gateway was unreachable.

Now a poll gets 10 seconds, and after five minutes without word of the order the wait gives up with ContactLost, which carries the order as last seen over the last poll's failure, so the command can say where the order stands. Both the give-up and the hour are judged on the clock after every poll, answered or not. Still a query every three seconds; nothing else about the order changes. Ctrl-C still lands at any moment, as before.

Code by Josh, cut down from #824 (commit 9cd3e1c, wait part only): WaitOptions { poll_interval, poll_timeout, give_up_after, timeout }, PollTimedOut and ContactLost errors. Not included, after review: the live line saying the gateway has gone quiet and is answering again, and the WaitEvent callback that drove it. A user who sees nothing for a while can Ctrl-C, and #831 then says where the order stands.

Tests: four clock-driven unit tests in cyclepay/tests.rs (a stalled network given up on after five minutes with the poll timeout as the cause, a refusing one with the refusal, an order gone for five minutes not found, a gateway back within five minutes carried on with) and the hour still holding on an unpaid order.


Part of restacking #824 into small PRs, one fix each, stacked on main in this order: cycles-buy/06-wait-clock → 07-follow-up → 08-json-fields. Each PR targets the one below it; after the one below merges, retarget to main.

🤖 Generated with Claude Code

https://claude.ai/code/session_015aem4tPs4TYVZb8k4LMbJJ

@raymondk
raymondk requested a review from a team as a code owner October 16, 2026 22:48
@raymondk
raymondk added this pull request to stack #835 October 20, 2026 15:44
@raymondk
raymondk force-pushed the cycles-buy/06-wait-clock branch from 8e7c8b2 to 8e00aa9 Compare October 20, 2026 15:45
Copilot AI balanced review requested due to automatic review settings October 20, 2026 15:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The overall one-hour timeout remains unenforced during an outage spanning that deadline.

1 open issue
What changed in this PR

Makes icp cycles buy detect gateway outages and bound waits without changing the order flow.

Changes:

  • Adds poll timeouts and clock-based outage detection.
  • Reports lost and restored contact, preserving the last known order on failure.
  • Adds timing tests, an integration test, and documentation.
File Description
docs/​guides/​tokens-and-cycles.md Documents outage warnings and wait limits.
crates/​icp-cli/​tests/​cycles_tests.rs Tests gateway stop/restart reporting.
crates/​icp-cli/​src/​cyclepay/​tests.rs Tests outage timing, recovery, and timeout behavior.
crates/​icp-cli/​src/​cyclepay/​purchase.rs Adds timed polling and connectivity events.
crates/​icp-cli/​src/​commands/​cycles/​buy.rs Displays connectivity changes and failure context.
CHANGELOG.md Records the wait reliability improvements.

Review effort: Balanced

Comment thread crates/icp-cli/src/cyclepay/purchase.rs Outdated
select! {
biased;
_ = interrupt.as_mut() => return Step::Interrupted,
_ = sleep_until(give_up_at) => return Step::GaveUp,
@raymondk
raymondk force-pushed the cycles-buy/06-wait-clock branch 2 times, most recently from a5ed15f to 94b912e Compare October 20, 2026 18:48
…of the order

The wait polled the gateway every three seconds with no time limit of its
own on a poll, so a stalled connection held it for the HTTP client's six
minutes; the give-up rule counted a hundred consecutive failed polls,
which took five minutes on a network that refuses and ten hours on one
that stalls; and the hour limit was only checked after a successful
poll, so it never fired while the gateway was unreachable.

Now a poll gets ten seconds, and after five minutes without word of the
order the wait gives up with `ContactLost`, carrying the order as last
seen over the last poll's failure. Both that and the hour are judged on
the clock after every poll, answered or not. Still a query every three
seconds; nothing else about the order changes.

Code by Josh, cut down from #824 (commit 9cd3e1c, wait part only).
Not included: the live line saying the gateway has gone quiet and is
answering again, and the events that drove it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015aem4tPs4TYVZb8k4LMbJJ
@raymondk
raymondk force-pushed the cycles-buy/06-wait-clock branch from 94b912e to f880802 Compare October 20, 2026 19:34
@raymondk raymondk changed the title fix(cycles): icp cycles buy notices when the gateway stops answering and gives up after five minutes fix(cycles): icp cycles buy gives up after five minutes without word of the order Oct 20, 2026
@raymondk
raymondk deleted the branch cycles-buy/05-paste-flags October 20, 2026 19:35
@raymondk raymondk closed this Oct 20, 2026
@raymondk raymondk reopened this Oct 20, 2026
@raymondk
raymondk removed this pull request from stack #835 October 20, 2026 19:40
@raymondk
raymondk changed the base branch from cycles-buy/05-paste-flags to main October 20, 2026 19:40
@raymondk
raymondk added this pull request to stack #838 October 20, 2026 19:40

This branch has not been deployed

No deployments
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.

3 participants