@decentnetwork/peer 0.1.44 → 0.1.46
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 +54 -3
- package/package.json +1 -1
package/dist/peer.js
CHANGED
|
@@ -2812,9 +2812,23 @@ export class Peer {
|
|
|
2812
2812
|
firstError = error;
|
|
2813
2813
|
}
|
|
2814
2814
|
}
|
|
2815
|
-
// Fresh direct path → send over UDP only
|
|
2816
|
-
//
|
|
2817
|
-
|
|
2815
|
+
// Fresh direct path → send over UDP only — but ONLY for bulk data.
|
|
2816
|
+
// Bulk is high-volume and must avoid relay fan-out / backlog, so once
|
|
2817
|
+
// the direct path is fresh it rides UDP exclusively.
|
|
2818
|
+
//
|
|
2819
|
+
// Low-volume traffic (chat 64 + control keepalives / endpoint offers /
|
|
2820
|
+
// profile) instead ALSO goes over the relay even when the direct path
|
|
2821
|
+
// looks fresh, because `udpFresh` is derived from INBOUND UDP
|
|
2822
|
+
// (lastUdpRecvMs) and inbound reachability does NOT imply outbound
|
|
2823
|
+
// reachability. On a symmetric / CGNAT peer (e.g. cellular T-Mobile
|
|
2824
|
+
// 172.56.x) the peer's pings keep arriving — so udpFresh stays true —
|
|
2825
|
+
// while our packets to the source port we observed are silently
|
|
2826
|
+
// black-holed: the peer never received from us on that port, so its NAT
|
|
2827
|
+
// has no inbound mapping for our endpoint. Returning UDP-only here would
|
|
2828
|
+
// fire chat into a dead endpoint forever — the exact "peer can send to us
|
|
2829
|
+
// but can't receive from us" one-way failure. net_crypto dedups by packet
|
|
2830
|
+
// number, so the extra relay copy is harmless for sparse chat / control.
|
|
2831
|
+
if (isBulkData && udpFresh && udpOk) {
|
|
2818
2832
|
return;
|
|
2819
2833
|
}
|
|
2820
2834
|
// Tier 2: TURN relay (tokyo) — a fast (~280ms) stable fallback that
|
|
@@ -3800,6 +3814,27 @@ export class Peer {
|
|
|
3800
3814
|
if (typeof this.#dhtMaintenanceTimer.unref === "function")
|
|
3801
3815
|
this.#dhtMaintenanceTimer.unref();
|
|
3802
3816
|
void this.#doDhtMaintenance().catch(() => undefined); // become findable right after join
|
|
3817
|
+
// Fast initial population. The steady 15s cadence converges far too
|
|
3818
|
+
// slowly from a cold table — a fresh peer sat at ~14 known nodes, which
|
|
3819
|
+
// is too sparse for the onion announce to store on the nodes truly
|
|
3820
|
+
// closest to our key (the ones native clients query when searching for
|
|
3821
|
+
// us). Run a few quick rounds up front to fill the table within seconds
|
|
3822
|
+
// so the announce can reach storing nodes and we become discoverable.
|
|
3823
|
+
for (const delay of [1200, 3000, 5500, 9000, 13000]) {
|
|
3824
|
+
const t = setTimeout(() => void this.#doDhtMaintenance().catch(() => undefined), delay);
|
|
3825
|
+
if (typeof t.unref === "function")
|
|
3826
|
+
t.unref();
|
|
3827
|
+
}
|
|
3828
|
+
// The join-time announce ran against a near-empty table, so it stored on
|
|
3829
|
+
// few/no nodes. Re-announce once the burst above has populated the table
|
|
3830
|
+
// (~10s) so our FIRST useful announce lands on the genuinely-closest
|
|
3831
|
+
// nodes — the difference between "discoverable within seconds" and "not
|
|
3832
|
+
// until the 20s steady-state timer happens to converge".
|
|
3833
|
+
for (const delay of [10000, 18000]) {
|
|
3834
|
+
const a = setTimeout(() => void this.#runSelfAnnounce(true, Date.now() + 8000).catch(() => undefined), delay);
|
|
3835
|
+
if (typeof a.unref === "function")
|
|
3836
|
+
a.unref();
|
|
3837
|
+
}
|
|
3803
3838
|
}
|
|
3804
3839
|
async #doDhtMaintenance() {
|
|
3805
3840
|
if (!this.#keyPair)
|
|
@@ -3810,6 +3845,22 @@ export class Peer {
|
|
|
3810
3845
|
for (const node of this.#closestKnownNodes(selfPk, 8)) {
|
|
3811
3846
|
void this.#sendDhtGetNodes(node, selfPk);
|
|
3812
3847
|
}
|
|
3848
|
+
// 1b. Fill the routing table ACROSS the keyspace via random-target
|
|
3849
|
+
// searches. toxcore keeps random DHT search slots so the table isn't
|
|
3850
|
+
// clustered only near self; without this a JS peer's table stayed tiny
|
|
3851
|
+
// (~14-97 nodes) and the onion announce could only store on a sparse,
|
|
3852
|
+
// far-from-closest subset that native searchers never query — so they
|
|
3853
|
+
// couldn't discover the JS peer by address. A fuller table lets the
|
|
3854
|
+
// announce reach the genuinely-closest nodes. Search harder while the
|
|
3855
|
+
// table is small, then taper to a steady refresh.
|
|
3856
|
+
const small = this.#knownNodes.length < 150;
|
|
3857
|
+
const randomSearches = this.#knownNodes.length < 60 ? 6 : small ? 4 : 2;
|
|
3858
|
+
for (let i = 0; i < randomSearches; i++) {
|
|
3859
|
+
const target = randomBytes(32);
|
|
3860
|
+
for (const node of this.#closestKnownNodes(target, small ? 6 : 4)) {
|
|
3861
|
+
void this.#sendDhtGetNodes(node, target);
|
|
3862
|
+
}
|
|
3863
|
+
}
|
|
3813
3864
|
// 2. For each friend not on a confirmed UDP path, get_nodes toward THEIR
|
|
3814
3865
|
// DHT key → learn their UDP endpoint → punch from our side.
|
|
3815
3866
|
for (const [, session] of this.#friendSessions.entries()) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/peer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.46",
|
|
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",
|