@decentnetwork/peer 0.1.126 → 0.1.128
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/peer.js +40 -10
- package/package.json +1 -1
package/dist/peer.js
CHANGED
|
@@ -118,6 +118,10 @@ const FRIEND_CONNECTION_LOOP_MS = readEnvInt("DECENT_FRIEND_CONNECTION_LOOP_MS",
|
|
|
118
118
|
* enclosing 3s re-punch cadence), and the cheap one silently set the pace for
|
|
119
119
|
* the expensive one. Shared here so they cannot diverge again. */
|
|
120
120
|
const DHT_PK_ANNOUNCE_COOLDOWN_MS = readEnvInt("DECENT_DHT_PK_ANNOUNCE_COOLDOWN_MS", 25_000);
|
|
121
|
+
/** Ceiling on the endpoint-lookup interval for a friend that keeps failing to
|
|
122
|
+
* resolve. This IS the worst-case time to notice a peer coming back, so it
|
|
123
|
+
* stays small — the sweep itself remains full width. */
|
|
124
|
+
const ONION_LOOKUP_MAX_BACKOFF_MS = readEnvInt("DECENT_ONION_LOOKUP_MAX_BACKOFF_MS", 120_000);
|
|
121
125
|
const FRIEND_TIMEOUT_MS = readEnvInt("DECENT_FRIEND_TIMEOUT_MS", 32000);
|
|
122
126
|
// A session whose keys we've PROVEN (decrypted ≥1 real packet from the peer) is
|
|
123
127
|
// NOT torn down at FRIEND_TIMEOUT_MS. A transient all-transport blackout — e.g.
|
|
@@ -393,8 +397,9 @@ export class Peer {
|
|
|
393
397
|
* same friend, and sharing one timestamp would let whichever ran first
|
|
394
398
|
* suppress the other for a full budget. */
|
|
395
399
|
#onionLookupCooldown = new Map();
|
|
396
|
-
/** Consecutive failed endpoint lookups per (friend,target)
|
|
397
|
-
* the
|
|
400
|
+
/** Consecutive failed endpoint lookups per (friend,target). Kept for
|
|
401
|
+
* diagnostics — it no longer narrows the sweep (see the width comment in
|
|
402
|
+
* #discoverAndCacheFriendEndpoint for why that was reverted). */
|
|
398
403
|
#onionLookupMisses = new Map();
|
|
399
404
|
// Per-friend cooldown for re-asserting the TCP-relay route toward an
|
|
400
405
|
// unconnected friend (the "accepted friend that never connects" wedge —
|
|
@@ -3094,9 +3099,26 @@ export class Peer {
|
|
|
3094
3099
|
const budgetKey = `${friendId}:${targetId}`;
|
|
3095
3100
|
const lastLookup = this.#onionLookupCooldown.get(budgetKey) ?? 0;
|
|
3096
3101
|
const sinceLast = Date.now() - lastLookup;
|
|
3097
|
-
|
|
3102
|
+
// Back off in TIME, never in width.
|
|
3103
|
+
//
|
|
3104
|
+
// Width is what finds iOS peers — narrowing it lost them entirely once
|
|
3105
|
+
// already (see the width comment below). Interval is free to grow: a
|
|
3106
|
+
// friend that has failed to resolve twenty times running is not about to
|
|
3107
|
+
// resolve on the twenty-first attempt 25s later, and every one of those
|
|
3108
|
+
// sweeps costs 24 nodes x 2 round trips x 3 X25519 layers.
|
|
3109
|
+
//
|
|
3110
|
+
// Measured on cn (2 cores, 14 friends of which ~5 unreachable): the flat
|
|
3111
|
+
// 25s interval left the daemon at 21.7% of a core purely on lookups for
|
|
3112
|
+
// peers that were simply not there.
|
|
3113
|
+
//
|
|
3114
|
+
// The cap is deliberately small. A peer that comes back online is found by
|
|
3115
|
+
// the next sweep, so the cap IS the worst-case discovery delay — 2 minutes
|
|
3116
|
+
// at full width, against the 200s-at-quarter-width that broke iOS.
|
|
3117
|
+
const misses = this.#onionLookupMisses.get(budgetKey) ?? 0;
|
|
3118
|
+
const budget = Math.min(DHT_PK_ANNOUNCE_COOLDOWN_MS * Math.max(1, misses), ONION_LOOKUP_MAX_BACKOFF_MS);
|
|
3119
|
+
if (sinceLast < budget) {
|
|
3098
3120
|
this.#debugLog(`endpoint lookup for ${friendId} skipped: ${Math.round(sinceLast / 1000)}s since last ` +
|
|
3099
|
-
`(budget ${
|
|
3121
|
+
`(budget ${Math.round(budget / 1000)}s, misses ${misses})`);
|
|
3100
3122
|
return false;
|
|
3101
3123
|
}
|
|
3102
3124
|
this.#onionLookupCooldown.set(budgetKey, Date.now());
|
|
@@ -3114,9 +3136,18 @@ export class Peer {
|
|
|
3114
3136
|
// peer that only just came back is still found without waiting for a
|
|
3115
3137
|
// restart. Widening beats a permanently narrow sweep: the failure we must
|
|
3116
3138
|
// not introduce is "never discovers", not "discovers a bit later".
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3139
|
+
// Width stays FULL. An earlier cut narrowed repeats to 4 nodes and only
|
|
3140
|
+
// went wide every 8th attempt — with the 25s budget that put 200s between
|
|
3141
|
+
// full sweeps, and iOS peers (which come online in short windows and are
|
|
3142
|
+
// the hardest to find at the best of times) stopped being seen at all.
|
|
3143
|
+
// Reported from the field the same day: weili.beagles.eth went offline and
|
|
3144
|
+
// stayed offline.
|
|
3145
|
+
//
|
|
3146
|
+
// Cost here is width x frequency, and the frequency gate above already
|
|
3147
|
+
// took 3s -> 25s, an 8x cut on its own. Narrowing width bought another 6x
|
|
3148
|
+
// and paid for it with the one property this code exists to provide.
|
|
3149
|
+
// Keep the cheap half, drop the expensive one.
|
|
3150
|
+
const width = Math.max(8, Math.min(24, MAX_FRIEND_ROUTE_ATTEMPTS));
|
|
3120
3151
|
const queue = dedupeNodes(this.#knownNodes.length > 0 ? this.#knownNodes : this.#opts.bootstrapNodes)
|
|
3121
3152
|
.filter((n) => !this.#isNodeBlacklisted(`${n.host}:${n.port}`))
|
|
3122
3153
|
.sort((a, b) => this.#nodeScore(`${b.host}:${b.port}`) - this.#nodeScore(`${a.host}:${a.port}`))
|
|
@@ -3186,9 +3217,8 @@ export class Peer {
|
|
|
3186
3217
|
return true;
|
|
3187
3218
|
}
|
|
3188
3219
|
}
|
|
3189
|
-
// Nothing found:
|
|
3190
|
-
|
|
3191
|
-
this.#onionLookupMisses.set(budgetKey, misses + 1);
|
|
3220
|
+
// Nothing found: count it, for diagnostics only.
|
|
3221
|
+
this.#onionLookupMisses.set(budgetKey, (this.#onionLookupMisses.get(budgetKey) ?? 0) + 1);
|
|
3192
3222
|
return false;
|
|
3193
3223
|
}
|
|
3194
3224
|
async #announceSelfBestEffort(force = false, deadlineMs = Number.POSITIVE_INFINITY) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/peer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.128",
|
|
4
4
|
"description": "Pure TypeScript port of Elastos Carrier (toxcore-derived) P2P messaging. DHT, onion routing, TCP relay, FlatBuffers app payloads, Express offline relay. Wire-compatible with iOS Beagle and the Carrier C SDK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|