Skip to content

forge: mirror backoff resets on a relay's answer, not on open - #14

Merged
melvincarvalho merged 1 commit into
gh-pagesfrom
mirror-backoff
Oct 19, 2026
Merged

melvincarvalho merged 1 commit into
gh-pagesfrom
mirror-backoff

Conversation

@melvincarvalho

Copy link
Copy Markdown
Contributor

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 REQ with EOSE or an EVENT, so a connection counts once it has worked, and a relay that drops on sight backs off to 60 s like one that refuses. CLOSED and NOTICE messages, 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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 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 attempt counter on socket open; reset it only when the relay answers the REQ with EOSE or EVENT.
  • Short-circuit non-array messages and log CLOSED/NOTICE responses 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

@melvincarvalho
melvincarvalho merged commit 63a16cb into gh-pages Oct 19, 2026
2 checks passed
@melvincarvalho
melvincarvalho deleted the mirror-backoff branch October 19, 2026 15:32
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