@libp2p/peer-store 11.2.1 → 11.2.2-3528df829

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/src/index.ts CHANGED
@@ -4,12 +4,13 @@
4
4
  * The peer store is where libp2p stores data about the peers it has encountered on the network.
5
5
  */
6
6
 
7
+ import { isPeerId } from '@libp2p/interface'
7
8
  import { peerIdFromCID } from '@libp2p/peer-id'
8
9
  import { RecordEnvelope, PeerRecord } from '@libp2p/peer-record'
9
10
  import all from 'it-all'
10
11
  import { PersistentStore } from './store.js'
11
12
  import type { PeerUpdate } from './store.js'
12
- import type { ComponentLogger, Libp2pEvents, Logger, TypedEventTarget, PeerId, PeerStore, Peer, PeerData, PeerQuery, PeerInfo } from '@libp2p/interface'
13
+ import type { ComponentLogger, Libp2pEvents, Logger, TypedEventTarget, PeerId, PeerStore, Peer, PeerData, PeerQuery, PeerInfo, AbortOptions, ConsumePeerRecordOptions } from '@libp2p/interface'
13
14
  import type { Multiaddr } from '@multiformats/multiaddr'
14
15
  import type { Datastore } from 'interface-datastore'
15
16
 
@@ -24,7 +25,7 @@ export interface PersistentPeerStoreComponents {
24
25
  * Return true to allow storing the passed multiaddr for the passed peer
25
26
  */
26
27
  export interface AddressFilter {
27
- (peerId: PeerId, multiaddr: Multiaddr): Promise<boolean> | boolean
28
+ (peerId: PeerId, multiaddr: Multiaddr, options?: AbortOptions): Promise<boolean> | boolean
28
29
  }
29
30
 
30
31
  export interface PersistentPeerStoreInit {
@@ -74,74 +75,60 @@ class PersistentPeerStore implements PeerStore {
74
75
  readonly [Symbol.toStringTag] = '@libp2p/peer-store'
75
76
 
76
77
  async forEach (fn: (peer: Peer,) => void, query?: PeerQuery): Promise<void> {
77
- this.log.trace('forEach await read lock')
78
- const release = await this.store.lock.readLock()
79
- this.log.trace('forEach got read lock')
78
+ const release = await this.store.lock.readLock(query)
80
79
 
81
80
  try {
82
81
  for await (const peer of this.store.all(query)) {
83
82
  fn(peer)
84
83
  }
85
84
  } finally {
86
- this.log.trace('forEach release read lock')
87
85
  release()
88
86
  }
89
87
  }
90
88
 
91
89
  async all (query?: PeerQuery): Promise<Peer[]> {
92
- this.log.trace('all await read lock')
93
- const release = await this.store.lock.readLock()
94
- this.log.trace('all got read lock')
90
+ const release = await this.store.lock.readLock(query)
95
91
 
96
92
  try {
97
93
  return await all(this.store.all(query))
98
94
  } finally {
99
- this.log.trace('all release read lock')
100
95
  release()
101
96
  }
102
97
  }
103
98
 
104
- async delete (peerId: PeerId): Promise<void> {
105
- this.log.trace('delete await write lock')
106
- const release = await this.store.lock.writeLock()
107
- this.log.trace('delete got write lock')
99
+ async delete (peerId: PeerId, options?: AbortOptions): Promise<void> {
100
+ const release = await this.store.lock.writeLock(options)
108
101
 
109
102
  try {
110
- await this.store.delete(peerId)
103
+ await this.store.delete(peerId, options)
111
104
  } finally {
112
- this.log.trace('delete release write lock')
113
105
  release()
114
106
  }
115
107
  }
116
108
 
117
- async has (peerId: PeerId): Promise<boolean> {
118
- this.log.trace('has await read lock')
119
- const release = await this.store.lock.readLock()
120
- this.log.trace('has got read lock')
109
+ async has (peerId: PeerId, options?: AbortOptions): Promise<boolean> {
110
+ const release = await this.store.lock.readLock(options)
121
111
 
122
112
  try {
123
- return await this.store.has(peerId)
113
+ return await this.store.has(peerId, options)
124
114
  } finally {
125
115
  this.log.trace('has release read lock')
126
116
  release()
127
117
  }
128
118
  }
129
119
 
130
- async get (peerId: PeerId): Promise<Peer> {
131
- this.log.trace('get await read lock')
132
- const release = await this.store.lock.readLock()
133
- this.log.trace('get got read lock')
120
+ async get (peerId: PeerId, options?: AbortOptions): Promise<Peer> {
121
+ const release = await this.store.lock.readLock(options)
134
122
 
135
123
  try {
136
- return await this.store.load(peerId)
124
+ return await this.store.load(peerId, options)
137
125
  } finally {
138
- this.log.trace('get release read lock')
139
126
  release()
140
127
  }
141
128
  }
142
129
 
143
- async getInfo (peerId: PeerId): Promise<PeerInfo> {
144
- const peer = await this.get(peerId)
130
+ async getInfo (peerId: PeerId, options?: AbortOptions): Promise<PeerInfo> {
131
+ const peer = await this.get(peerId, options)
145
132
 
146
133
  return {
147
134
  id: peer.id,
@@ -149,59 +136,55 @@ class PersistentPeerStore implements PeerStore {
149
136
  }
150
137
  }
151
138
 
152
- async save (id: PeerId, data: PeerData): Promise<Peer> {
153
- this.log.trace('save await write lock')
154
- const release = await this.store.lock.writeLock()
155
- this.log.trace('save got write lock')
139
+ async save (id: PeerId, data: PeerData, options?: AbortOptions): Promise<Peer> {
140
+ const release = await this.store.lock.writeLock(options)
156
141
 
157
142
  try {
158
- const result = await this.store.save(id, data)
143
+ const result = await this.store.save(id, data, options)
159
144
 
160
145
  this.#emitIfUpdated(id, result)
161
146
 
162
147
  return result.peer
163
148
  } finally {
164
- this.log.trace('save release write lock')
165
149
  release()
166
150
  }
167
151
  }
168
152
 
169
- async patch (id: PeerId, data: PeerData): Promise<Peer> {
170
- this.log.trace('patch await write lock')
171
- const release = await this.store.lock.writeLock()
172
- this.log.trace('patch got write lock')
153
+ async patch (id: PeerId, data: PeerData, options?: AbortOptions): Promise<Peer> {
154
+ const release = await this.store.lock.writeLock(options)
173
155
 
174
156
  try {
175
- const result = await this.store.patch(id, data)
157
+ const result = await this.store.patch(id, data, options)
176
158
 
177
159
  this.#emitIfUpdated(id, result)
178
160
 
179
161
  return result.peer
180
162
  } finally {
181
- this.log.trace('patch release write lock')
182
163
  release()
183
164
  }
184
165
  }
185
166
 
186
- async merge (id: PeerId, data: PeerData): Promise<Peer> {
187
- this.log.trace('merge await write lock')
188
- const release = await this.store.lock.writeLock()
189
- this.log.trace('merge got write lock')
167
+ async merge (id: PeerId, data: PeerData, options?: AbortOptions): Promise<Peer> {
168
+ const release = await this.store.lock.writeLock(options)
190
169
 
191
170
  try {
192
- const result = await this.store.merge(id, data)
171
+ const result = await this.store.merge(id, data, options)
193
172
 
194
173
  this.#emitIfUpdated(id, result)
195
174
 
196
175
  return result.peer
197
176
  } finally {
198
- this.log.trace('merge release write lock')
199
177
  release()
200
178
  }
201
179
  }
202
180
 
203
- async consumePeerRecord (buf: Uint8Array, expectedPeer?: PeerId): Promise<boolean> {
204
- const envelope = await RecordEnvelope.openAndCertify(buf, PeerRecord.DOMAIN)
181
+ async consumePeerRecord (buf: Uint8Array, options?: ConsumePeerRecordOptions): Promise<boolean>
182
+ async consumePeerRecord (buf: Uint8Array, expectedPeer?: PeerId, options?: AbortOptions): Promise<boolean>
183
+ async consumePeerRecord (buf: Uint8Array, arg1?: any, arg2?: any): Promise<boolean> {
184
+ const expectedPeer: PeerId | undefined = isPeerId(arg1) ? arg1 : isPeerId(arg1?.expectedPeer) ? arg1.expectedPeer : undefined
185
+ const options: AbortOptions | undefined = isPeerId(arg1) ? arg2 : arg1 === undefined ? arg2 : arg1
186
+
187
+ const envelope = await RecordEnvelope.openAndCertify(buf, PeerRecord.DOMAIN, options)
205
188
  const peerId = peerIdFromCID(envelope.publicKey.toCID())
206
189
 
207
190
  if (expectedPeer?.equals(peerId) === false) {
@@ -213,7 +196,7 @@ class PersistentPeerStore implements PeerStore {
213
196
  let peer: Peer | undefined
214
197
 
215
198
  try {
216
- peer = await this.get(peerId)
199
+ peer = await this.get(peerId, options)
217
200
  } catch (err: any) {
218
201
  if (err.name !== 'NotFoundError') {
219
202
  throw err
@@ -222,7 +205,7 @@ class PersistentPeerStore implements PeerStore {
222
205
 
223
206
  // ensure seq is greater than, or equal to, the last received
224
207
  if (peer?.peerRecordEnvelope != null) {
225
- const storedEnvelope = await RecordEnvelope.createFromProtobuf(peer.peerRecordEnvelope)
208
+ const storedEnvelope = RecordEnvelope.createFromProtobuf(peer.peerRecordEnvelope)
226
209
  const storedRecord = PeerRecord.createFromProtobuf(storedEnvelope.payload)
227
210
 
228
211
  if (storedRecord.seqNumber >= peerRecord.seqNumber) {
@@ -237,7 +220,7 @@ class PersistentPeerStore implements PeerStore {
237
220
  isCertified: true,
238
221
  multiaddr
239
222
  }))
240
- })
223
+ }, options)
241
224
 
242
225
  return true
243
226
  }
package/src/store.ts CHANGED
@@ -11,6 +11,7 @@ import { NAMESPACE_COMMON, peerIdToDatastoreKey } from './utils/peer-id-to-datas
11
11
  import { toPeerPB } from './utils/to-peer-pb.js'
12
12
  import type { AddressFilter, PersistentPeerStoreComponents, PersistentPeerStoreInit } from './index.js'
13
13
  import type { PeerUpdate as PeerUpdateExternal, PeerId, Peer, PeerData, PeerQuery, Logger } from '@libp2p/interface'
14
+ import type { AbortOptions } from '@multiformats/multiaddr'
14
15
  import type { Datastore, Key, Query } from 'interface-datastore'
15
16
  import type { Mortice } from 'mortice'
16
17
 
@@ -74,9 +75,9 @@ export class PersistentStore {
74
75
  this.maxPeerAge = init.maxPeerAge ?? MAX_PEER_AGE
75
76
  }
76
77
 
77
- async has (peerId: PeerId): Promise<boolean> {
78
+ async has (peerId: PeerId, options?: AbortOptions): Promise<boolean> {
78
79
  try {
79
- await this.load(peerId)
80
+ await this.load(peerId, options)
80
81
 
81
82
  return true
82
83
  } catch (err: any) {
@@ -88,41 +89,43 @@ export class PersistentStore {
88
89
  return false
89
90
  }
90
91
 
91
- async delete (peerId: PeerId): Promise<void> {
92
+ async delete (peerId: PeerId, options?: AbortOptions): Promise<void> {
92
93
  if (this.peerId.equals(peerId)) {
93
94
  return
94
95
  }
95
96
 
96
- await this.datastore.delete(peerIdToDatastoreKey(peerId))
97
+ await this.datastore.delete(peerIdToDatastoreKey(peerId), options)
97
98
  }
98
99
 
99
- async load (peerId: PeerId): Promise<Peer> {
100
+ async load (peerId: PeerId, options?: AbortOptions): Promise<Peer> {
100
101
  const key = peerIdToDatastoreKey(peerId)
101
- const buf = await this.datastore.get(key)
102
+ const buf = await this.datastore.get(key, options)
102
103
  const peer = PeerPB.decode(buf)
103
104
 
104
105
  if (this.#peerIsExpired(peerId, peer)) {
105
- await this.datastore.delete(key)
106
+ await this.datastore.delete(key, options)
106
107
  throw new NotFoundError()
107
108
  }
108
109
 
109
110
  return pbToPeer(peerId, peer, this.peerId.equals(peerId) ? Infinity : this.maxAddressAge)
110
111
  }
111
112
 
112
- async save (peerId: PeerId, data: PeerData): Promise<PeerUpdate> {
113
- const existingPeer = await this.#findExistingPeer(peerId)
113
+ async save (peerId: PeerId, data: PeerData, options?: AbortOptions): Promise<PeerUpdate> {
114
+ const existingPeer = await this.#findExistingPeer(peerId, options)
114
115
 
115
116
  const peerPb: PeerPB = await toPeerPB(peerId, data, 'patch', {
117
+ ...options,
116
118
  addressFilter: this.addressFilter
117
119
  })
118
120
 
119
121
  return this.#saveIfDifferent(peerId, peerPb, existingPeer)
120
122
  }
121
123
 
122
- async patch (peerId: PeerId, data: Partial<PeerData>): Promise<PeerUpdate> {
123
- const existingPeer = await this.#findExistingPeer(peerId)
124
+ async patch (peerId: PeerId, data: Partial<PeerData>, options?: AbortOptions): Promise<PeerUpdate> {
125
+ const existingPeer = await this.#findExistingPeer(peerId, options)
124
126
 
125
127
  const peerPb: PeerPB = await toPeerPB(peerId, data, 'patch', {
128
+ ...options,
126
129
  addressFilter: this.addressFilter,
127
130
  existingPeer
128
131
  })
@@ -130,8 +133,8 @@ export class PersistentStore {
130
133
  return this.#saveIfDifferent(peerId, peerPb, existingPeer)
131
134
  }
132
135
 
133
- async merge (peerId: PeerId, data: PeerData): Promise<PeerUpdate> {
134
- const existingPeer = await this.#findExistingPeer(peerId)
136
+ async merge (peerId: PeerId, data: PeerData, options?: AbortOptions): Promise<PeerUpdate> {
137
+ const existingPeer = await this.#findExistingPeer(peerId, options)
135
138
 
136
139
  const peerPb: PeerPB = await toPeerPB(peerId, data, 'merge', {
137
140
  addressFilter: this.addressFilter,
@@ -141,8 +144,8 @@ export class PersistentStore {
141
144
  return this.#saveIfDifferent(peerId, peerPb, existingPeer)
142
145
  }
143
146
 
144
- async * all (query?: PeerQuery): AsyncGenerator<Peer, void, unknown> {
145
- for await (const { key, value } of this.datastore.query(mapQuery(query ?? {}, this.maxAddressAge))) {
147
+ async * all (options?: PeerQuery): AsyncGenerator<Peer, void, unknown> {
148
+ for await (const { key, value } of this.datastore.query(mapQuery(options ?? {}, this.maxAddressAge), options)) {
146
149
  const peerId = keyToPeerId(key)
147
150
 
148
151
  // skip self peer if present
@@ -154,7 +157,7 @@ export class PersistentStore {
154
157
 
155
158
  // remove expired peer
156
159
  if (this.#peerIsExpired(peerId, peer)) {
157
- await this.datastore.delete(key)
160
+ await this.datastore.delete(key, options)
158
161
  continue
159
162
  }
160
163
 
@@ -162,15 +165,15 @@ export class PersistentStore {
162
165
  }
163
166
  }
164
167
 
165
- async #findExistingPeer (peerId: PeerId): Promise<ExistingPeer | undefined> {
168
+ async #findExistingPeer (peerId: PeerId, options?: AbortOptions): Promise<ExistingPeer | undefined> {
166
169
  try {
167
170
  const key = peerIdToDatastoreKey(peerId)
168
- const buf = await this.datastore.get(key)
171
+ const buf = await this.datastore.get(key, options)
169
172
  const peerPB = PeerPB.decode(buf)
170
173
 
171
174
  // remove expired peer
172
175
  if (this.#peerIsExpired(peerId, peerPB)) {
173
- await this.datastore.delete(key)
176
+ await this.datastore.delete(key, options)
174
177
  throw new NotFoundError()
175
178
  }
176
179
 
@@ -185,12 +188,12 @@ export class PersistentStore {
185
188
  }
186
189
  }
187
190
 
188
- async #saveIfDifferent (peerId: PeerId, peer: PeerPB, existingPeer?: ExistingPeer): Promise<PeerUpdate> {
191
+ async #saveIfDifferent (peerId: PeerId, peer: PeerPB, existingPeer?: ExistingPeer, options?: AbortOptions): Promise<PeerUpdate> {
189
192
  // record last update
190
193
  peer.updated = Date.now()
191
194
  const buf = PeerPB.encode(peer)
192
195
 
193
- await this.datastore.put(peerIdToDatastoreKey(peerId), buf)
196
+ await this.datastore.put(peerIdToDatastoreKey(peerId), buf, options)
194
197
 
195
198
  return {
196
199
  peer: bytesToPeer(peerId, buf, this.maxAddressAge),
@@ -3,8 +3,9 @@ import { isMultiaddr, multiaddr } from '@multiformats/multiaddr'
3
3
  import type { AddressFilter } from '../index.js'
4
4
  import type { Address as AddressPB } from '../pb/peer.js'
5
5
  import type { PeerId, Address } from '@libp2p/interface'
6
+ import type { AbortOptions } from '@multiformats/multiaddr'
6
7
 
7
- export async function dedupeFilterAndSortAddresses (peerId: PeerId, filter: AddressFilter, addresses: Array<Address | AddressPB | undefined>, existingAddresses?: AddressPB[]): Promise<AddressPB[]> {
8
+ export async function dedupeFilterAndSortAddresses (peerId: PeerId, filter: AddressFilter, addresses: Array<Address | AddressPB | undefined>, existingAddresses?: AddressPB[], options?: AbortOptions): Promise<AddressPB[]> {
8
9
  const addressMap = new Map<string, Address>()
9
10
 
10
11
  for (const addr of addresses) {
@@ -20,7 +21,7 @@ export async function dedupeFilterAndSortAddresses (peerId: PeerId, filter: Addr
20
21
  throw new InvalidParametersError('Multiaddr was invalid')
21
22
  }
22
23
 
23
- if (!(await filter(peerId, addr.multiaddr))) {
24
+ if (!(await filter(peerId, addr.multiaddr, options))) {
24
25
  continue
25
26
  }
26
27
 
@@ -7,8 +7,9 @@ import type { AddressFilter } from '../index.js'
7
7
  import type { Tag, Peer as PeerPB } from '../pb/peer.js'
8
8
  import type { ExistingPeer } from '../store.js'
9
9
  import type { PeerId, Address, PeerData, TagOptions } from '@libp2p/interface'
10
+ import type { AbortOptions } from '@multiformats/multiaddr'
10
11
 
11
- export interface ToPBPeerOptions {
12
+ export interface ToPBPeerOptions extends AbortOptions {
12
13
  addressFilter?: AddressFilter
13
14
  existingPeer?: ExistingPeer
14
15
  }
@@ -148,7 +149,8 @@ export async function toPeerPB (peerId: PeerId, data: Partial<PeerData>, strateg
148
149
  peerId,
149
150
  options.addressFilter ?? (async () => true),
150
151
  addresses,
151
- options.existingPeer?.peerPB.addresses
152
+ options.existingPeer?.peerPB.addresses,
153
+ options
152
154
  ),
153
155
  protocols: [...protocols.values()].sort((a, b) => {
154
156
  return a.localeCompare(b)
@@ -1,10 +0,0 @@
1
- {
2
- "AddressFilter": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_peer-store.AddressFilter.html",
3
- ".:AddressFilter": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_peer-store.AddressFilter.html",
4
- "PersistentPeerStoreComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_peer-store.PersistentPeerStoreComponents.html",
5
- ".:PersistentPeerStoreComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_peer-store.PersistentPeerStoreComponents.html",
6
- "PersistentPeerStoreInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_peer-store.PersistentPeerStoreInit.html",
7
- ".:PersistentPeerStoreInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_peer-store.PersistentPeerStoreInit.html",
8
- "persistentPeerStore": "https://libp2p.github.io/js-libp2p/functions/_libp2p_peer-store.persistentPeerStore.html",
9
- ".:persistentPeerStore": "https://libp2p.github.io/js-libp2p/functions/_libp2p_peer-store.persistentPeerStore.html"
10
- }