@libp2p/peer-store 7.0.2 → 8.0.0

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.
Files changed (76) hide show
  1. package/README.md +0 -170
  2. package/dist/index.min.js +14 -14
  3. package/dist/src/errors.d.ts +0 -1
  4. package/dist/src/errors.d.ts.map +1 -1
  5. package/dist/src/errors.js +1 -2
  6. package/dist/src/errors.js.map +1 -1
  7. package/dist/src/index.d.ts +23 -25
  8. package/dist/src/index.d.ts.map +1 -1
  9. package/dist/src/index.js +86 -88
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/pb/peer.d.ts +28 -9
  12. package/dist/src/pb/peer.d.ts.map +1 -1
  13. package/dist/src/pb/peer.js +147 -31
  14. package/dist/src/pb/peer.js.map +1 -1
  15. package/dist/src/store.d.ts +18 -28
  16. package/dist/src/store.d.ts.map +1 -1
  17. package/dist/src/store.js +77 -147
  18. package/dist/src/store.js.map +1 -1
  19. package/dist/src/utils/bytes-to-peer.d.ts +4 -0
  20. package/dist/src/utils/bytes-to-peer.d.ts.map +1 -0
  21. package/dist/src/utils/bytes-to-peer.js +33 -0
  22. package/dist/src/utils/bytes-to-peer.js.map +1 -0
  23. package/dist/src/utils/dedupe-addresses.d.ts +6 -0
  24. package/dist/src/utils/dedupe-addresses.d.ts.map +1 -0
  25. package/dist/src/utils/dedupe-addresses.js +41 -0
  26. package/dist/src/utils/dedupe-addresses.js.map +1 -0
  27. package/dist/src/utils/peer-data-to-datastore-peer.d.ts +5 -0
  28. package/dist/src/utils/peer-data-to-datastore-peer.d.ts.map +1 -0
  29. package/dist/src/utils/peer-data-to-datastore-peer.js +92 -0
  30. package/dist/src/utils/peer-data-to-datastore-peer.js.map +1 -0
  31. package/dist/src/utils/peer-id-to-datastore-key.d.ts +5 -0
  32. package/dist/src/utils/peer-id-to-datastore-key.d.ts.map +1 -0
  33. package/dist/src/utils/peer-id-to-datastore-key.js +13 -0
  34. package/dist/src/utils/peer-id-to-datastore-key.js.map +1 -0
  35. package/dist/src/utils/to-peer-pb.d.ts +10 -0
  36. package/dist/src/utils/to-peer-pb.d.ts.map +1 -0
  37. package/dist/src/utils/to-peer-pb.js +182 -0
  38. package/dist/src/utils/to-peer-pb.js.map +1 -0
  39. package/dist/typedoc-urls.json +13 -2
  40. package/package.json +8 -10
  41. package/src/errors.ts +1 -2
  42. package/src/index.ts +97 -103
  43. package/src/pb/peer.proto +10 -7
  44. package/src/pb/peer.ts +187 -37
  45. package/src/store.ts +102 -189
  46. package/src/utils/bytes-to-peer.ts +41 -0
  47. package/src/utils/dedupe-addresses.ts +51 -0
  48. package/src/utils/peer-data-to-datastore-peer.ts +116 -0
  49. package/src/utils/peer-id-to-datastore-key.ts +15 -0
  50. package/src/utils/to-peer-pb.ts +237 -0
  51. package/dist/src/address-book.d.ts +0 -29
  52. package/dist/src/address-book.d.ts.map +0 -1
  53. package/dist/src/address-book.js +0 -304
  54. package/dist/src/address-book.js.map +0 -1
  55. package/dist/src/key-book.d.ts +0 -21
  56. package/dist/src/key-book.d.ts.map +0 -1
  57. package/dist/src/key-book.js +0 -121
  58. package/dist/src/key-book.js.map +0 -1
  59. package/dist/src/metadata-book.d.ts +0 -28
  60. package/dist/src/metadata-book.d.ts.map +0 -1
  61. package/dist/src/metadata-book.js +0 -211
  62. package/dist/src/metadata-book.js.map +0 -1
  63. package/dist/src/pb/tags.d.ts +0 -21
  64. package/dist/src/pb/tags.d.ts.map +0 -1
  65. package/dist/src/pb/tags.js +0 -111
  66. package/dist/src/pb/tags.js.map +0 -1
  67. package/dist/src/proto-book.d.ts +0 -18
  68. package/dist/src/proto-book.d.ts.map +0 -1
  69. package/dist/src/proto-book.js +0 -199
  70. package/dist/src/proto-book.js.map +0 -1
  71. package/src/address-book.ts +0 -367
  72. package/src/key-book.ts +0 -140
  73. package/src/metadata-book.ts +0 -244
  74. package/src/pb/tags.proto +0 -11
  75. package/src/pb/tags.ts +0 -145
  76. package/src/proto-book.ts +0 -234
