Skip to content

fix(broadcast): survive the Credible RPC alignment window - #124

Merged
lean-apple merged 11 commits into
mainfrom
fix/credible-rpc-alignment-window
Aug 27, 2026
Merged

fix(broadcast): survive the Credible RPC alignment window#124
lean-apple merged 11 commits into
mainfrom
fix/credible-rpc-alignment-window

Conversation

@lean-apple

@lean-apple lean-apple commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

An endpoint can briefly answer assertions are unavailable while a credible layer's assertion state catches up with the chain. This makes PCL wait through that window without ever risking a second transaction on the same nonce.

How the retry is safe

  • PCL fills and signs the transaction once, then resubmits those exact bytes on every attempt. Same hash, same nonce, so a node that already holds it deduplicates the retry rather than accepting a second transaction.
  • An already known answer counts as submitted — otherwise a send that succeeded but whose response was lost would turn into a spurious failure.
  • Gas estimation is retried too, before anything is signed. Assertion rejections are reverts and stay terminal.
  • Anything else fails on the spot.

Scaled to the endpoint

--with-credible-rpc (or PCL_WITH_CREDIBLE_RPC) says which kind of endpoint is being broadcast to:

Endpoint Attempts Wording
--with-credible-rpc 6, ~6s per step Credible layer is realigning while submitting…
plain 3 Endpoint is unavailable while submitting…

The flag scales how long to wait, not whether to retry. A plain endpoint can produce the same refusal — behind a proxy, or a URL the operator did not realise fronts a Credible RPC — so gating the retry on the flag would turn a recoverable blip into a hard failure when the flag is wrong. The two are indistinguishable from the URL alone, so the kind is stated rather than probed.

Errors

If the window outlasts the retries, the error says whether anything was submitted:

  • onchain.assertions_unavailable — nothing was signed or submitted, the nonce is unchanged, re-run the command.
  • onchain.tx_submission_unconfirmed — carries the signed hash; check it before re-running, since a rebuilt transaction would reuse the nonce.

Resolves ENG-4467

@linear-code

linear-code Bot commented Aug 13, 2026

Copy link
Copy Markdown

ENG-4467

@lean-apple
lean-apple force-pushed the fix/credible-rpc-alignment-window branch from 4482d57 to ad5a569 Compare August 26, 2026 19:50
@lean-apple
lean-apple marked this pull request as ready for review August 26, 2026 20:02
RUSTSEC-2026-0258: an h2 peer can hold a connection open with unbounded
empty DATA frames. Reached transitively through every HTTP client here.

Pinned to the version alone: letting cargo re-resolve moved a dozen
unrelated windows-sys selections that h2 does not need.
An endpoint can briefly answer `assertions are unavailable` while a credible
layer's assertion state catches up with the chain, which failed the command.

PCL now fills and signs once, then resubmits those exact bytes: same hash and
nonce, so a node already holding the transaction deduplicates the retry instead
of accepting a second one. An "already known" answer counts as submitted, since
a send whose response was lost would otherwise fail spuriously. Gas estimation
is retried too, before anything is signed; assertion rejections are reverts and
stay terminal.

Exhausting the retries says whether anything is in flight: before signing the
nonce is untouched and the command can be re-run, after signing the error
carries the hash to check first.
An `assertions are unavailable` refusal is worth retrying wherever it comes
from, but only a Credible RPC has an alignment window long enough to wait out.

`--with-credible-rpc` says which kind of endpoint is being broadcast to: set, a
refusal gets the full window (6 attempts over ~6s per step); unset, it gets a
short retry (3 attempts) and the wording drops the credible-layer reference.

The two are indistinguishable from the URL alone, so the kind is stated rather
than probed.
@lean-apple
lean-apple force-pushed the fix/credible-rpc-alignment-window branch from c5bc610 to 1ba6482 Compare August 26, 2026 20:18
One line each for the attempt budgets and the two delays: what the value is for, not how the loop uses it.
`PreparedTx` cached the hash and the encoded bytes; both come off the
envelope the wallet returns, so the envelope is the one thing to carry.
The recommended fillers use a caching nonce manager, which increments its
cached value on every fill after the first. A gas estimate refused inside
the alignment window therefore signed the retry with the next nonce, and
the transaction sat pending behind the gap it had skipped.

The nonce is now resolved once and set on the request, which the filler
treats as finished and never looks up. pcl broadcasts sequentially, so
one reading covers the whole window.
@lean-apple
lean-apple force-pushed the fix/credible-rpc-alignment-window branch from f39b164 to 3e845ff Compare August 26, 2026 20:42
Comment thread crates/pcl/core/src/api/error.rs Outdated
Comment thread crates/pcl/core/src/onchain.rs Outdated
Comment thread crates/pcl/core/src/onchain.rs
@lean-apple
lean-apple requested a review from mateo-mro August 27, 2026 09:21
Comment thread crates/pcl/core/src/onchain.rs
Comment thread crates/pcl/core/src/onchain.rs
@lean-apple
lean-apple enabled auto-merge (squash) August 27, 2026 10:51
@lean-apple
lean-apple requested a review from mateo-mro August 27, 2026 12:12
@lean-apple
lean-apple merged commit 8413417 into main Aug 27, 2026
13 checks passed
@lean-apple
lean-apple deleted the fix/credible-rpc-alignment-window branch August 27, 2026 12:56
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