aboutsummaryrefslogtreecommitdiffstats
path: root/names
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-07 11:54:05 -0700
committerAdam Soltys <[email protected]>2026-10-07 11:54:05 -0700
commitb415b1fb31bd734619e1da3c88ca7e3822151c87 (patch)
tree2c984450318158613e8bd4a74aa3156a4c13dc75 /names
parent5b6cdd95a3769ba897ae845590c7cbff0096e532 (diff)
downloadcoinosv3-b415b1fb31bd734619e1da3c88ca7e3822151c87.tar.gz
coinosv3-b415b1fb31bd734619e1da3c88ca7e3822151c87.zip
names: a welcome DM counts as sent only when a relay acknowledges it — dead sockets are dropped and it retries on fresh ones (four welcomes on 2026-10-07 vanished after the uplink dropped while the log said sent)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'names')
-rw-r--r--names/server.js26
1 files changed, 24 insertions, 2 deletions
diff --git a/names/server.js b/names/server.js
index e17ca05..a40cff6 100644
--- a/names/server.js
+++ b/names/server.js
@@ -178,13 +178,35 @@ async function sendWelcome(pubkey, linkedKeys = []) {
// clients with an endless stream of his own welcome message.
const [, toPeer] = wrapManyEvents(WELCOME.sk, [{ publicKey: pubkey }], WELCOME.message);
const inbox = await inboxRelaysOf(pubkey);
- await Promise.allSettled(pool.publish([...new Set([...inbox, ...LNURL_RELAYS])], toPeer));
- log(`welcome DM sent to ${pubkey.slice(0, 12)}`);
+ const relays = [...new Set([...inbox, ...LNURL_RELAYS])];
+ // Count acknowledgements, not attempts: a socket that died under the
+ // pool (the home uplink drops every connection at once) swallows a
+ // publish without a word, and four welcomes on 2026-10-07 went nowhere
+ // while the log said "sent". Nobody heard it → drop those sockets and
+ // try again on fresh ones, then say what really happened.
+ let acked = await publishAcked(relays, toPeer);
+ for (let i = 1; !acked.length && i <= 3; i++) {
+ try { pool.close(relays); } catch {}
+ await new Promise((r) => setTimeout(r, 5000 * i));
+ acked = await publishAcked(relays, toPeer);
+ }
+ if (acked.length) log(`welcome DM sent to ${pubkey.slice(0, 12)} (${acked.join(', ')})`);
+ else {
+ for (const k of keys) delete state.welcomed[k]; persist(); // undelivered: the next claim may try again
+ log(`welcome DM to ${pubkey.slice(0, 12)} FAILED: no relay accepted it`);
+ }
} catch (e) {
log('welcome DM failed: ' + e.message);
}
}
+// Publish and return the relays that answered OK within the time limit.
+async function publishAcked(relays, ev, ms = 10000) {
+ const timeout = new Promise((_, j) => setTimeout(() => j(new Error('timeout')), ms));
+ const res = await Promise.allSettled(pool.publish(relays, ev).map((p) => Promise.race([p, timeout])));
+ return relays.filter((_, i) => res[i].status === 'fulfilled').map((r) => r.replace(/^wss:\/\//, ''));
+}
+
const lnurlMeta = (address) => JSON.stringify([
['text/plain', `Paying ${address}`],
['text/identifier', address],