pair_spire: retry create_new_key (and other bunker admin RPCs) on transient timeout #38
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
pair_spiremakes a chain of nsecbunkerd admin RPCs over NIP-46:create_new_key→ensure_policy/get_policies→create_new_token→get_key_tokens. When the bunker is briefly slow/overloaded, any of these can time out and surface as aPairingError→ 502, failing the whole pairing.PR #37 added a retry for
get_key_tokens(the empty-list race aftercreate_new_token). This follow-up is to extend that resilience to the RPCs that can time out — first and foremostcreate_new_key.Observed (bitspire-#70 session, regtest)
Two distinct transient bunker failures during on-hardware pairing testing:
bunker returned no tokens after create_new_token—get_key_tokensraced empty; the identical call ~25s later succeeded. Fixed in #37 (_get_key_tokens_with_retry, 5× / 0.4s backoff).bunker admin RPC failed during pairing: no response for 'create_new_key' within 15.0s—create_new_keytimed out; a plain retry of the mint immediately succeeded. Not yet handled.Both correlate with the nsecbunkerd being momentarily unresponsive (also seen as
no NIP-46 response for 'nip44_decrypt' within 15.0sin the logs around the same time).Proposal
Wrap the transient-timeout-prone bunker admin calls in
pair_spirewith a small retry/backoff, so a sluggish bunker doesn't fail an otherwise-valid pairing. At minimumcreate_new_key; considercreate_new_tokentoo.NsecBunkerErrorwhose message matches the timeout shape (no response for '<method>' within Ns) is transient → retry with backoff (mirror theget_key_tokenshelper: a few attempts, ~0.4s backoff).NsecBunkerNotConfiguredError, or a non-timeoutNsecBunkerError(rejection / bad policy), is terminal → fail fast as today.create_new_keyis replace-by-name on the bunker side, so re-issuing on a timeout is safe.A single small helper (e.g.
_bunker_call_with_retry(coro_factory, *, transient_re=...)) reused across the admin calls would keep it tidy, or a decorator on the RPC wrappers.Out of scope / note
The underlying nsecbunkerd slowness in regtest may be load from heavy test-session churn; this is about making pairing tolerate a slow bunker, not fixing the bunker itself. If the timeouts show up in production under normal load, that's a separate nsecbunkerd perf issue.
Code refs
pairing.py—pair_spire(the admin RPC chain),_get_key_tokens_with_retry(the existing pattern to generalize).Related: bitspire-#70, PR #37.
Fix implemented in PR #37 (commit
2b90590). Rather than aget_key_tokens-only helper, generalised to_bunker_retry, which now wraps every admin RPC in thepair_spirechain (create_new_key,ensure_policy,create_new_token,get_key_tokens):NsecBunkerTimeoutError(theno response for '<method>' within Nscase) → transient, retried with backoff.retry_empty=True).NsecBunkerRpcError(real rejection) /NsecBunkerNotConfiguredError→ terminal, fail fast.create_new_keyis replace-by-name andensure_policyreconciles idempotently, so re-issuing on a timeout is safe. Addedtest_create_new_key_retries_past_transient_timeout+test_bunker_rejection_fails_fast_without_retry(229 tests pass).Confirmed reproduction that motivated the broadened scope: on aio-demo,
create_new_keyandget_key_tokensboth 15s-timed-out (502), and a manual retry succeeded — exactly what this now auto-recovers.Leaving open until PR #37 merges and the fix reaches the deployed instance (per the deploy-not-commit close convention).