@libp2p/kad-dht 0.28.6
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/LICENSE +4 -0
- package/README.md +105 -0
- package/dist/src/constants.d.ts +20 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +34 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/content-fetching/index.d.ts +55 -0
- package/dist/src/content-fetching/index.d.ts.map +1 -0
- package/dist/src/content-fetching/index.js +190 -0
- package/dist/src/content-fetching/index.js.map +1 -0
- package/dist/src/content-routing/index.d.ts +42 -0
- package/dist/src/content-routing/index.d.ts.map +1 -0
- package/dist/src/content-routing/index.js +129 -0
- package/dist/src/content-routing/index.js.map +1 -0
- package/dist/src/dual-kad-dht.d.ts +65 -0
- package/dist/src/dual-kad-dht.d.ts.map +1 -0
- package/dist/src/dual-kad-dht.js +191 -0
- package/dist/src/dual-kad-dht.js.map +1 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +15 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/kad-dht.d.ts +131 -0
- package/dist/src/kad-dht.d.ts.map +1 -0
- package/dist/src/kad-dht.js +268 -0
- package/dist/src/kad-dht.js.map +1 -0
- package/dist/src/message/dht.d.ts +297 -0
- package/dist/src/message/dht.js +921 -0
- package/dist/src/message/index.d.ts +32 -0
- package/dist/src/message/index.d.ts.map +1 -0
- package/dist/src/message/index.js +81 -0
- package/dist/src/message/index.js.map +1 -0
- package/dist/src/network.d.ts +60 -0
- package/dist/src/network.d.ts.map +1 -0
- package/dist/src/network.js +124 -0
- package/dist/src/network.js.map +1 -0
- package/dist/src/peer-list/index.d.ts +29 -0
- package/dist/src/peer-list/index.d.ts.map +1 -0
- package/dist/src/peer-list/index.js +44 -0
- package/dist/src/peer-list/index.js.map +1 -0
- package/dist/src/peer-list/peer-distance-list.d.ts +34 -0
- package/dist/src/peer-list/peer-distance-list.d.ts.map +1 -0
- package/dist/src/peer-list/peer-distance-list.js +64 -0
- package/dist/src/peer-list/peer-distance-list.js.map +1 -0
- package/dist/src/peer-routing/index.d.ts +71 -0
- package/dist/src/peer-routing/index.d.ts.map +1 -0
- package/dist/src/peer-routing/index.js +256 -0
- package/dist/src/peer-routing/index.js.map +1 -0
- package/dist/src/providers.d.ts +64 -0
- package/dist/src/providers.d.ts.map +1 -0
- package/dist/src/providers.js +208 -0
- package/dist/src/providers.js.map +1 -0
- package/dist/src/query/events.d.ts +46 -0
- package/dist/src/query/events.d.ts.map +1 -0
- package/dist/src/query/events.js +73 -0
- package/dist/src/query/events.js.map +1 -0
- package/dist/src/query/manager.d.ts +40 -0
- package/dist/src/query/manager.d.ts.map +1 -0
- package/dist/src/query/manager.js +140 -0
- package/dist/src/query/manager.js.map +1 -0
- package/dist/src/query/query-path.d.ts +58 -0
- package/dist/src/query/query-path.d.ts.map +1 -0
- package/dist/src/query/query-path.js +171 -0
- package/dist/src/query/query-path.js.map +1 -0
- package/dist/src/query/types.d.ts +16 -0
- package/dist/src/query/types.d.ts.map +1 -0
- package/dist/src/query/types.js +2 -0
- package/dist/src/query/types.js.map +1 -0
- package/dist/src/query-self.d.ts +31 -0
- package/dist/src/query-self.d.ts.map +1 -0
- package/dist/src/query-self.js +73 -0
- package/dist/src/query-self.js.map +1 -0
- package/dist/src/routing-table/generated-prefix-list-browser.d.ts +3 -0
- package/dist/src/routing-table/generated-prefix-list-browser.d.ts.map +1 -0
- package/dist/src/routing-table/generated-prefix-list-browser.js +1027 -0
- package/dist/src/routing-table/generated-prefix-list-browser.js.map +1 -0
- package/dist/src/routing-table/generated-prefix-list.d.ts +3 -0
- package/dist/src/routing-table/generated-prefix-list.d.ts.map +1 -0
- package/dist/src/routing-table/generated-prefix-list.js +4099 -0
- package/dist/src/routing-table/generated-prefix-list.js.map +1 -0
- package/dist/src/routing-table/index.d.ts +91 -0
- package/dist/src/routing-table/index.d.ts.map +1 -0
- package/dist/src/routing-table/index.js +183 -0
- package/dist/src/routing-table/index.js.map +1 -0
- package/dist/src/routing-table/refresh.d.ts +50 -0
- package/dist/src/routing-table/refresh.d.ts.map +1 -0
- package/dist/src/routing-table/refresh.js +204 -0
- package/dist/src/routing-table/refresh.js.map +1 -0
- package/dist/src/routing-table/types.d.ts +24 -0
- package/dist/src/routing-table/types.d.ts.map +1 -0
- package/dist/src/rpc/handlers/add-provider.d.ts +13 -0
- package/dist/src/rpc/handlers/add-provider.d.ts.map +1 -0
- package/dist/src/rpc/handlers/add-provider.js +42 -0
- package/dist/src/rpc/handlers/add-provider.js.map +1 -0
- package/dist/src/rpc/handlers/find-node.d.ts +18 -0
- package/dist/src/rpc/handlers/find-node.d.ts.map +1 -0
- package/dist/src/rpc/handlers/find-node.js +32 -0
- package/dist/src/rpc/handlers/find-node.js.map +1 -0
- package/dist/src/rpc/handlers/get-providers.d.ts +24 -0
- package/dist/src/rpc/handlers/get-providers.d.ts.map +1 -0
- package/dist/src/rpc/handlers/get-providers.js +60 -0
- package/dist/src/rpc/handlers/get-providers.js.map +1 -0
- package/dist/src/rpc/handlers/get-value.d.ts +27 -0
- package/dist/src/rpc/handlers/get-value.d.ts.map +1 -0
- package/dist/src/rpc/handlers/get-value.js +94 -0
- package/dist/src/rpc/handlers/get-value.js.map +1 -0
- package/dist/src/rpc/handlers/index.d.ts +13 -0
- package/dist/src/rpc/handlers/index.d.ts.map +1 -0
- package/dist/src/rpc/handlers/ping.d.ts +7 -0
- package/dist/src/rpc/handlers/ping.d.ts.map +1 -0
- package/dist/src/rpc/handlers/ping.js +9 -0
- package/dist/src/rpc/handlers/ping.js.map +1 -0
- package/dist/src/rpc/handlers/put-value.d.ts +18 -0
- package/dist/src/rpc/handlers/put-value.d.ts.map +1 -0
- package/dist/src/rpc/handlers/put-value.js +35 -0
- package/dist/src/rpc/handlers/put-value.js.map +1 -0
- package/dist/src/rpc/index.d.ts +38 -0
- package/dist/src/rpc/index.d.ts.map +1 -0
- package/dist/src/rpc/index.js +75 -0
- package/dist/src/rpc/index.js.map +1 -0
- package/dist/src/rpc/types.d.ts +6 -0
- package/dist/src/rpc/types.d.ts.map +1 -0
- package/dist/src/topology-listener.d.ts +33 -0
- package/dist/src/topology-listener.d.ts.map +1 -0
- package/dist/src/topology-listener.js +50 -0
- package/dist/src/topology-listener.js.map +1 -0
- package/dist/src/types.d.ts +143 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/utils.d.ts +33 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/src/utils.js +89 -0
- package/dist/src/utils.js.map +1 -0
- package/package.json +200 -0
- package/src/constants.ts +50 -0
- package/src/content-fetching/index.ts +276 -0
- package/src/content-routing/index.ts +202 -0
- package/src/dual-kad-dht.ts +257 -0
- package/src/index.ts +21 -0
- package/src/kad-dht.ts +396 -0
- package/src/message/dht.d.ts +297 -0
- package/src/message/dht.js +921 -0
- package/src/message/dht.proto +75 -0
- package/src/message/index.ts +111 -0
- package/src/network.ts +185 -0
- package/src/peer-list/index.ts +54 -0
- package/src/peer-list/peer-distance-list.ts +93 -0
- package/src/peer-routing/index.ts +332 -0
- package/src/providers.ts +278 -0
- package/src/query/events.ts +126 -0
- package/src/query/manager.ts +188 -0
- package/src/query/query-path.ts +263 -0
- package/src/query/types.ts +22 -0
- package/src/query-self.ts +106 -0
- package/src/routing-table/generated-prefix-list-browser.ts +1026 -0
- package/src/routing-table/generated-prefix-list.ts +4098 -0
- package/src/routing-table/index.ts +265 -0
- package/src/routing-table/refresh.ts +263 -0
- package/src/rpc/handlers/add-provider.ts +63 -0
- package/src/rpc/handlers/find-node.ts +57 -0
- package/src/rpc/handlers/get-providers.ts +95 -0
- package/src/rpc/handlers/get-value.ts +130 -0
- package/src/rpc/handlers/ping.ts +13 -0
- package/src/rpc/handlers/put-value.ts +58 -0
- package/src/rpc/index.ts +118 -0
- package/src/topology-listener.ts +78 -0
- package/src/utils.ts +108 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import Queue from 'p-queue';
|
|
2
|
+
import type { PeerId } from '@libp2p/interfaces/peer-id';
|
|
3
|
+
import type { Dialer, Startable } from '@libp2p/interfaces';
|
|
4
|
+
import type { ComponentMetricsTracker } from '@libp2p/interfaces/metrics';
|
|
5
|
+
export interface KBucketPeer {
|
|
6
|
+
id: Uint8Array;
|
|
7
|
+
peer: PeerId;
|
|
8
|
+
}
|
|
9
|
+
export interface KBucket {
|
|
10
|
+
id: Uint8Array;
|
|
11
|
+
contacts: KBucketPeer[];
|
|
12
|
+
dontSplit: boolean;
|
|
13
|
+
left: KBucket;
|
|
14
|
+
right: KBucket;
|
|
15
|
+
}
|
|
16
|
+
export interface KBucketTree {
|
|
17
|
+
root: KBucket;
|
|
18
|
+
localNodeId: Uint8Array;
|
|
19
|
+
on: (event: 'ping', callback: (oldContacts: KBucketPeer[], newContact: KBucketPeer) => void) => void;
|
|
20
|
+
closest: (key: Uint8Array, count: number) => KBucketPeer[];
|
|
21
|
+
closestPeer: (key: Uint8Array) => KBucketPeer;
|
|
22
|
+
remove: (key: Uint8Array) => void;
|
|
23
|
+
add: (peer: KBucketPeer) => void;
|
|
24
|
+
get: (key: Uint8Array) => Uint8Array;
|
|
25
|
+
count: () => number;
|
|
26
|
+
toIterable: () => Iterable<KBucket>;
|
|
27
|
+
}
|
|
28
|
+
export interface RoutingTableOptions {
|
|
29
|
+
peerId: PeerId;
|
|
30
|
+
dialer: Dialer;
|
|
31
|
+
lan: boolean;
|
|
32
|
+
metrics?: ComponentMetricsTracker;
|
|
33
|
+
kBucketSize?: number;
|
|
34
|
+
pingTimeout?: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A wrapper around `k-bucket`, to provide easy store and
|
|
38
|
+
* retrieval for peers.
|
|
39
|
+
*/
|
|
40
|
+
export declare class RoutingTable implements Startable {
|
|
41
|
+
private readonly log;
|
|
42
|
+
private readonly peerId;
|
|
43
|
+
dialer: Dialer;
|
|
44
|
+
private readonly lan;
|
|
45
|
+
private readonly metrics?;
|
|
46
|
+
kBucketSize: number;
|
|
47
|
+
private readonly pingTimeout;
|
|
48
|
+
kb?: KBucketTree;
|
|
49
|
+
private running;
|
|
50
|
+
pingQueue: Queue;
|
|
51
|
+
constructor(options: RoutingTableOptions);
|
|
52
|
+
isStarted(): boolean;
|
|
53
|
+
start(): Promise<void>;
|
|
54
|
+
stop(): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Called on the `ping` event from `k-bucket` when a bucket is full
|
|
57
|
+
* and cannot split.
|
|
58
|
+
*
|
|
59
|
+
* `oldContacts.length` is defined by the `numberOfNodesToPing` param
|
|
60
|
+
* passed to the `k-bucket` constructor.
|
|
61
|
+
*
|
|
62
|
+
* `oldContacts` will not be empty and is the list of contacts that
|
|
63
|
+
* have not been contacted for the longest.
|
|
64
|
+
*/
|
|
65
|
+
_onPing(oldContacts: KBucketPeer[], newContact: KBucketPeer): void;
|
|
66
|
+
/**
|
|
67
|
+
* Amount of currently stored peers
|
|
68
|
+
*/
|
|
69
|
+
get size(): number;
|
|
70
|
+
/**
|
|
71
|
+
* Find a specific peer by id
|
|
72
|
+
*/
|
|
73
|
+
find(peer: PeerId): Promise<PeerId | undefined>;
|
|
74
|
+
/**
|
|
75
|
+
* Retrieve the closest peers to the given key
|
|
76
|
+
*/
|
|
77
|
+
closestPeer(key: Uint8Array): PeerId | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* Retrieve the `count`-closest peers to the given key
|
|
80
|
+
*/
|
|
81
|
+
closestPeers(key: Uint8Array, count?: number): PeerId[];
|
|
82
|
+
/**
|
|
83
|
+
* Add or update the routing table with the given peer
|
|
84
|
+
*/
|
|
85
|
+
add(peer: PeerId): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Remove a given peer from the table
|
|
88
|
+
*/
|
|
89
|
+
remove(peer: PeerId): Promise<void>;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/routing-table/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,SAAS,CAAA;AAI3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC3D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAA;AAGzE,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,UAAU,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,UAAU,CAAA;IACd,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,SAAS,EAAE,OAAO,CAAA;IAClB,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,UAAU,CAAA;IACvB,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,EAAE,UAAU,EAAE,WAAW,KAAK,IAAI,KAAK,IAAI,CAAA;IACpG,OAAO,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,KAAK,WAAW,EAAE,CAAA;IAC1D,WAAW,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,WAAW,CAAA;IAC7C,MAAM,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAA;IACjC,GAAG,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAA;IAChC,GAAG,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,UAAU,CAAA;IACpC,KAAK,EAAE,MAAM,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAA;CACpC;AAID,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,OAAO,CAAA;IACZ,OAAO,CAAC,EAAE,uBAAuB,CAAA;IACjC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;;GAGG;AACH,qBAAa,YAAa,YAAW,SAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IACxB,MAAM,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAyB;IAC3C,WAAW,EAAE,MAAM,CAAA;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IAC7B,EAAE,CAAC,EAAE,WAAW,CAAA;IACvB,OAAO,CAAC,OAAO,CAAS;IACjB,SAAS,EAAE,KAAK,CAAA;gBAEV,OAAO,EAAE,mBAAmB;IAgBzC,SAAS;IAIH,KAAK;IAYL,IAAI;IAMV;;;;;;;;;OASG;IACH,OAAO,CAAE,WAAW,EAAE,WAAW,EAAE,EAAE,UAAU,EAAE,WAAW;IA+D5D;;OAEG;IACH,IAAI,IAAI,WAMP;IAED;;OAEG;IACG,IAAI,CAAE,IAAI,EAAE,MAAM;IASxB;;OAEG;IACH,WAAW,CAAE,GAAG,EAAE,UAAU;IAQ5B;;OAEG;IACH,YAAY,CAAE,GAAG,EAAE,UAAU,EAAE,KAAK,SAAmB;IAUvD;;OAEG;IACG,GAAG,CAAE,IAAI,EAAE,MAAM;IAmBvB;;OAEG;IACG,MAAM,CAAE,IAAI,EAAE,MAAM;CAgB3B"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// @ts-expect-error no types
|
|
2
|
+
import KBuck from 'k-bucket';
|
|
3
|
+
import * as utils from '../utils.js';
|
|
4
|
+
import Queue from 'p-queue';
|
|
5
|
+
import { PROTOCOL_DHT } from '../constants.js';
|
|
6
|
+
import { TimeoutController } from 'timeout-abort-controller';
|
|
7
|
+
import { logger } from '@libp2p/logger';
|
|
8
|
+
const METRIC_ROUTING_TABLE_SIZE = 'routing-table-size';
|
|
9
|
+
/**
|
|
10
|
+
* A wrapper around `k-bucket`, to provide easy store and
|
|
11
|
+
* retrieval for peers.
|
|
12
|
+
*/
|
|
13
|
+
export class RoutingTable {
|
|
14
|
+
constructor(options) {
|
|
15
|
+
const { peerId, dialer, kBucketSize, pingTimeout, lan, metrics } = options;
|
|
16
|
+
this.log = logger(`libp2p:kad-dht:${lan ? 'lan' : 'wan'}:routing-table`);
|
|
17
|
+
this.peerId = peerId;
|
|
18
|
+
this.dialer = dialer;
|
|
19
|
+
this.kBucketSize = kBucketSize ?? 20;
|
|
20
|
+
this.pingTimeout = pingTimeout ?? 10000;
|
|
21
|
+
this.lan = lan;
|
|
22
|
+
this.metrics = metrics;
|
|
23
|
+
this.pingQueue = new Queue({ concurrency: 1 });
|
|
24
|
+
this.running = false;
|
|
25
|
+
this._onPing = this._onPing.bind(this);
|
|
26
|
+
}
|
|
27
|
+
isStarted() {
|
|
28
|
+
return this.running;
|
|
29
|
+
}
|
|
30
|
+
async start() {
|
|
31
|
+
this.running = true;
|
|
32
|
+
const kBuck = new KBuck({
|
|
33
|
+
localNodeId: await utils.convertPeerId(this.peerId),
|
|
34
|
+
numberOfNodesPerKBucket: this.kBucketSize,
|
|
35
|
+
numberOfNodesToPing: 1
|
|
36
|
+
});
|
|
37
|
+
kBuck.on('ping', this._onPing);
|
|
38
|
+
this.kb = kBuck;
|
|
39
|
+
}
|
|
40
|
+
async stop() {
|
|
41
|
+
this.running = false;
|
|
42
|
+
this.pingQueue.clear();
|
|
43
|
+
this.kb = undefined;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Called on the `ping` event from `k-bucket` when a bucket is full
|
|
47
|
+
* and cannot split.
|
|
48
|
+
*
|
|
49
|
+
* `oldContacts.length` is defined by the `numberOfNodesToPing` param
|
|
50
|
+
* passed to the `k-bucket` constructor.
|
|
51
|
+
*
|
|
52
|
+
* `oldContacts` will not be empty and is the list of contacts that
|
|
53
|
+
* have not been contacted for the longest.
|
|
54
|
+
*/
|
|
55
|
+
_onPing(oldContacts, newContact) {
|
|
56
|
+
// add to a queue so multiple ping requests do not overlap and we don't
|
|
57
|
+
// flood the network with ping requests if lots of newContact requests
|
|
58
|
+
// are received
|
|
59
|
+
this.pingQueue.add(async () => {
|
|
60
|
+
if (!this.running) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
let responded = 0;
|
|
64
|
+
try {
|
|
65
|
+
await Promise.all(oldContacts.map(async (oldContact) => {
|
|
66
|
+
let timeoutController;
|
|
67
|
+
try {
|
|
68
|
+
timeoutController = new TimeoutController(this.pingTimeout);
|
|
69
|
+
this.log('pinging old contact %p', oldContact.peer);
|
|
70
|
+
const { stream } = await this.dialer.dialProtocol(oldContact.peer, PROTOCOL_DHT, {
|
|
71
|
+
signal: timeoutController.signal
|
|
72
|
+
});
|
|
73
|
+
await stream.close();
|
|
74
|
+
responded++;
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
if (this.running && this.kb != null) {
|
|
78
|
+
// only evict peers if we are still running, otherwise we evict when dialing is
|
|
79
|
+
// cancelled due to shutdown in progress
|
|
80
|
+
this.log.error('could not ping peer %p', oldContact.peer, err);
|
|
81
|
+
this.log('evicting old contact after ping failed %p', oldContact);
|
|
82
|
+
this.kb.remove(oldContact.id);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
if (timeoutController != null) {
|
|
87
|
+
timeoutController.clear();
|
|
88
|
+
}
|
|
89
|
+
this.metrics?.updateComponentMetric({
|
|
90
|
+
system: 'libp2p',
|
|
91
|
+
component: `kad-dht-${this.lan ? 'lan' : 'wan'}`,
|
|
92
|
+
metric: METRIC_ROUTING_TABLE_SIZE,
|
|
93
|
+
value: this.size
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}));
|
|
97
|
+
if (this.running && responded < oldContacts.length && this.kb != null) {
|
|
98
|
+
this.log('adding new contact %p', newContact.peer);
|
|
99
|
+
this.kb.add(newContact);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
this.log.error('could not process k-bucket ping event', err);
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
.catch(err => {
|
|
107
|
+
this.log.error('could not process k-bucket ping event', err);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// -- Public Interface
|
|
111
|
+
/**
|
|
112
|
+
* Amount of currently stored peers
|
|
113
|
+
*/
|
|
114
|
+
get size() {
|
|
115
|
+
if (this.kb == null) {
|
|
116
|
+
return 0;
|
|
117
|
+
}
|
|
118
|
+
return this.kb.count();
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Find a specific peer by id
|
|
122
|
+
*/
|
|
123
|
+
async find(peer) {
|
|
124
|
+
const key = await utils.convertPeerId(peer);
|
|
125
|
+
const closest = this.closestPeer(key);
|
|
126
|
+
if (closest != null && peer.equals(closest)) {
|
|
127
|
+
return closest;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Retrieve the closest peers to the given key
|
|
132
|
+
*/
|
|
133
|
+
closestPeer(key) {
|
|
134
|
+
const res = this.closestPeers(key, 1);
|
|
135
|
+
if (res.length > 0) {
|
|
136
|
+
return res[0];
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Retrieve the `count`-closest peers to the given key
|
|
141
|
+
*/
|
|
142
|
+
closestPeers(key, count = this.kBucketSize) {
|
|
143
|
+
if (this.kb == null) {
|
|
144
|
+
return [];
|
|
145
|
+
}
|
|
146
|
+
const closest = this.kb.closest(key, count);
|
|
147
|
+
return closest.map(p => p.peer);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Add or update the routing table with the given peer
|
|
151
|
+
*/
|
|
152
|
+
async add(peer) {
|
|
153
|
+
if (this.kb == null) {
|
|
154
|
+
throw new Error('RoutingTable is not started');
|
|
155
|
+
}
|
|
156
|
+
const id = await utils.convertPeerId(peer);
|
|
157
|
+
this.kb.add({ id: id, peer: peer });
|
|
158
|
+
this.log('added %p with kad id %b', peer, id);
|
|
159
|
+
this.metrics?.updateComponentMetric({
|
|
160
|
+
system: 'libp2p',
|
|
161
|
+
component: `kad-dht-${this.lan ? 'lan' : 'wan'}`,
|
|
162
|
+
metric: METRIC_ROUTING_TABLE_SIZE,
|
|
163
|
+
value: this.size
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Remove a given peer from the table
|
|
168
|
+
*/
|
|
169
|
+
async remove(peer) {
|
|
170
|
+
if (this.kb == null) {
|
|
171
|
+
throw new Error('RoutingTable is not started');
|
|
172
|
+
}
|
|
173
|
+
const id = await utils.convertPeerId(peer);
|
|
174
|
+
this.kb.remove(id);
|
|
175
|
+
this.metrics?.updateComponentMetric({
|
|
176
|
+
system: 'libp2p',
|
|
177
|
+
component: `kad-dht-${this.lan ? 'lan' : 'wan'}`,
|
|
178
|
+
metric: METRIC_ROUTING_TABLE_SIZE,
|
|
179
|
+
value: this.size
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/routing-table/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { RoutingTable } from './index.js';
|
|
2
|
+
import type { PeerRouting } from '../peer-routing/index.js';
|
|
3
|
+
export interface RoutingTableRefreshOptions {
|
|
4
|
+
peerRouting: PeerRouting;
|
|
5
|
+
routingTable: RoutingTable;
|
|
6
|
+
lan: boolean;
|
|
7
|
+
refreshInterval?: number;
|
|
8
|
+
refreshQueryTimeout?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A wrapper around `k-bucket`, to provide easy store and
|
|
12
|
+
* retrieval for peers.
|
|
13
|
+
*/
|
|
14
|
+
export declare class RoutingTableRefresh {
|
|
15
|
+
private readonly log;
|
|
16
|
+
private readonly peerRouting;
|
|
17
|
+
private readonly routingTable;
|
|
18
|
+
private readonly refreshInterval;
|
|
19
|
+
private readonly refreshQueryTimeout;
|
|
20
|
+
private readonly commonPrefixLengthRefreshedAt;
|
|
21
|
+
private refreshTimeoutId?;
|
|
22
|
+
constructor(options: RoutingTableRefreshOptions);
|
|
23
|
+
start(): Promise<void>;
|
|
24
|
+
stop(): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* To speed lookups, we seed the table with random PeerIds. This means
|
|
27
|
+
* when we are asked to locate a peer on the network, we can find a KadId
|
|
28
|
+
* that is close to the requested peer ID and query that, then network
|
|
29
|
+
* peers will tell us who they know who is close to the fake ID
|
|
30
|
+
*/
|
|
31
|
+
refreshTable(force?: boolean): void;
|
|
32
|
+
_refreshCommonPrefixLength(cpl: number, lastRefresh: Date, force: boolean): Promise<void>;
|
|
33
|
+
_getTrackedCommonPrefixLengthsForRefresh(maxCommonPrefix: number): Date[];
|
|
34
|
+
_generateRandomPeerId(targetCommonPrefixLength: number): Promise<import("@libp2p/interfaces/dist/src/peer-id").PeerId>;
|
|
35
|
+
_makePeerId(localKadId: Uint8Array, randomPrefix: number, targetCommonPrefixLength: number): Promise<Uint8Array>;
|
|
36
|
+
/**
|
|
37
|
+
* returns the maximum common prefix length between any peer in the table
|
|
38
|
+
* and the current peer
|
|
39
|
+
*/
|
|
40
|
+
_maxCommonPrefix(): number;
|
|
41
|
+
/**
|
|
42
|
+
* Returns the number of peers in the table with a given prefix length
|
|
43
|
+
*/
|
|
44
|
+
_numPeersForCpl(prefixLength: number): number;
|
|
45
|
+
/**
|
|
46
|
+
* Yields the common prefix length of every peer in the table
|
|
47
|
+
*/
|
|
48
|
+
_prefixLengths(): Generator<number, void, unknown>;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=refresh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../../src/routing-table/refresh.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAO3D,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,WAAW,CAAA;IACxB,YAAY,EAAE,YAAY,CAAA;IAC1B,GAAG,EAAE,OAAO,CAAA;IACZ,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IACxC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAQ;IAC5C,OAAO,CAAC,QAAQ,CAAC,6BAA6B,CAAQ;IACtD,OAAO,CAAC,gBAAgB,CAAC,CAAc;gBAE1B,OAAO,EAAE,0BAA0B;IAY1C,KAAK;IAKL,IAAI;IAMV;;;;;OAKG;IACH,YAAY,CAAE,KAAK,GAAE,OAAe;IAyD9B,0BAA0B,CAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO;IAuBhF,wCAAwC,CAAE,eAAe,EAAE,MAAM;IAe3D,qBAAqB,CAAE,wBAAwB,EAAE,MAAM;IAavD,WAAW,CAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,wBAAwB,EAAE,MAAM;IA8BjG;;;OAGG;IACH,gBAAgB;IAchB;;OAEG;IACH,eAAe,CAAE,YAAY,EAAE,MAAM;IAYrC;;OAEG;IACD,cAAc;CAoBjB"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { xor as uint8ArrayXor } from 'uint8arrays/xor';
|
|
2
|
+
import GENERATED_PREFIXES from './generated-prefix-list.js';
|
|
3
|
+
import { sha256 } from 'multiformats/hashes/sha2';
|
|
4
|
+
import { randomBytes } from '@libp2p/crypto';
|
|
5
|
+
import { peerIdFromBytes } from '@libp2p/peer-id';
|
|
6
|
+
import { logger } from '@libp2p/logger';
|
|
7
|
+
import length from 'it-length';
|
|
8
|
+
import { TimeoutController } from 'timeout-abort-controller';
|
|
9
|
+
import { TABLE_REFRESH_INTERVAL, TABLE_REFRESH_QUERY_TIMEOUT } from '../constants.js';
|
|
10
|
+
/**
|
|
11
|
+
* Cannot generate random KadIds longer than this + 1
|
|
12
|
+
*/
|
|
13
|
+
const MAX_COMMON_PREFIX_LENGTH = 15;
|
|
14
|
+
/**
|
|
15
|
+
* A wrapper around `k-bucket`, to provide easy store and
|
|
16
|
+
* retrieval for peers.
|
|
17
|
+
*/
|
|
18
|
+
export class RoutingTableRefresh {
|
|
19
|
+
constructor(options) {
|
|
20
|
+
const { peerRouting, routingTable, refreshInterval, refreshQueryTimeout, lan } = options;
|
|
21
|
+
this.log = logger(`libp2p:kad-dht:${lan ? 'lan' : 'wan'}:routing-table:refresh`);
|
|
22
|
+
this.peerRouting = peerRouting;
|
|
23
|
+
this.routingTable = routingTable;
|
|
24
|
+
this.refreshInterval = refreshInterval ?? TABLE_REFRESH_INTERVAL;
|
|
25
|
+
this.refreshQueryTimeout = refreshQueryTimeout ?? TABLE_REFRESH_QUERY_TIMEOUT;
|
|
26
|
+
this.commonPrefixLengthRefreshedAt = [];
|
|
27
|
+
this.refreshTable = this.refreshTable.bind(this);
|
|
28
|
+
}
|
|
29
|
+
async start() {
|
|
30
|
+
this.log(`refreshing routing table every ${this.refreshInterval}ms`);
|
|
31
|
+
this.refreshTable(true);
|
|
32
|
+
}
|
|
33
|
+
async stop() {
|
|
34
|
+
if (this.refreshTimeoutId != null) {
|
|
35
|
+
clearTimeout(this.refreshTimeoutId);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* To speed lookups, we seed the table with random PeerIds. This means
|
|
40
|
+
* when we are asked to locate a peer on the network, we can find a KadId
|
|
41
|
+
* that is close to the requested peer ID and query that, then network
|
|
42
|
+
* peers will tell us who they know who is close to the fake ID
|
|
43
|
+
*/
|
|
44
|
+
refreshTable(force = false) {
|
|
45
|
+
this.log('refreshing routing table');
|
|
46
|
+
const prefixLength = this._maxCommonPrefix();
|
|
47
|
+
const refreshCpls = this._getTrackedCommonPrefixLengthsForRefresh(prefixLength);
|
|
48
|
+
this.log(`max common prefix length ${prefixLength}`);
|
|
49
|
+
this.log(`tracked CPLs [ ${refreshCpls.map(date => date.toISOString()).join(', ')} ]`);
|
|
50
|
+
/**
|
|
51
|
+
* If we see a gap at a common prefix length in the Routing table, we ONLY refresh up until
|
|
52
|
+
* the maximum cpl we have in the Routing Table OR (2 * (Cpl+ 1) with the gap), whichever
|
|
53
|
+
* is smaller.
|
|
54
|
+
*
|
|
55
|
+
* This is to prevent refreshes for Cpls that have no peers in the network but happen to be
|
|
56
|
+
* before a very high max Cpl for which we do have peers in the network.
|
|
57
|
+
*
|
|
58
|
+
* The number of 2 * (Cpl + 1) can be proved and a proof would have been written here if
|
|
59
|
+
* the programmer had paid more attention in the Math classes at university.
|
|
60
|
+
*
|
|
61
|
+
* So, please be patient and a doc explaining it will be published soon.
|
|
62
|
+
*
|
|
63
|
+
* https://github.com/libp2p/go-libp2p-kad-dht/commit/2851c88acb0a3f86bcfe3cfd0f4604a03db801d8#diff-ad45f4ba97ffbc4083c2eb87a4420c1157057b233f048030d67c6b551855ccf6R219
|
|
64
|
+
*/
|
|
65
|
+
Promise.all(refreshCpls.map(async (lastRefresh, index) => {
|
|
66
|
+
try {
|
|
67
|
+
await this._refreshCommonPrefixLength(index, lastRefresh, force);
|
|
68
|
+
if (this._numPeersForCpl(prefixLength) === 0) {
|
|
69
|
+
const lastCpl = Math.min(2 * (index + 1), refreshCpls.length - 1);
|
|
70
|
+
for (let n = index + 1; n < lastCpl + 1; n++) {
|
|
71
|
+
try {
|
|
72
|
+
await this._refreshCommonPrefixLength(n, lastRefresh, force);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
this.log.error(err);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
this.log.error(err);
|
|
82
|
+
}
|
|
83
|
+
})).catch(err => {
|
|
84
|
+
this.log.error(err);
|
|
85
|
+
}).then(() => {
|
|
86
|
+
this.refreshTimeoutId = setTimeout(this.refreshTable, this.refreshInterval);
|
|
87
|
+
if (this.refreshTimeoutId.unref != null) {
|
|
88
|
+
this.refreshTimeoutId.unref();
|
|
89
|
+
}
|
|
90
|
+
}).catch(err => {
|
|
91
|
+
this.log.error(err);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
async _refreshCommonPrefixLength(cpl, lastRefresh, force) {
|
|
95
|
+
if (!force && lastRefresh.getTime() > (Date.now() - this.refreshInterval)) {
|
|
96
|
+
this.log('not running refresh for cpl %s as time since last refresh not above interval', cpl);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
// gen a key for the query to refresh the cpl
|
|
100
|
+
const peerId = await this._generateRandomPeerId(cpl);
|
|
101
|
+
this.log('starting refreshing cpl %s with key %p (routing table size was %s)', cpl, peerId, this.routingTable.size);
|
|
102
|
+
const controller = new TimeoutController(this.refreshQueryTimeout);
|
|
103
|
+
try {
|
|
104
|
+
const peers = await length(this.peerRouting.getClosestPeers(peerId.toBytes(), { signal: controller.signal }));
|
|
105
|
+
this.log(`found ${peers} peers that were close to imaginary peer %p`, peerId);
|
|
106
|
+
this.log('finished refreshing cpl %s with key %p (routing table size is now %s)', cpl, peerId, this.routingTable.size);
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
controller.clear();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
_getTrackedCommonPrefixLengthsForRefresh(maxCommonPrefix) {
|
|
113
|
+
if (maxCommonPrefix > MAX_COMMON_PREFIX_LENGTH) {
|
|
114
|
+
maxCommonPrefix = MAX_COMMON_PREFIX_LENGTH;
|
|
115
|
+
}
|
|
116
|
+
const dates = [];
|
|
117
|
+
for (let i = 0; i <= maxCommonPrefix; i++) {
|
|
118
|
+
// defaults to the zero value if we haven't refreshed it yet.
|
|
119
|
+
dates[i] = this.commonPrefixLengthRefreshedAt[i] ?? new Date();
|
|
120
|
+
}
|
|
121
|
+
return dates;
|
|
122
|
+
}
|
|
123
|
+
async _generateRandomPeerId(targetCommonPrefixLength) {
|
|
124
|
+
if (this.routingTable.kb == null) {
|
|
125
|
+
throw new Error('Routing table not started');
|
|
126
|
+
}
|
|
127
|
+
const randomData = randomBytes(2);
|
|
128
|
+
const randomUint16 = (randomData[1] << 8) + randomData[0];
|
|
129
|
+
const key = await this._makePeerId(this.routingTable.kb.localNodeId, randomUint16, targetCommonPrefixLength);
|
|
130
|
+
return peerIdFromBytes(key);
|
|
131
|
+
}
|
|
132
|
+
async _makePeerId(localKadId, randomPrefix, targetCommonPrefixLength) {
|
|
133
|
+
if (targetCommonPrefixLength > MAX_COMMON_PREFIX_LENGTH) {
|
|
134
|
+
throw new Error(`Cannot generate peer ID for common prefix length greater than ${MAX_COMMON_PREFIX_LENGTH}`);
|
|
135
|
+
}
|
|
136
|
+
const view = new DataView(localKadId.buffer, localKadId.byteOffset, localKadId.byteLength);
|
|
137
|
+
const localPrefix = view.getUint16(0, false);
|
|
138
|
+
// For host with ID `L`, an ID `K` belongs to a bucket with ID `B` ONLY IF CommonPrefixLen(L,K) is EXACTLY B.
|
|
139
|
+
// Hence, to achieve a targetPrefix `T`, we must toggle the (T+1)th bit in L & then copy (T+1) bits from L
|
|
140
|
+
// to our randomly generated prefix.
|
|
141
|
+
const toggledLocalPrefix = localPrefix ^ (0x8000 >> targetCommonPrefixLength);
|
|
142
|
+
// Combine the toggled local prefix and the random bits at the correct offset
|
|
143
|
+
// such that ONLY the first `targetCommonPrefixLength` bits match the local ID.
|
|
144
|
+
const mask = 65535 << (16 - (targetCommonPrefixLength + 1));
|
|
145
|
+
const targetPrefix = (toggledLocalPrefix & mask) | (randomPrefix & ~mask);
|
|
146
|
+
// Convert to a known peer ID.
|
|
147
|
+
const keyPrefix = GENERATED_PREFIXES[targetPrefix];
|
|
148
|
+
const keyBuffer = new ArrayBuffer(34);
|
|
149
|
+
const keyView = new DataView(keyBuffer, 0, keyBuffer.byteLength);
|
|
150
|
+
keyView.setUint8(0, sha256.code);
|
|
151
|
+
keyView.setUint8(1, 32);
|
|
152
|
+
keyView.setUint32(2, keyPrefix, false);
|
|
153
|
+
return new Uint8Array(keyView.buffer, keyView.byteOffset, keyView.byteLength);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* returns the maximum common prefix length between any peer in the table
|
|
157
|
+
* and the current peer
|
|
158
|
+
*/
|
|
159
|
+
_maxCommonPrefix() {
|
|
160
|
+
// xor our KadId with every KadId in the k-bucket tree,
|
|
161
|
+
// return the longest id prefix that is the same
|
|
162
|
+
let prefixLength = 0;
|
|
163
|
+
for (const length of this._prefixLengths()) {
|
|
164
|
+
if (length > prefixLength) {
|
|
165
|
+
prefixLength = length;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return prefixLength;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Returns the number of peers in the table with a given prefix length
|
|
172
|
+
*/
|
|
173
|
+
_numPeersForCpl(prefixLength) {
|
|
174
|
+
let count = 0;
|
|
175
|
+
for (const length of this._prefixLengths()) {
|
|
176
|
+
if (length === prefixLength) {
|
|
177
|
+
count++;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return count;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Yields the common prefix length of every peer in the table
|
|
184
|
+
*/
|
|
185
|
+
*_prefixLengths() {
|
|
186
|
+
if (this.routingTable.kb == null) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
for (const { id } of this.routingTable.kb.toIterable()) {
|
|
190
|
+
const distance = uint8ArrayXor(this.routingTable.kb.localNodeId, id);
|
|
191
|
+
let leadingZeros = 0;
|
|
192
|
+
for (const byte of distance) {
|
|
193
|
+
if (byte === 0) {
|
|
194
|
+
leadingZeros++;
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
yield leadingZeros;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=refresh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../../src/routing-table/refresh.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type PeerId from 'peer-id';
|
|
2
|
+
export interface KBucketPeer {
|
|
3
|
+
id: Uint8Array;
|
|
4
|
+
peer: PeerId;
|
|
5
|
+
}
|
|
6
|
+
export interface KBucket {
|
|
7
|
+
id: Uint8Array;
|
|
8
|
+
contacts: KBucketPeer[];
|
|
9
|
+
dontSplit: boolean;
|
|
10
|
+
left: KBucket;
|
|
11
|
+
right: KBucket;
|
|
12
|
+
}
|
|
13
|
+
export interface KBucketTree {
|
|
14
|
+
root: KBucket;
|
|
15
|
+
localNodeId: Uint8Array;
|
|
16
|
+
on: (event: 'ping', callback: (oldContacts: KBucketPeer[], newContact: KBucketPeer) => void) => void;
|
|
17
|
+
closest: (key: Uint8Array, count: number) => KBucketPeer[];
|
|
18
|
+
closestPeer: (key: Uint8Array) => KBucketPeer;
|
|
19
|
+
remove: (key: Uint8Array) => void;
|
|
20
|
+
add: (peer: KBucketPeer) => void;
|
|
21
|
+
count: () => number;
|
|
22
|
+
toIterable: () => Iterable<KBucket>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/routing-table/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,SAAS,CAAA;AAEjC,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,UAAU,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,UAAU,CAAA;IACd,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,SAAS,EAAE,OAAO,CAAA;IAClB,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,UAAU,CAAA;IACvB,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,EAAE,UAAU,EAAE,WAAW,KAAK,IAAI,KAAK,IAAI,CAAA;IACpG,OAAO,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,KAAK,WAAW,EAAE,CAAA;IAC1D,WAAW,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,WAAW,CAAA;IAC7C,MAAM,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAA;IACjC,GAAG,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAA;IAChC,KAAK,EAAE,MAAM,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAA;CACpC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Providers } from '../../providers';
|
|
2
|
+
import type { PeerId } from '@libp2p/interfaces/peer-id';
|
|
3
|
+
import type { DHTMessageHandler } from '../index.js';
|
|
4
|
+
import type { Message } from '../../message/index.js';
|
|
5
|
+
export interface AddProviderHandlerOptions {
|
|
6
|
+
providers: Providers;
|
|
7
|
+
}
|
|
8
|
+
export declare class AddProviderHandler implements DHTMessageHandler {
|
|
9
|
+
private readonly providers;
|
|
10
|
+
constructor(options: AddProviderHandlerOptions);
|
|
11
|
+
handle(peerId: PeerId, msg: Message): Promise<undefined>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=add-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-provider.d.ts","sourceRoot":"","sources":["../../../../src/rpc/handlers/add-provider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AAIrD,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,SAAS,CAAA;CACrB;AAED,qBAAa,kBAAmB,YAAW,iBAAiB;IAC1D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;gBAExB,OAAO,EAAE,yBAAyB;IAKzC,MAAM,CAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO;CAwC3C"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { CID } from 'multiformats/cid';
|
|
2
|
+
import errcode from 'err-code';
|
|
3
|
+
import { logger } from '@libp2p/logger';
|
|
4
|
+
const log = logger('libp2p:kad-dht:rpc:handlers:add-provider');
|
|
5
|
+
export class AddProviderHandler {
|
|
6
|
+
constructor(options) {
|
|
7
|
+
const { providers } = options;
|
|
8
|
+
this.providers = providers;
|
|
9
|
+
}
|
|
10
|
+
async handle(peerId, msg) {
|
|
11
|
+
log('start');
|
|
12
|
+
if (msg.key == null || msg.key.length === 0) {
|
|
13
|
+
throw errcode(new Error('Missing key'), 'ERR_MISSING_KEY');
|
|
14
|
+
}
|
|
15
|
+
let cid;
|
|
16
|
+
try {
|
|
17
|
+
// this is actually just the multihash, not the whole CID
|
|
18
|
+
cid = CID.decode(msg.key);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
throw errcode(new Error('Invalid CID'), 'ERR_INVALID_CID');
|
|
22
|
+
}
|
|
23
|
+
if (msg.providerPeers == null || msg.providerPeers.length === 0) {
|
|
24
|
+
log.error('no providers found in message');
|
|
25
|
+
}
|
|
26
|
+
await Promise.all(msg.providerPeers.map(async (pi) => {
|
|
27
|
+
// Ignore providers not from the originator
|
|
28
|
+
if (!pi.id.equals(peerId)) {
|
|
29
|
+
log('invalid provider peer %p from %p', pi.id, peerId);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (pi.multiaddrs.length < 1) {
|
|
33
|
+
log('no valid addresses for provider %p. Ignore', peerId);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
log('received provider %p for %s (addrs %s)', peerId, cid, pi.multiaddrs.map((m) => m.toString()));
|
|
37
|
+
await this.providers.addProvider(cid, pi.id);
|
|
38
|
+
}));
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=add-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-provider.js","sourceRoot":"","sources":["../../../../src/rpc/handlers/add-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,OAAO,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAMvC,MAAM,GAAG,GAAG,MAAM,CAAC,0CAA0C,CAAC,CAAA;AAM9D,MAAM,OAAO,kBAAkB;IAG7B,YAAa,OAAkC;QAC7C,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAA;QAC7B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,MAAM,CAAE,MAAc,EAAE,GAAY;QACxC,GAAG,CAAC,OAAO,CAAC,CAAA;QAEZ,IAAI,GAAG,CAAC,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE;YAC3C,MAAM,OAAO,CAAC,IAAI,KAAK,CAAC,aAAa,CAAC,EAAE,iBAAiB,CAAC,CAAA;SAC3D;QAED,IAAI,GAAQ,CAAA;QACZ,IAAI;YACF,yDAAyD;YACzD,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;SAC1B;QAAC,OAAO,GAAQ,EAAE;YACjB,MAAM,OAAO,CAAC,IAAI,KAAK,CAAC,aAAa,CAAC,EAAE,iBAAiB,CAAC,CAAA;SAC3D;QAED,IAAI,GAAG,CAAC,aAAa,IAAI,IAAI,IAAI,GAAG,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE;YAC/D,GAAG,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAA;SAC3C;QAED,MAAM,OAAO,CAAC,GAAG,CACf,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;YACjC,2CAA2C;YAC3C,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;gBACzB,GAAG,CAAC,kCAAkC,EAAE,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;gBACtD,OAAM;aACP;YAED,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;gBAC5B,GAAG,CAAC,4CAA4C,EAAE,MAAM,CAAC,CAAA;gBACzD,OAAM;aACP;YAED,GAAG,CAAC,wCAAwC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;YAElG,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,CAAA;QAC9C,CAAC,CAAC,CACH,CAAA;QAED,OAAO,SAAS,CAAA;IAClB,CAAC;CACF"}
|