Skip to content

fix: alert on unsendable cancels and stop paying 2 indexers - #737

Merged
MoonBoi9001 merged 7 commits into
mb9/fix-small-cancel-review-findingsfrom
mb9/alert-and-stop-double-paying-on-failed-cancels
Oct 9, 2026
Merged

MoonBoi9001 merged 7 commits into
mb9/fix-small-cancel-review-findingsfrom
mb9/alert-and-stop-double-paying-on-failed-cancels

Conversation

@MoonBoi9001

@MoonBoi9001 MoonBoi9001 commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

A cancel that can never be sent now counts toward the stuck alert, and an agreement whose indexer stopped serving it is replaced only once it can't be paid, whatever ends it. The cancel retry also runs as its own service rather than inside the optional chain listener, which config can turn off.

A cancel the chain client refused to send, such as gas over the cap or a signer out of funds,
counted as an outage, so it was retried forever without raising agreement_cancel_stuck. The
chain is read just before each send, so every failed send now counts except an unchecked receipt.
Agreements marked Cancelling were only ever finished by a sweep inside the chain listener, which
config can turn off, leaving them cancelling for good. The sweep now runs on its own every 5 minutes
whatever the listener does, and a stop request cuts a slow sweep short.
When the cancel of an agreement whose indexer stopped serving it failed, a replacement was queued
anyway, so dipper paid both indexers until a retry landed the cancel. The replacement now waits
until the chain shows the old one ended, and the cancel retry queues it once it ends it.
When a replacement was accepted, an old agreement in a status dipper can't mark Cancelling, such
as Unresponsive with its offer still open, got no on-chain cancel, so the indexer could accept it.
It now gets one if the chain shows it live, and its pending row stays for retry if that fails.
A stale agreement whose cancel failed was replaced only if the cancel retry ended it, so one the
chain listener ended first was never replaced. The agreement now records that a replacement is due,
and the cancel retry queues it once the agreement has ended, whatever ended it, and only once.
A replaced agreement that can't be marked cancelling had its cancel resent every sweep even when
the contract refused it or it mined without ending the agreement, costing gas each time with no
alert. Those now raise agreement_cancel_stuck once and stop; a failed read or send still retries.
@MoonBoi9001
MoonBoi9001 marked this pull request as ready for review October 8, 2026 20:44
That change cancelled a replaced Unresponsive agreement on-chain, assuming its offer could still
be open. An agreement is only marked Unresponsive when the gRPC proposal fails, and dipper puts an
offer on-chain only after the indexer accepts that proposal, so no such offer exists.
@MoonBoi9001
MoonBoi9001 added this pull request to stack #741 October 9, 2026 17:57
@MoonBoi9001
MoonBoi9001 removed this pull request from stack #741 October 9, 2026 17:58
@MoonBoi9001
MoonBoi9001 added this pull request to stack #742 October 9, 2026 17:58
@MoonBoi9001
MoonBoi9001 removed this pull request from stack #742 October 9, 2026 17:58
@MoonBoi9001
MoonBoi9001 added this pull request to stack #743 October 9, 2026 17:58
@MoonBoi9001
MoonBoi9001 merged commit 07583b1 into mb9/review Oct 9, 2026
12 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.

1 participant