Repository navigation
forge: mirror backoff resets on a relay's answer, not on open - #14
Conversation
…; CLOSED and NOTICE are logged
There was a problem hiding this comment.
🟢 Approval recommended
The change is small and self-contained, the attempt closure/reset semantics and Nostr message handling are correct, and the existing mirror test already exercises the EVENT/EOSE message path.
No open issues 🎉
What changed in this PR
This PR fixes a reconnection-backoff bug in the forge plugin's Nostr relay mirror. Previously, the reconnect attempt counter was reset to 0 in the socket's open handler, so a relay that accepted a connection and then immediately dropped it (e.g. an address relay.damus.io had rate-limited) would be reconnected to roughly once per second indefinitely, worsening the rate-limiting. The fix moves the reset into the message handler so the counter only resets once the relay actually answers the REQ with EOSE or an EVENT; a relay that drops on sight now backs off up to 60 s just like one that refuses the connection. Additionally, CLOSED/NOTICE messages (how a relay reports why it rejected a filter) are now logged rather than silently ignored.
Changes:
- Stop resetting the reconnect
attemptcounter on socketopen; reset it only when the relay answers theREQwithEOSEorEVENT. - Short-circuit non-array messages and log
CLOSED/NOTICEresponses at warn level.
| File | Description |
|---|---|
| forge/plugin.js | Reworks mirrorConnect's message handling so backoff only resets on a successful relay answer, and surfaces CLOSED/NOTICE rejections in the log. |
Review effort: Balanced
Found while giving the swap pool the same subscription shape (blocktrails/fund-agent#20). The mirror reset its reconnect attempt counter on
open, so a relay that accepts the socket and then drops it, which relay.damus.io did today for an address it has rate-limited, would be reconnected to every second for as long as it kept doing that. That is how an address gets rate-limited further.Now the counter resets only when the relay answers the
REQwithEOSEor anEVENT, so a connection counts once it has worked, and a relay that drops on sight backs off to 60 s like one that refuses.CLOSEDandNOTICEmessages, which are how a relay says why it rejected the filter, are logged rather than ignored.149 tests pass; no new test, since the in-process relay in the suite answers every REQ and the change is to the retry path only.