Skip to content

Approve: register the trust pair before answering, and retry the answer - #53

Merged
TeoSlayer merged 2 commits into
mainfrom
fix/approve-answer-order
Oct 28, 2026
Merged

TeoSlayer merged 2 commits into
mainfrom
fix/approve-answer-order

Conversation

@TeoSlayer

Copy link
Copy Markdown
Contributor

Why

Approving a friend request told the registry about the trust pair and sent the answer at the same moment, once each, discarding every error:

  • a private requester can't be looked up until the registry has the pair, so the direct accept usually failed;
  • the relayed answer needs the registry's in-memory record of the request (lost on a registry restart).

When both copies were lost, the approver trusted the requester one-way (and, for a relayed request, with no key) while the requester still waited and kept its messages queued. On the hosted fleet, five pairs were stuck like this, some for three weeks (repaired by hand on 2026-10-28; the hosted node now also re-sends its request when a message arrives from someone it asked).

What

ApproveHandshake now, in the background:

  1. reports the trust pair to the registry (retried);
  2. for a relayed request (no key), takes the requester's key from the registry (backfillPeerKey);
  3. answers through the relay (retried; "no pending" is final), then directly;
  4. warns when the answer reached neither.

retryRPC: three tries, a second then two apart, stops early when the manager is stopping.

Tests

  • New TestApproveRegistersThePairBeforeAnsweringAndRetries: order is report → key lookup → relay answer (first one dropped, retried) → direct accept, and the key is filled in.
  • go test ./... passes.

Not in this PR (separate, if wanted): the registry keeping pending requests across restarts (rendezvous handshake shard snapshot), and the daemon re-sending its request when a connection from a peer it asked is admitted only on the registry's word.

🤖 Generated with Claude Code

Teo Calin and others added 2 commits October 28, 2026 14:55
Approving a request told the registry about the new trust pair and sent the
answer in parallel, once each, discarding every error. A private requester
can't be looked up until the registry has the pair, so the direct accept
usually failed; the relayed answer needs the registry's in-memory record of
the request. When both copies were lost, the approver trusted the requester
(one-way, with no key for a relayed request) while the requester still
waited, and kept its messages queued: five hosted pairs had been stuck like
this for up to three weeks.

Now the pair is registered first, a relayed request's key is taken from the
registry (backfillPeerKey), and the relayed and direct answers follow, each
registry call retried (three tries, unless stopping; "no pending" is final),
with a warning when the answer reached neither.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TestOutgoing_CancelledRequestIsForgottenAcrossRestart never stopped the
manager it restarts from, so its background save could write trust.json
while the temp dir was being removed ("directory not empty"); it failed
30 of 30 runs under -race on main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@TeoSlayer
TeoSlayer merged commit 562c35f into main Oct 28, 2026
3 checks passed
@TeoSlayer
TeoSlayer deleted the fix/approve-answer-order branch October 28, 2026 22:03
@codecov

codecov Bot commented Oct 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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