@hashtree/nostr 0.1.1 → 0.1.4
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/README.md +87 -0
- package/dist/events.d.ts +66 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +426 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/resolver/nostr.d.ts +2 -0
- package/dist/resolver/nostr.d.ts.map +1 -1
- package/dist/resolver/nostr.js +122 -31
- package/dist/resolver/nostr.js.map +1 -1
- package/dist/snapshot.d.ts +20 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +147 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/webrtc/index.d.ts +3 -2
- package/dist/webrtc/index.d.ts.map +1 -1
- package/dist/webrtc/index.js +3 -2
- package/dist/webrtc/index.js.map +1 -1
- package/dist/webrtc/peer.d.ts +12 -1
- package/dist/webrtc/peer.d.ts.map +1 -1
- package/dist/webrtc/peer.js +39 -5
- package/dist/webrtc/peer.js.map +1 -1
- package/dist/webrtc/peerSelector.d.ts +31 -0
- package/dist/webrtc/peerSelector.d.ts.map +1 -0
- package/dist/webrtc/peerSelector.js +348 -0
- package/dist/webrtc/peerSelector.js.map +1 -0
- package/dist/webrtc/protocol.d.ts +15 -4
- package/dist/webrtc/protocol.d.ts.map +1 -1
- package/dist/webrtc/protocol.js +31 -17
- package/dist/webrtc/protocol.js.map +1 -1
- package/dist/webrtc/store.d.ts +31 -4
- package/dist/webrtc/store.d.ts.map +1 -1
- package/dist/webrtc/store.js +362 -99
- package/dist/webrtc/store.js.map +1 -1
- package/dist/webrtc/types.d.ts +66 -4
- package/dist/webrtc/types.d.ts.map +1 -1
- package/dist/webrtc/types.js +71 -9
- package/dist/webrtc/types.js.map +1 -1
- package/package.json +12 -3
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import { PEER_METADATA_SNAPSHOT_VERSION, } from './types.js';
|
|
2
|
+
const FAIRNESS_SELECTION_SHARE_WARNING = 0.30;
|
|
3
|
+
const FAIRNESS_MIN_PEERS = 5;
|
|
4
|
+
const INITIAL_BACKOFF_MS = 1000;
|
|
5
|
+
const BACKOFF_MULTIPLIER = 2;
|
|
6
|
+
const MAX_BACKOFF_MS = 480_000;
|
|
7
|
+
const MIN_RTO_MS = 50;
|
|
8
|
+
const MAX_RTO_MS = 60_000;
|
|
9
|
+
const INITIAL_RTO_MS = 1000;
|
|
10
|
+
function clamp01(n) {
|
|
11
|
+
return Math.max(0, Math.min(1, n));
|
|
12
|
+
}
|
|
13
|
+
function clampRtoMs(rtoMs) {
|
|
14
|
+
if (!Number.isFinite(rtoMs) || rtoMs <= 0)
|
|
15
|
+
return INITIAL_RTO_MS;
|
|
16
|
+
return Math.max(MIN_RTO_MS, Math.min(MAX_RTO_MS, Math.floor(rtoMs)));
|
|
17
|
+
}
|
|
18
|
+
function sanitizeLatency(value) {
|
|
19
|
+
if (!Number.isFinite(value) || value < 0)
|
|
20
|
+
return 0;
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
function defaultStats(peerId) {
|
|
24
|
+
return {
|
|
25
|
+
peerId,
|
|
26
|
+
connectedAtMs: Date.now(),
|
|
27
|
+
requestsSent: 0,
|
|
28
|
+
successes: 0,
|
|
29
|
+
timeouts: 0,
|
|
30
|
+
failures: 0,
|
|
31
|
+
srttMs: 0,
|
|
32
|
+
rttvarMs: 0,
|
|
33
|
+
rtoMs: INITIAL_RTO_MS,
|
|
34
|
+
consecutiveRtoBackoffs: 0,
|
|
35
|
+
backoffLevel: 0,
|
|
36
|
+
bytesReceived: 0,
|
|
37
|
+
bytesSent: 0,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function successRate(stats) {
|
|
41
|
+
if (stats.requestsSent === 0)
|
|
42
|
+
return 0.5;
|
|
43
|
+
return stats.successes / stats.requestsSent;
|
|
44
|
+
}
|
|
45
|
+
function isBackedOff(stats) {
|
|
46
|
+
return Boolean(stats.backedOffUntilMs && Date.now() < stats.backedOffUntilMs);
|
|
47
|
+
}
|
|
48
|
+
function scoreWeighted(stats) {
|
|
49
|
+
const reliability = successRate(stats);
|
|
50
|
+
const latencyScore = stats.srttMs > 0 ? Math.min(1, 500 / (stats.srttMs + 50)) : 0.5;
|
|
51
|
+
const recencyBonus = stats.lastSuccessMs && Date.now() - stats.lastSuccessMs < 60_000 ? 0.1 : 0;
|
|
52
|
+
return 0.6 * reliability + 0.3 * latencyScore + 0.1 * (1 + recencyBonus);
|
|
53
|
+
}
|
|
54
|
+
function scoreUtilityUcb(stats, totalRequests) {
|
|
55
|
+
const good = stats.successes + 1;
|
|
56
|
+
const bad = stats.failures + stats.timeouts + 1;
|
|
57
|
+
const ratio = good / bad;
|
|
58
|
+
const ratioScore = ratio / (1 + ratio);
|
|
59
|
+
const latencyScore = stats.srttMs > 0 ? Math.min(1, 300 / (stats.srttMs + 50)) : 0.5;
|
|
60
|
+
const efficiencyScore = stats.bytesSent > 0 ? Math.min(1, stats.bytesReceived / stats.bytesSent) : 0.5;
|
|
61
|
+
const exploitation = 0.55 * ratioScore + 0.25 * latencyScore + 0.2 * efficiencyScore;
|
|
62
|
+
const uncertainty = Math.sqrt(Math.log(totalRequests + 1) / (stats.requestsSent + 1));
|
|
63
|
+
return exploitation + 0.2 * uncertainty;
|
|
64
|
+
}
|
|
65
|
+
function scoreTitForTat(stats, totalRequests) {
|
|
66
|
+
const reliability = (stats.successes + 1) / (stats.requestsSent + 2);
|
|
67
|
+
const reciprocity = stats.bytesSent > 0 ? Math.min(1, stats.bytesReceived / stats.bytesSent) : 0.5;
|
|
68
|
+
const retaliation = (stats.timeouts + stats.failures) / Math.max(1, stats.requestsSent);
|
|
69
|
+
const latencyScore = stats.srttMs > 0 ? Math.min(1, 350 / (stats.srttMs + 50)) : 0.5;
|
|
70
|
+
const exploration = Math.sqrt(Math.log(totalRequests + 1) / (stats.requestsSent + 1));
|
|
71
|
+
return 0.45 * reliability + 0.25 * reciprocity + 0.2 * latencyScore - 0.25 * retaliation + 0.1 * exploration;
|
|
72
|
+
}
|
|
73
|
+
function peerMetadataFromStats(principal, stats) {
|
|
74
|
+
return {
|
|
75
|
+
principal,
|
|
76
|
+
requestsSent: stats.requestsSent,
|
|
77
|
+
successes: stats.successes,
|
|
78
|
+
timeouts: stats.timeouts,
|
|
79
|
+
failures: stats.failures,
|
|
80
|
+
srttMs: sanitizeLatency(stats.srttMs),
|
|
81
|
+
rttvarMs: sanitizeLatency(stats.rttvarMs),
|
|
82
|
+
rtoMs: clampRtoMs(stats.rtoMs),
|
|
83
|
+
bytesReceived: stats.bytesReceived,
|
|
84
|
+
bytesSent: stats.bytesSent,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function applyMetadata(stats, metadata) {
|
|
88
|
+
stats.requestsSent = Math.max(0, Math.floor(metadata.requestsSent));
|
|
89
|
+
stats.successes = Math.max(0, Math.floor(metadata.successes));
|
|
90
|
+
stats.timeouts = Math.max(0, Math.floor(metadata.timeouts));
|
|
91
|
+
stats.failures = Math.max(0, Math.floor(metadata.failures));
|
|
92
|
+
stats.srttMs = sanitizeLatency(metadata.srttMs);
|
|
93
|
+
stats.rttvarMs = sanitizeLatency(metadata.rttvarMs);
|
|
94
|
+
stats.rtoMs = clampRtoMs(metadata.rtoMs);
|
|
95
|
+
stats.bytesReceived = Math.max(0, Math.floor(metadata.bytesReceived));
|
|
96
|
+
stats.bytesSent = Math.max(0, Math.floor(metadata.bytesSent));
|
|
97
|
+
stats.backoffLevel = 0;
|
|
98
|
+
stats.backedOffUntilMs = undefined;
|
|
99
|
+
stats.lastSuccessMs = undefined;
|
|
100
|
+
stats.lastFailureMs = undefined;
|
|
101
|
+
stats.consecutiveRtoBackoffs = 0;
|
|
102
|
+
}
|
|
103
|
+
function totalRequests(stats) {
|
|
104
|
+
let total = 0;
|
|
105
|
+
for (const s of stats)
|
|
106
|
+
total += s.requestsSent;
|
|
107
|
+
return total;
|
|
108
|
+
}
|
|
109
|
+
export function peerPrincipal(peerId) {
|
|
110
|
+
return peerId;
|
|
111
|
+
}
|
|
112
|
+
export class PeerSelector {
|
|
113
|
+
stats = new Map();
|
|
114
|
+
persistedMetadata = new Map();
|
|
115
|
+
strategy;
|
|
116
|
+
fairnessEnabled = true;
|
|
117
|
+
roundRobinIdx = 0;
|
|
118
|
+
constructor(strategy = 'weighted') {
|
|
119
|
+
this.strategy = strategy;
|
|
120
|
+
}
|
|
121
|
+
static withStrategy(strategy) {
|
|
122
|
+
return new PeerSelector(strategy);
|
|
123
|
+
}
|
|
124
|
+
setFairness(enabled) {
|
|
125
|
+
this.fairnessEnabled = enabled;
|
|
126
|
+
}
|
|
127
|
+
setStrategy(strategy) {
|
|
128
|
+
this.strategy = strategy;
|
|
129
|
+
}
|
|
130
|
+
getPeerIds() {
|
|
131
|
+
return Array.from(this.stats.keys());
|
|
132
|
+
}
|
|
133
|
+
addPeer(peerId) {
|
|
134
|
+
if (this.stats.has(peerId))
|
|
135
|
+
return;
|
|
136
|
+
const stats = defaultStats(peerId);
|
|
137
|
+
const persisted = this.persistedMetadata.get(peerPrincipal(peerId));
|
|
138
|
+
if (persisted)
|
|
139
|
+
applyMetadata(stats, persisted);
|
|
140
|
+
this.stats.set(peerId, stats);
|
|
141
|
+
}
|
|
142
|
+
removePeer(peerId) {
|
|
143
|
+
const stats = this.stats.get(peerId);
|
|
144
|
+
if (!stats)
|
|
145
|
+
return;
|
|
146
|
+
const principal = peerPrincipal(peerId);
|
|
147
|
+
this.persistedMetadata.set(principal, peerMetadataFromStats(principal, stats));
|
|
148
|
+
this.stats.delete(peerId);
|
|
149
|
+
}
|
|
150
|
+
recordRequest(peerId, bytes) {
|
|
151
|
+
const stats = this.stats.get(peerId);
|
|
152
|
+
if (!stats)
|
|
153
|
+
return;
|
|
154
|
+
stats.requestsSent += 1;
|
|
155
|
+
stats.bytesSent += Math.max(0, Math.floor(bytes));
|
|
156
|
+
}
|
|
157
|
+
recordSuccess(peerId, rttMs, bytes) {
|
|
158
|
+
const stats = this.stats.get(peerId);
|
|
159
|
+
if (!stats)
|
|
160
|
+
return;
|
|
161
|
+
const now = Date.now();
|
|
162
|
+
stats.successes += 1;
|
|
163
|
+
stats.bytesReceived += Math.max(0, Math.floor(bytes));
|
|
164
|
+
stats.lastSuccessMs = now;
|
|
165
|
+
stats.consecutiveRtoBackoffs = 0;
|
|
166
|
+
stats.backoffLevel = 0;
|
|
167
|
+
stats.backedOffUntilMs = undefined;
|
|
168
|
+
const rtt = Math.max(0, rttMs);
|
|
169
|
+
if (stats.srttMs === 0) {
|
|
170
|
+
stats.srttMs = rtt;
|
|
171
|
+
stats.rttvarMs = rtt / 2;
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
stats.rttvarMs = 0.75 * stats.rttvarMs + 0.25 * Math.abs(stats.srttMs - rtt);
|
|
175
|
+
stats.srttMs = 0.875 * stats.srttMs + 0.125 * rtt;
|
|
176
|
+
}
|
|
177
|
+
const rto = stats.srttMs + Math.max(20, 4 * stats.rttvarMs);
|
|
178
|
+
stats.rtoMs = clampRtoMs(rto);
|
|
179
|
+
}
|
|
180
|
+
recordTimeout(peerId) {
|
|
181
|
+
const stats = this.stats.get(peerId);
|
|
182
|
+
if (!stats)
|
|
183
|
+
return;
|
|
184
|
+
const now = Date.now();
|
|
185
|
+
stats.timeouts += 1;
|
|
186
|
+
stats.lastFailureMs = now;
|
|
187
|
+
stats.backoffLevel += 1;
|
|
188
|
+
const backoffMs = Math.min(MAX_BACKOFF_MS, INITIAL_BACKOFF_MS * BACKOFF_MULTIPLIER ** (stats.backoffLevel - 1));
|
|
189
|
+
stats.backedOffUntilMs = now + backoffMs;
|
|
190
|
+
if (stats.consecutiveRtoBackoffs < 5) {
|
|
191
|
+
stats.rtoMs = Math.min(MAX_RTO_MS, stats.rtoMs * 2);
|
|
192
|
+
stats.consecutiveRtoBackoffs += 1;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
recordFailure(peerId) {
|
|
196
|
+
const stats = this.stats.get(peerId);
|
|
197
|
+
if (!stats)
|
|
198
|
+
return;
|
|
199
|
+
const now = Date.now();
|
|
200
|
+
stats.failures += 1;
|
|
201
|
+
stats.lastFailureMs = now;
|
|
202
|
+
stats.backoffLevel += 1;
|
|
203
|
+
const backoffMs = Math.min(MAX_BACKOFF_MS, INITIAL_BACKOFF_MS * BACKOFF_MULTIPLIER ** (stats.backoffLevel - 1));
|
|
204
|
+
stats.backedOffUntilMs = now + backoffMs;
|
|
205
|
+
}
|
|
206
|
+
selectPeers() {
|
|
207
|
+
const allStats = Array.from(this.stats.values());
|
|
208
|
+
if (allStats.length === 0)
|
|
209
|
+
return [];
|
|
210
|
+
const ready = allStats.filter((s) => !isBackedOff(s));
|
|
211
|
+
const backedOff = allStats.filter((s) => isBackedOff(s));
|
|
212
|
+
const total = totalRequests(allStats);
|
|
213
|
+
let orderedReady = this.order(ready, total);
|
|
214
|
+
if (this.fairnessEnabled && orderedReady.length >= FAIRNESS_MIN_PEERS) {
|
|
215
|
+
orderedReady = this.applyFairness(orderedReady);
|
|
216
|
+
}
|
|
217
|
+
const orderedBackedOff = this.order(backedOff, total);
|
|
218
|
+
return orderedReady.concat(orderedBackedOff).map((s) => s.peerId);
|
|
219
|
+
}
|
|
220
|
+
exportPeerMetadataSnapshot() {
|
|
221
|
+
const snapshot = new Map(this.persistedMetadata);
|
|
222
|
+
for (const [peerId, stats] of this.stats.entries()) {
|
|
223
|
+
const principal = peerPrincipal(peerId);
|
|
224
|
+
snapshot.set(principal, peerMetadataFromStats(principal, stats));
|
|
225
|
+
}
|
|
226
|
+
const peers = Array.from(snapshot.values()).sort((a, b) => a.principal.localeCompare(b.principal));
|
|
227
|
+
return {
|
|
228
|
+
version: PEER_METADATA_SNAPSHOT_VERSION,
|
|
229
|
+
peers,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
importPeerMetadataSnapshot(snapshot) {
|
|
233
|
+
if (!snapshot || snapshot.version !== PEER_METADATA_SNAPSHOT_VERSION)
|
|
234
|
+
return;
|
|
235
|
+
this.persistedMetadata.clear();
|
|
236
|
+
for (const peer of snapshot.peers ?? []) {
|
|
237
|
+
if (!peer?.principal)
|
|
238
|
+
continue;
|
|
239
|
+
this.persistedMetadata.set(peer.principal, {
|
|
240
|
+
principal: peer.principal,
|
|
241
|
+
requestsSent: Math.max(0, Math.floor(peer.requestsSent)),
|
|
242
|
+
successes: Math.max(0, Math.floor(peer.successes)),
|
|
243
|
+
timeouts: Math.max(0, Math.floor(peer.timeouts)),
|
|
244
|
+
failures: Math.max(0, Math.floor(peer.failures)),
|
|
245
|
+
srttMs: sanitizeLatency(peer.srttMs),
|
|
246
|
+
rttvarMs: sanitizeLatency(peer.rttvarMs),
|
|
247
|
+
rtoMs: clampRtoMs(peer.rtoMs),
|
|
248
|
+
bytesReceived: Math.max(0, Math.floor(peer.bytesReceived)),
|
|
249
|
+
bytesSent: Math.max(0, Math.floor(peer.bytesSent)),
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
for (const [peerId, stats] of this.stats.entries()) {
|
|
253
|
+
const persisted = this.persistedMetadata.get(peerPrincipal(peerId));
|
|
254
|
+
if (persisted)
|
|
255
|
+
applyMetadata(stats, persisted);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
order(peers, allTotalRequests) {
|
|
259
|
+
if (peers.length <= 1)
|
|
260
|
+
return peers.slice();
|
|
261
|
+
if (this.strategy === 'roundRobin') {
|
|
262
|
+
const sorted = peers.slice().sort((a, b) => a.peerId.localeCompare(b.peerId));
|
|
263
|
+
const offset = this.roundRobinIdx % sorted.length;
|
|
264
|
+
this.roundRobinIdx = (this.roundRobinIdx + 1) % sorted.length;
|
|
265
|
+
return sorted.slice(offset).concat(sorted.slice(0, offset));
|
|
266
|
+
}
|
|
267
|
+
if (this.strategy === 'random') {
|
|
268
|
+
return peers.slice().sort(() => Math.random() - 0.5);
|
|
269
|
+
}
|
|
270
|
+
return peers.slice().sort((a, b) => this.scoreFor(b, allTotalRequests) - this.scoreFor(a, allTotalRequests));
|
|
271
|
+
}
|
|
272
|
+
scoreFor(stats, allTotalRequests) {
|
|
273
|
+
switch (this.strategy) {
|
|
274
|
+
case 'lowestLatency':
|
|
275
|
+
return stats.srttMs > 0 ? -stats.srttMs : -1_000_000;
|
|
276
|
+
case 'highestSuccessRate':
|
|
277
|
+
return successRate(stats);
|
|
278
|
+
case 'titForTat':
|
|
279
|
+
return scoreTitForTat(stats, allTotalRequests);
|
|
280
|
+
case 'utilityUcb':
|
|
281
|
+
return scoreUtilityUcb(stats, allTotalRequests);
|
|
282
|
+
case 'weighted':
|
|
283
|
+
default:
|
|
284
|
+
return scoreWeighted(stats);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
applyFairness(peers) {
|
|
288
|
+
const ordered = peers.slice();
|
|
289
|
+
const total = totalRequests(ordered);
|
|
290
|
+
if (total <= 0)
|
|
291
|
+
return ordered;
|
|
292
|
+
for (let i = 0; i < ordered.length; i++) {
|
|
293
|
+
const top = ordered[0];
|
|
294
|
+
const share = top.requestsSent / total;
|
|
295
|
+
if (share <= FAIRNESS_SELECTION_SHARE_WARNING)
|
|
296
|
+
break;
|
|
297
|
+
ordered.push(ordered.shift());
|
|
298
|
+
}
|
|
299
|
+
return ordered;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
export function normalizeDispatchConfig(dispatch, availablePeers) {
|
|
303
|
+
let cap = dispatch.maxFanout === 0 ? availablePeers : Math.min(dispatch.maxFanout, availablePeers);
|
|
304
|
+
if (cap < 0)
|
|
305
|
+
cap = 0;
|
|
306
|
+
const initialFanout = (dispatch.initialFanout === 0 ? 1 : dispatch.initialFanout);
|
|
307
|
+
const hedgeFanout = (dispatch.hedgeFanout === 0 ? 1 : dispatch.hedgeFanout);
|
|
308
|
+
const floor = Math.max(1, cap);
|
|
309
|
+
return {
|
|
310
|
+
initialFanout: Math.min(initialFanout, floor),
|
|
311
|
+
hedgeFanout: Math.min(hedgeFanout, floor),
|
|
312
|
+
maxFanout: cap,
|
|
313
|
+
hedgeIntervalMs: Math.max(0, Math.floor(dispatch.hedgeIntervalMs)),
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
export function buildHedgedWavePlan(peerCount, dispatch) {
|
|
317
|
+
if (peerCount <= 0)
|
|
318
|
+
return [];
|
|
319
|
+
const cap = Math.min(dispatch.maxFanout, peerCount);
|
|
320
|
+
if (cap <= 0)
|
|
321
|
+
return [];
|
|
322
|
+
const plan = [];
|
|
323
|
+
let sent = 0;
|
|
324
|
+
const first = Math.max(1, Math.min(dispatch.initialFanout, cap));
|
|
325
|
+
plan.push(first);
|
|
326
|
+
sent += first;
|
|
327
|
+
while (sent < cap) {
|
|
328
|
+
const next = Math.max(1, Math.min(dispatch.hedgeFanout, cap - sent));
|
|
329
|
+
plan.push(next);
|
|
330
|
+
sent += next;
|
|
331
|
+
}
|
|
332
|
+
return plan;
|
|
333
|
+
}
|
|
334
|
+
export function syncSelectorPeers(selector, currentPeerIds) {
|
|
335
|
+
const current = new Set(currentPeerIds);
|
|
336
|
+
for (const peerId of selector.getPeerIds()) {
|
|
337
|
+
if (!current.has(peerId))
|
|
338
|
+
selector.removePeer(peerId);
|
|
339
|
+
}
|
|
340
|
+
for (const peerId of currentPeerIds)
|
|
341
|
+
selector.addPeer(peerId);
|
|
342
|
+
}
|
|
343
|
+
export function blendWeightedScore(baseScore, boostWeight, boostValue) {
|
|
344
|
+
const weight = clamp01(boostWeight);
|
|
345
|
+
const boost = clamp01(boostValue);
|
|
346
|
+
return (1 - weight) * baseScore + weight * (baseScore + boost);
|
|
347
|
+
}
|
|
348
|
+
//# sourceMappingURL=peerSelector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peerSelector.js","sourceRoot":"","sources":["../../src/webrtc/peerSelector.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DataRequest, DataResponse, DataMessage } from './types.js';
|
|
2
|
+
import { type HtlPolicy } from './types.js';
|
|
2
3
|
/**
|
|
3
4
|
* Encode a request message to wire format
|
|
4
5
|
*/
|
|
@@ -22,27 +23,37 @@ export interface PendingRequest {
|
|
|
22
23
|
hash: Uint8Array;
|
|
23
24
|
resolve: (data: Uint8Array | null) => void;
|
|
24
25
|
timeout: ReturnType<typeof setTimeout>;
|
|
26
|
+
startedAt?: number;
|
|
25
27
|
}
|
|
26
28
|
/**
|
|
27
29
|
* Per-peer HTL config (Freenet-style probabilistic decrement)
|
|
28
30
|
* Generated once per peer connection, stays fixed for connection lifetime
|
|
29
31
|
*/
|
|
30
32
|
export interface PeerHTLConfig {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
atMaxSample: number;
|
|
34
|
+
atMinSample: number;
|
|
35
|
+
decrementAtMax?: boolean;
|
|
36
|
+
decrementAtMin?: boolean;
|
|
33
37
|
}
|
|
34
38
|
/**
|
|
35
39
|
* Generate random HTL config for a new peer connection
|
|
36
40
|
*/
|
|
37
41
|
export declare function generatePeerHTLConfig(): PeerHTLConfig;
|
|
38
42
|
/**
|
|
39
|
-
* Decrement HTL using peer's config
|
|
40
|
-
|
|
43
|
+
* Decrement HTL using peer's config and selected policy.
|
|
44
|
+
*/
|
|
45
|
+
export declare function decrementHTLWithPolicy(htl: number, policy: HtlPolicy, config: PeerHTLConfig): number;
|
|
46
|
+
/**
|
|
47
|
+
* Backward-compatible helper using blob-request policy.
|
|
41
48
|
*/
|
|
42
49
|
export declare function decrementHTL(htl: number, config: PeerHTLConfig): number;
|
|
43
50
|
/**
|
|
44
51
|
* Check if a request should be forwarded based on HTL
|
|
45
52
|
*/
|
|
53
|
+
export declare function shouldForwardHTL(htl: number): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Backward-compatible helper.
|
|
56
|
+
*/
|
|
46
57
|
export declare function shouldForward(htl: number): boolean;
|
|
47
58
|
/**
|
|
48
59
|
* Create a request body
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/webrtc/protocol.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/webrtc/protocol.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAGL,KAAK,SAAS,EAGf,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,WAAW,GAAG,WAAW,CAM3D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,YAAY,GAAG,WAAW,CAM7D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI,CAiB/E;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAO7F;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IAC3C,OAAO,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IAEpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,aAAa,CAKrD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,aAAa,GACpB,MAAM,CAsBR;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,MAAM,CAEvE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,GAAE,MAAmC,GAAG,WAAW,CAErG;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,YAAY,CAE/E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,YAAY,CAEd;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAEvD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAMlD;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,YAAY,EACjB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAC3C,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAe9B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI,CAMvF"}
|
package/dist/webrtc/protocol.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { encode, decode } from '@msgpack/msgpack';
|
|
11
11
|
import { sha256 } from '@hashtree/core';
|
|
12
|
-
import {
|
|
12
|
+
import { BLOB_REQUEST_POLICY, HtlMode, MSG_TYPE_REQUEST, MSG_TYPE_RESPONSE, } from './types.js';
|
|
13
13
|
/**
|
|
14
14
|
* Encode a request message to wire format
|
|
15
15
|
*/
|
|
@@ -70,40 +70,54 @@ export async function verifyHash(data, expectedHash) {
|
|
|
70
70
|
*/
|
|
71
71
|
export function generatePeerHTLConfig() {
|
|
72
72
|
return {
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
atMaxSample: Math.random(),
|
|
74
|
+
atMinSample: Math.random(),
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
/**
|
|
78
|
-
* Decrement HTL using peer's config
|
|
79
|
-
* Called when SENDING to a peer, not on receive
|
|
78
|
+
* Decrement HTL using peer's config and selected policy.
|
|
80
79
|
*/
|
|
81
|
-
export function
|
|
80
|
+
export function decrementHTLWithPolicy(htl, policy, config) {
|
|
82
81
|
if (htl <= 0)
|
|
83
82
|
return 0;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
const bounded = Math.min(htl, policy.maxHtl);
|
|
84
|
+
const maxSample = config.atMaxSample ?? (config.decrementAtMax ? 0 : 1);
|
|
85
|
+
const minSample = config.atMinSample ?? (config.decrementAtMin ? 0 : 1);
|
|
86
|
+
if (policy.mode !== HtlMode.Probabilistic) {
|
|
87
|
+
return Math.max(0, bounded - 1);
|
|
87
88
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
const pAtMax = Math.max(0, Math.min(1, policy.pAtMax));
|
|
90
|
+
const pAtMin = Math.max(0, Math.min(1, policy.pAtMin));
|
|
91
|
+
if (bounded === policy.maxHtl) {
|
|
92
|
+
return maxSample < pAtMax ? bounded - 1 : bounded;
|
|
91
93
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return htl - 1;
|
|
94
|
+
if (bounded === 1) {
|
|
95
|
+
return minSample < pAtMin ? 0 : 1;
|
|
95
96
|
}
|
|
97
|
+
return bounded - 1;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Backward-compatible helper using blob-request policy.
|
|
101
|
+
*/
|
|
102
|
+
export function decrementHTL(htl, config) {
|
|
103
|
+
return decrementHTLWithPolicy(htl, BLOB_REQUEST_POLICY, config);
|
|
96
104
|
}
|
|
97
105
|
/**
|
|
98
106
|
* Check if a request should be forwarded based on HTL
|
|
99
107
|
*/
|
|
100
|
-
export function
|
|
108
|
+
export function shouldForwardHTL(htl) {
|
|
101
109
|
return htl > 0;
|
|
102
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Backward-compatible helper.
|
|
113
|
+
*/
|
|
114
|
+
export function shouldForward(htl) {
|
|
115
|
+
return shouldForwardHTL(htl);
|
|
116
|
+
}
|
|
103
117
|
/**
|
|
104
118
|
* Create a request body
|
|
105
119
|
*/
|
|
106
|
-
export function createRequest(hash, htl =
|
|
120
|
+
export function createRequest(hash, htl = BLOB_REQUEST_POLICY.maxHtl) {
|
|
107
121
|
return { h: hash, htl };
|
|
108
122
|
}
|
|
109
123
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/webrtc/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/webrtc/protocol.ts"],"names":[],"mappings":"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"}
|
package/dist/webrtc/store.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { Store, Hash } from '@hashtree/core';
|
|
2
|
-
import { type WebRTCStoreConfig, type PeerStatus, type WebRTCStoreEventHandler, type PeerPool, type PeerClassifier, type PoolConfig, type
|
|
2
|
+
import { type WebRTCStoreConfig, type PeerStatus, type WebRTCStoreEventHandler, type PeerPool, type PeerClassifier, type PoolConfig, type MeshStats } from './types.js';
|
|
3
3
|
import { Peer } from './peer.js';
|
|
4
4
|
export declare const DEFAULT_RELAYS: string[];
|
|
5
5
|
export declare class WebRTCStore implements Store {
|
|
6
6
|
private config;
|
|
7
|
+
private routing;
|
|
8
|
+
private readonly peerSelector;
|
|
7
9
|
private pools;
|
|
8
10
|
private peerClassifier;
|
|
9
11
|
private getFollowedPubkeys;
|
|
@@ -27,6 +29,11 @@ export declare class WebRTCStore implements Store {
|
|
|
27
29
|
private pendingGets;
|
|
28
30
|
private blossomFetches;
|
|
29
31
|
private currentHelloAuthors;
|
|
32
|
+
private seenFrameIds;
|
|
33
|
+
private seenEventIds;
|
|
34
|
+
private meshReceived;
|
|
35
|
+
private meshForwarded;
|
|
36
|
+
private meshDroppedDuplicate;
|
|
30
37
|
constructor(config: WebRTCStoreConfig);
|
|
31
38
|
private log;
|
|
32
39
|
/**
|
|
@@ -84,10 +91,14 @@ export declare class WebRTCStore implements Store {
|
|
|
84
91
|
private handleOffer;
|
|
85
92
|
private connectToPeer;
|
|
86
93
|
private handlePeerClose;
|
|
94
|
+
private orderedConnectedPeers;
|
|
95
|
+
private createInFlightPeerRequest;
|
|
96
|
+
private waitForNextPeerResult;
|
|
97
|
+
private queryPeersWithDispatch;
|
|
87
98
|
/**
|
|
88
99
|
* Forward a request to other peers (excluding the requester)
|
|
89
100
|
* Called by Peer when it receives a request it can't fulfill locally
|
|
90
|
-
* Uses
|
|
101
|
+
* Uses selector ordering + staged hedged dispatch
|
|
91
102
|
* @param htl - Hops To Live (already decremented by calling peer)
|
|
92
103
|
*/
|
|
93
104
|
private forwardRequest;
|
|
@@ -96,6 +107,12 @@ export declare class WebRTCStore implements Store {
|
|
|
96
107
|
* Called when we receive data that peers may be waiting for
|
|
97
108
|
*/
|
|
98
109
|
sendToInterestedPeers(hash: Uint8Array, data: Uint8Array): number;
|
|
110
|
+
private pruneSeenSet;
|
|
111
|
+
private markSeenFrameId;
|
|
112
|
+
private markSeenEventId;
|
|
113
|
+
private forwardMeshFrame;
|
|
114
|
+
private handleMeshFrame;
|
|
115
|
+
private dispatchSignaling;
|
|
99
116
|
private sendSignaling;
|
|
100
117
|
/**
|
|
101
118
|
* Force send a hello message (useful for testing after pool config changes)
|
|
@@ -117,7 +134,7 @@ export declare class WebRTCStore implements Store {
|
|
|
117
134
|
*/
|
|
118
135
|
disconnectPeerByPubkey(pubkey: string): void;
|
|
119
136
|
/**
|
|
120
|
-
* Get my
|
|
137
|
+
* Get my endpoint ID
|
|
121
138
|
*/
|
|
122
139
|
getMyPeerId(): string;
|
|
123
140
|
/**
|
|
@@ -142,6 +159,16 @@ export declare class WebRTCStore implements Store {
|
|
|
142
159
|
follows: PoolConfig;
|
|
143
160
|
other: PoolConfig;
|
|
144
161
|
};
|
|
162
|
+
private peerMetadataPointerHash;
|
|
163
|
+
/**
|
|
164
|
+
* Persist selector metadata snapshot to local store.
|
|
165
|
+
* Returns the snapshot hash, or null when local storage is unavailable.
|
|
166
|
+
*/
|
|
167
|
+
persistPeerMetadata(): Promise<Uint8Array | null>;
|
|
168
|
+
/**
|
|
169
|
+
* Load selector metadata snapshot from local store, if available.
|
|
170
|
+
*/
|
|
171
|
+
loadPeerMetadata(): Promise<boolean>;
|
|
145
172
|
/**
|
|
146
173
|
* Get fallback stores count
|
|
147
174
|
*/
|
|
@@ -150,7 +177,7 @@ export declare class WebRTCStore implements Store {
|
|
|
150
177
|
* Get WebRTC stats (aggregate and per-peer)
|
|
151
178
|
*/
|
|
152
179
|
getStats(): {
|
|
153
|
-
aggregate:
|
|
180
|
+
aggregate: MeshStats;
|
|
154
181
|
perPeer: Map<string, {
|
|
155
182
|
pubkey: string;
|
|
156
183
|
pool: PeerPool;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/webrtc/store.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAKL,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAEf,KAAK,uBAAuB,EAO5B,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/webrtc/store.ts"],"names":[],"mappings":"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"}
|