@@ -1,199 +0,0 @@
1
- import { logger } from '@libp2p/logger';
2
- import { CodeError } from '@libp2p/interfaces/errors';
3
- import { codes } from './errors.js';
4
- import { peerIdFromPeerId } from '@libp2p/peer-id';
5
- import { CustomEvent } from '@libp2p/interfaces/events';
6
- const log = logger('libp2p:peer-store:proto-book');
7
- const EVENT_NAME = 'change:protocols';
8
- export class PeerStoreProtoBook {
9
- /**
10
- * The ProtoBook is responsible for keeping the known supported
11
- * protocols of a peer
12
- */
13
- constructor(dispatchEvent, store) {
14
- this.dispatchEvent = dispatchEvent;
15
- this.store = store;
16
- }
17
- async get(peerId) {
18
- log.trace('get wait for read lock');
19
- const release = await this.store.lock.readLock();
20
- log.trace('get got read lock');
21
- try {
22
- const peer = await this.store.load(peerId);
23
- return peer.protocols;
24
- }
25
- catch (err) {
26
- if (err.code !== codes.ERR_NOT_FOUND) {
27
- throw err;
28
- }
29
- }
30
- finally {
31
- log.trace('get release read lock');
32
- release();
33
- }
34
- return [];
35
- }
36
- async set(peerId, protocols) {
37
- peerId = peerIdFromPeerId(peerId);
38
- if (!Array.isArray(protocols)) {
39
- log.error('protocols must be provided to store data');
40
- throw new CodeError('protocols must be provided', codes.ERR_INVALID_PARAMETERS);
41
- }
42
- log.trace('set await write lock');
43
- const release = await this.store.lock.writeLock();
44
- log.trace('set got write lock');
45
- let peer;
46
- let updatedPeer;
47
- try {
48
- try {
49
- peer = await this.store.load(peerId);
50
- if (new Set([
51
- ...protocols
52
- ]).size === peer.protocols.length) {
53
- return;
54
- }
55
- }
56
- catch (err) {
57
- if (err.code !== codes.ERR_NOT_FOUND) {
58
- throw err;
59
- }
60
- }
61
- updatedPeer = await this.store.patchOrCreate(peerId, {
62
- protocols
63
- });
64
- log('stored provided protocols for %p', peerId);
65
- }
66
- finally {
67
- log.trace('set release write lock');
68
- release();
69
- }
70
- this.dispatchEvent(new CustomEvent(EVENT_NAME, {
71
- detail: {
72
- peerId,
73
- protocols: updatedPeer.protocols,
74
- oldProtocols: peer == null ? [] : peer.protocols
75
- }
76
- }));
77
- }
78
- async add(peerId, protocols) {
79
- peerId = peerIdFromPeerId(peerId);
80
- if (!Array.isArray(protocols)) {
81
- log.error('protocols must be provided to store data');
82
- throw new CodeError('protocols must be provided', codes.ERR_INVALID_PARAMETERS);
83
- }
84
- log.trace('add await write lock');
85
- const release = await this.store.lock.writeLock();
86
- log.trace('add got write lock');
87
- let peer;
88
- let updatedPeer;
89
- try {
90
- try {
91
- peer = await this.store.load(peerId);
92
- if (new Set([
93
- ...peer.protocols,
94
- ...protocols
95
- ]).size === peer.protocols.length) {
96
- return;
97
- }
98
- }
99
- catch (err) {
100
- if (err.code !== codes.ERR_NOT_FOUND) {
101
- throw err;
102
- }
103
- }
104
- updatedPeer = await this.store.mergeOrCreate(peerId, {
105
- protocols
106
- });
107
- log('added provided protocols for %p', peerId);
108
- }
109
- finally {
110
- log.trace('add release write lock');
111
- release();
112
- }
113
- this.dispatchEvent(new CustomEvent(EVENT_NAME, {
114
- detail: {
115
- peerId,
116
- protocols: updatedPeer.protocols,
117
- oldProtocols: peer == null ? [] : peer.protocols
118
- }
119
- }));
120
- }
121
- async remove(peerId, protocols) {
122
- peerId = peerIdFromPeerId(peerId);
123
- if (!Array.isArray(protocols)) {
124
- log.error('protocols must be provided to store data');
125
- throw new CodeError('protocols must be provided', codes.ERR_INVALID_PARAMETERS);
126
- }
127
- log.trace('remove await write lock');
128
- const release = await this.store.lock.writeLock();
129
- log.trace('remove got write lock');
130
- let peer;
131
- let updatedPeer;
132
- try {
133
- try {
134
- peer = await this.store.load(peerId);
135
- const protocolSet = new Set(peer.protocols);
136
- for (const protocol of protocols) {
137
- protocolSet.delete(protocol);
138
- }
139
- if (peer.protocols.length === protocolSet.size) {
140
- return;
141
- }
142
- protocols = Array.from(protocolSet);
143
- }
144
- catch (err) {
145
- if (err.code !== codes.ERR_NOT_FOUND) {
146
- throw err;
147
- }
148
- }
149
- updatedPeer = await this.store.patchOrCreate(peerId, {
150
- protocols
151
- });
152
- }
153
- finally {
154
- log.trace('remove release write lock');
155
- release();
156
- }
157
- this.dispatchEvent(new CustomEvent(EVENT_NAME, {
158
- detail: {
159
- peerId,
160
- protocols: updatedPeer.protocols,
161
- oldProtocols: peer == null ? [] : peer.protocols
162
- }
163
- }));
164
- }
165
- async delete(peerId) {
166
- peerId = peerIdFromPeerId(peerId);
167
- log.trace('delete await write lock');
168
- const release = await this.store.lock.writeLock();
169
- log.trace('delete got write lock');
170
- let peer;
171
- try {
172
- try {
173
- peer = await this.store.load(peerId);
174
- }
175
- catch (err) {
176
- if (err.code !== codes.ERR_NOT_FOUND) {
177
- throw err;
178
- }
179
- }
180
- await this.store.patchOrCreate(peerId, {
181
- protocols: []
182
- });
183
- }
184
- finally {
185
- log.trace('delete release write lock');
186
- release();
187
- }
188
- if (peer != null) {
189
- this.dispatchEvent(new CustomEvent(EVENT_NAME, {
190
- detail: {
191
- peerId,
192
- protocols: [],
193
- oldProtocols: peer.protocols
194
- }
195
- }));
196
- }
197
- }
198
- }
199
- //# sourceMappingURL=proto-book.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"proto-book.js","sourceRoot":"","sources":["../../src/proto-book.ts"],"names":[],"mappings":"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"}
@@ -1,367 +0,0 @@
1
- import { logger } from '@libp2p/logger'
2
- import { CodeError } from '@libp2p/interfaces/errors'
3
- import { isMultiaddr } from '@multiformats/multiaddr'
4
- import { codes } from './errors.js'
5
- import { PeerRecord, RecordEnvelope } from '@libp2p/peer-record'
6
- import { peerIdFromPeerId } from '@libp2p/peer-id'
7
- import { CustomEvent } from '@libp2p/interfaces/events'
8
- import type { Address, AddressFilter, Peer, PeerMultiaddrsChangeData, PeerStore } from '@libp2p/interface-peer-store'
9
- import type { Store } from './store.js'
10
- import type { Envelope } from '@libp2p/interface-record'
11
- import type { PeerId } from '@libp2p/interface-peer-id'
12
- import type { PeerInfo } from '@libp2p/interface-peer-info'
13
- import type { Multiaddr } from '@multiformats/multiaddr'
14
-
15
- const log = logger('libp2p:peer-store:address-book')
16
- const EVENT_NAME = 'change:multiaddrs'
17
-
18
- async function allowAll (): Promise<boolean> {
19
- return true
20
- }
21
-
22
- export class PeerStoreAddressBook {
23
- private readonly dispatchEvent: PeerStore['dispatchEvent']
24
- private readonly store: Store
25
- private readonly addressFilter: AddressFilter
26
-
27
- constructor (dispatchEvent: PeerStore['dispatchEvent'], store: Store, addressFilter?: AddressFilter) {
28
- this.dispatchEvent = dispatchEvent
29
- this.store = store
30
- this.addressFilter = addressFilter ?? allowAll
31
- }
32
-
33
- /**
34
- * ConsumePeerRecord adds addresses from a signed peer record contained in a record envelope.
35
- * This will return a boolean that indicates if the record was successfully processed and added
36
- * into the AddressBook.
37
- */
38
- async consumePeerRecord (envelope: Envelope): Promise<boolean> {
39
- log.trace('consumePeerRecord await write lock')
40
- const release = await this.store.lock.writeLock()
41
- log.trace('consumePeerRecord got write lock')
42
-
43
- let peerId
44
- let peer: Peer | undefined
45
- let updatedPeer
46
-
47
- try {
48
- let peerRecord
49
- try {
50
- peerRecord = PeerRecord.createFromProtobuf(envelope.payload)
51
- } catch (err: any) {
52
- log.error('invalid peer record received')
53
- return false
54
- }
55
-
56
- peerId = peerRecord.peerId
57
- const multiaddrs = peerRecord.multiaddrs
58
-
59
- // Verify peerId
60
- if (!peerId.equals(envelope.peerId)) {
61
- log('signing key does not match PeerId in the PeerRecord')
62
- return false
63
- }
64
-
65
- // ensure the record has multiaddrs
66
- if (multiaddrs == null || multiaddrs.length === 0) {
67
- return false
68
- }
69
-
70
- if (await this.store.has(peerId)) {
71
- peer = await this.store.load(peerId)
72
-
73
- if (peer.peerRecordEnvelope != null) {
74
- const storedEnvelope = await RecordEnvelope.createFromProtobuf(peer.peerRecordEnvelope)
75
- const storedRecord = PeerRecord.createFromProtobuf(storedEnvelope.payload)
76
-
77
- // ensure seq is greater than, or equal to, the last received
78
- if (storedRecord.seqNumber >= peerRecord.seqNumber) {
79
- log('sequence number was lower or equal to existing sequence number - stored: %d received: %d', storedRecord.seqNumber, peerRecord.seqNumber)
80
- return false
81
- }
82
- }
83
- }
84
-
85
- const addresses = await filterMultiaddrs(peerId, multiaddrs, this.addressFilter, true)
86
-
87
- // Replace unsigned addresses by the new ones from the record
88
- // TODO: Once we have ttls for the addresses, we should merge these in
89
- updatedPeer = await this.store.patchOrCreate(peerId, {
90
- addresses,
91
- peerRecordEnvelope: envelope.marshal().subarray()
92
- })
93
-
94
- log('stored provided peer record for %p', peerRecord.peerId)
95
- } finally {
96
- log.trace('consumePeerRecord release write lock')
97
- release()
98
- }
99
-
100
- this.dispatchEvent(new CustomEvent<PeerMultiaddrsChangeData>(EVENT_NAME, {
101
- detail: {
102
- peerId,
103
- multiaddrs: updatedPeer.addresses.map(({ multiaddr }) => multiaddr),
104
- oldMultiaddrs: peer == null ? [] : peer.addresses.map(({ multiaddr }) => multiaddr)
105
- }
106
- }))
107
-
108
- return true
109
- }
110
-
111
- async getRawEnvelope (peerId: PeerId): Promise<Uint8Array | undefined> {
112
- log.trace('getRawEnvelope await read lock')
113
- const release = await this.store.lock.readLock()
114
- log.trace('getRawEnvelope got read lock')
115
-
116
- try {
117
- const peer = await this.store.load(peerId)
118
-
119
- return peer.peerRecordEnvelope
120
- } catch (err: any) {
121
- if (err.code !== codes.ERR_NOT_FOUND) {
122
- throw err
123
- }
124
- } finally {
125
- log.trace('getRawEnvelope release read lock')
126
- release()
127
- }
128
- }
129
-
130
- /**
131
- * Get an Envelope containing a PeerRecord for the given peer.
132
- * Returns undefined if no record exists.
133
- */
134
- async getPeerRecord (peerId: PeerId): Promise<RecordEnvelope | undefined> {
135
- const raw = await this.getRawEnvelope(peerId)
136
-
137
- if (raw == null) {
138
- return undefined
139
- }
140
-
141
- return await RecordEnvelope.createFromProtobuf(raw)
142
- }
143
-
144
- async get (peerId: PeerId): Promise<Address[]> {
145
- peerId = peerIdFromPeerId(peerId)
146
-
147
- log.trace('get wait for read lock')
148
- const release = await this.store.lock.readLock()
149
- log.trace('get got read lock')
150
-
151
- try {
152
- const peer = await this.store.load(peerId)
153
-
154
- return peer.addresses
155
- } catch (err: any) {
156
- if (err.code !== codes.ERR_NOT_FOUND) {
157
- throw err
158
- }
159
- } finally {
160
- log.trace('get release read lock')
161
- release()
162
- }
163
-
164
- return []
165
- }
166
-
167
- async set (peerId: PeerId, multiaddrs: Multiaddr[]): Promise<void> {
168
- peerId = peerIdFromPeerId(peerId)
169
-
170
- if (!Array.isArray(multiaddrs)) {
171
- log.error('multiaddrs must be an array of Multiaddrs')
172
- throw new CodeError('multiaddrs must be an array of Multiaddrs', codes.ERR_INVALID_PARAMETERS)
173
- }
174
-
175
- log.trace('set await write lock')
176
- const release = await this.store.lock.writeLock()
177
- log.trace('set got write lock')
178
-
179
- let hasPeer = false
180
- let peer: Peer | undefined
181
- let updatedPeer
182
-
183
- try {
184
- const addresses = await filterMultiaddrs(peerId, multiaddrs, this.addressFilter)
185
-
186
- // No valid addresses found
187
- if (addresses.length === 0) {
188
- return
189
- }
190
-
191
- try {
192
- peer = await this.store.load(peerId)
193
- hasPeer = true
194
-
195
- if (new Set([
196
- ...addresses.map(({ multiaddr }) => multiaddr.toString()),
197
- ...peer.addresses.map(({ multiaddr }) => multiaddr.toString())
198
- ]).size === peer.addresses.length && addresses.length === peer.addresses.length) {
199
- // not changing anything, no need to update
200
- return
201
- }
202
- } catch (err: any) {
203
- if (err.code !== codes.ERR_NOT_FOUND) {
204
- throw err
205
- }
206
- }
207
-
208
- updatedPeer = await this.store.patchOrCreate(peerId, { addresses })
209
-
210
- log('set multiaddrs for %p', peerId)
211
- } finally {
212
- log.trace('set multiaddrs for %p', peerId)
213
- log('set release write lock')
214
- release()
215
- }
216
-
217
- this.dispatchEvent(new CustomEvent<PeerMultiaddrsChangeData>(EVENT_NAME, {
218
- detail: {
219
- peerId,
220
- multiaddrs: updatedPeer.addresses.map(addr => addr.multiaddr),
221
- oldMultiaddrs: peer == null ? [] : peer.addresses.map(({ multiaddr }) => multiaddr)
222
- }
223
- }))
224
-
225
- // Notify the existence of a new peer
226
- if (!hasPeer) {
227
- this.dispatchEvent(new CustomEvent<PeerInfo>('peer', {
228
- detail: {
229
- id: peerId,
230
- multiaddrs: updatedPeer.addresses.map(addr => addr.multiaddr),
231
- protocols: updatedPeer.protocols
232
- }
233
- }))
234
- }
235
- }
236
-
237
- async add (peerId: PeerId, multiaddrs: Multiaddr[]): Promise<void> {
238
- peerId = peerIdFromPeerId(peerId)
239
-
240
- if (!Array.isArray(multiaddrs)) {
241
- log.error('multiaddrs must be an array of Multiaddrs')
242
- throw new CodeError('multiaddrs must be an array of Multiaddrs', codes.ERR_INVALID_PARAMETERS)
243
- }
244
-
245
- log.trace('add await write lock')
246
- const release = await this.store.lock.writeLock()
247
- log.trace('add got write lock')
248
-
249
- let hasPeer = false
250
- let peer: Peer | undefined
251
- let updatedPeer
252
-
253
- try {
254
- const addresses = await filterMultiaddrs(peerId, multiaddrs, this.addressFilter)
255
-
256
- // No valid addresses found
257
- if (addresses.length === 0) {
258
- return
259
- }
260
-
261
- try {
262
- peer = await this.store.load(peerId)
263
- hasPeer = true
264
-
265
- if (new Set([
266
- ...addresses.map(({ multiaddr }) => multiaddr.toString()),
267
- ...peer.addresses.map(({ multiaddr }) => multiaddr.toString())
268
- ]).size === peer.addresses.length) {
269
- return
270
- }
271
- } catch (err: any) {
272
- if (err.code !== codes.ERR_NOT_FOUND) {
273
- throw err
274
- }
275
- }
276
-
277
- updatedPeer = await this.store.mergeOrCreate(peerId, { addresses })
278
-
279
- log('added multiaddrs for %p', peerId)
280
- } finally {
281
- log.trace('set release write lock')
282
- release()
283
- }
284
-
285
- this.dispatchEvent(new CustomEvent<PeerMultiaddrsChangeData>(EVENT_NAME, {
286
- detail: {
287
- peerId,
288
- multiaddrs: updatedPeer.addresses.map(addr => addr.multiaddr),
289
- oldMultiaddrs: peer == null ? [] : peer.addresses.map(({ multiaddr }) => multiaddr)
290
- }
291
- }))
292
-
293
- // Notify the existence of a new peer
294
- if (!hasPeer) {
295
- this.dispatchEvent(new CustomEvent<PeerInfo>('peer', {
296
- detail: {
297
- id: peerId,
298
- multiaddrs: updatedPeer.addresses.map(addr => addr.multiaddr),
299
- protocols: updatedPeer.protocols
300
- }
301
- }))
302
- }
303
- }
304
-
305
- async delete (peerId: PeerId): Promise<void> {
306
- peerId = peerIdFromPeerId(peerId)
307
-
308
- log.trace('delete await write lock')
309
- const release = await this.store.lock.writeLock()
310
- log.trace('delete got write lock')
311
-
312
- let peer: Peer | undefined
313
-
314
- try {
315
- try {
316
- peer = await this.store.load(peerId)
317
- } catch (err: any) {
318
- if (err.code !== codes.ERR_NOT_FOUND) {
319
- throw err
320
- }
321
- }
322
-
323
- await this.store.patchOrCreate(peerId, {
324
- addresses: []
325
- })
326
- } finally {
327
- log.trace('delete release write lock')
328
- release()
329
- }
330
-
331
- if (peer != null) {
332
- this.dispatchEvent(new CustomEvent<PeerMultiaddrsChangeData>(EVENT_NAME, {
333
- detail: {
334
- peerId,
335
- multiaddrs: [],
336
- oldMultiaddrs: peer == null ? [] : peer.addresses.map(({ multiaddr }) => multiaddr)
337
- }
338
- }))
339
- }
340
- }
341
- }
342
-
343
- async function filterMultiaddrs (peerId: PeerId, multiaddrs: Multiaddr[], addressFilter: AddressFilter, isCertified: boolean = false): Promise<Address[]> {
344
- const output: Address[] = []
345
-
346
- await Promise.all(
347
- multiaddrs.map(async multiaddr => {
348
- if (!isMultiaddr(multiaddr)) {
349
- log.error('multiaddr must be an instance of Multiaddr')
350
- throw new CodeError('multiaddr must be an instance of Multiaddr', codes.ERR_INVALID_PARAMETERS)
351
- }
352
-
353
- const include = await addressFilter(peerId, multiaddr)
354
-
355
- if (!include) {
356
- return
357
- }
358
-
359
- output.push({
360
- multiaddr,
361
- isCertified
362
- })
363
- })
364
- )
365
-
366
- return output
367
- }