@libp2p/peer-store 1.0.4 → 1.0.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libp2p/peer-store",
3
- "version": "1.0.4",
3
+ "version": "1.0.7",
4
4
  "description": "Stores information about peers libp2p knows on the network",
5
5
  "license": "Apache-2.0 OR MIT",
6
6
  "homepage": "https://github.com/libp2p/js-libp2p-interfaces/tree/master/packages/libp2p-peer-store#readme",
@@ -140,9 +140,9 @@
140
140
  "test:electron-main": "npm run test -- -t electron-main"
141
141
  },
142
142
  "dependencies": {
143
- "@libp2p/interfaces": "^1.3.6",
144
- "@libp2p/logger": "^1.0.3",
145
- "@libp2p/peer-record": "^1.0.1",
143
+ "@libp2p/interfaces": "^1.3.0",
144
+ "@libp2p/logger": "^1.1.0",
145
+ "@libp2p/peer-record": "^1.0.0",
146
146
  "@multiformats/multiaddr": "^10.1.5",
147
147
  "interface-datastore": "^6.1.0",
148
148
  "it-all": "^1.0.6",
@@ -152,13 +152,13 @@
152
152
  "it-pipe": "^2.0.3",
153
153
  "mortice": "^3.0.0",
154
154
  "multiformats": "^9.6.3",
155
- "protobufjs": "^6.10.2"
155
+ "protobufjs": "^6.11.2"
156
156
  },
157
157
  "devDependencies": {
158
- "@libp2p/interface-compliance-tests": "^1.1.2",
159
- "@libp2p/peer-id": "^1.1.3",
160
- "@libp2p/peer-id-factory": "^1.0.5",
161
- "@libp2p/utils": "^1.0.5",
158
+ "@libp2p/interface-compliance-tests": "^1.1.0",
159
+ "@libp2p/peer-id": "^1.1.0",
160
+ "@libp2p/peer-id-factory": "^1.0.0",
161
+ "@libp2p/utils": "^1.0.9",
162
162
  "aegir": "^36.1.3",
163
163
  "datastore-core": "^7.0.1",
164
164
  "err-code": "^3.0.1",
package/src/README.md CHANGED
@@ -49,7 +49,7 @@ The `addressBook` keeps the known multiaddrs of a peer. The multiaddrs of each p
49
49
 
50
50
  `Map<string, Address>`
51
51
 
52
- A `peerId.toString(base58btc)` identifier mapping to a `Address` object, which should have the following structure:
52
+ A `peerId.toString()` identifier mapping to a `Address` object, which should have the following structure:
53
53
 
54
54
  ```js
55
55
  {
@@ -63,7 +63,7 @@ The `keyBook` tracks the public keys of the peers by keeping their [`PeerId`][pe
63
63
 
64
64
  `Map<string, PeerId`
65
65
 
66
- A `peerId.toString(base58btc)` identifier mapping to a `PeerId` of the peer. This instance contains the peer public key.
66
+ A `peerId.toString()` identifier mapping to a `PeerId` of the peer. This instance contains the peer public key.
67
67
 
68
68
  #### Protocol Book
69
69
 
@@ -71,7 +71,7 @@ The `protoBook` holds the identifiers of the protocols supported by each peer. T
71
71
 
72
72
  `Map<string, Set<string>>`
73
73
 
74
- A `peerId.toString(base58btc)` identifier mapping to a `Set` of protocol identifier strings.
74
+ A `peerId.toString()` identifier mapping to a `Set` of protocol identifier strings.
75
75
 
76
76
  #### Metadata Book
77
77
 
@@ -79,7 +79,7 @@ The `metadataBook` keeps track of the known metadata of a peer. Its metadata is
79
79
 
80
80
  `Map<string, Map<string, Uint8Array>>`
81
81
 
82
- A `peerId.toString(base58btc)` identifier mapping to the peer metadata Map.
82
+ A `peerId.toString()` identifier mapping to the peer metadata Map.
83
83
 
84
84
  ### API
85
85
 
@@ -8,14 +8,13 @@ import all from 'it-all'
8
8
  import filter from 'it-filter'
9
9
  import map from 'it-map'
10
10
  import each from 'it-foreach'
11
- import { base58btc } from 'multiformats/bases/base58'
12
11
  import { peerIdFromPeerId } from '@libp2p/peer-id'
13
12
  import { CustomEvent } from '@libp2p/interfaces'
14
- import type { PeerStore } from '@libp2p/interfaces/peer-store'
13
+ import type { AddressFilter, Peer, PeerMultiaddrsChangeData, PeerStore } from '@libp2p/interfaces/peer-store'
15
14
  import type { Store } from './store.js'
16
- import type { AddressFilter, AddressSorter } from './index.js'
17
15
  import type { Envelope } from '@libp2p/interfaces/record'
18
16
  import type { PeerId } from '@libp2p/interfaces/peer-id'
17
+ import type { PeerInfo } from '@libp2p/interfaces/peer-info'
19
18
 
20
19
  const log = logger('libp2p:peer-store:address-book')
21
20
  const EVENT_NAME = 'change:multiaddrs'
@@ -41,11 +40,12 @@ export class PeerStoreAddressBook {
41
40
  * into the AddressBook.
42
41
  */
43
42
  async consumePeerRecord (envelope: Envelope) {
44
- log('consumePeerRecord await write lock')
43
+ log.trace('consumePeerRecord await write lock')
45
44
  const release = await this.store.lock.writeLock()
46
- log('consumePeerRecord got write lock')
45
+ log.trace('consumePeerRecord got write lock')
47
46
 
48
47
  let peerId
48
+ let peer: Peer | undefined
49
49
  let updatedPeer
50
50
 
51
51
  try {
@@ -72,7 +72,7 @@ export class PeerStoreAddressBook {
72
72
  }
73
73
 
74
74
  if (await this.store.has(peerId)) {
75
- const peer = await this.store.load(peerId)
75
+ peer = await this.store.load(peerId)
76
76
 
77
77
  if (peer.peerRecordEnvelope != null) {
78
78
  const storedEnvelope = await RecordEnvelope.createFromProtobuf(peer.peerRecordEnvelope)
@@ -80,35 +80,42 @@ export class PeerStoreAddressBook {
80
80
 
81
81
  // ensure seq is greater than, or equal to, the last received
82
82
  if (storedRecord.seqNumber >= peerRecord.seqNumber) {
83
+ log('sequence number was lower or equal to existing sequence number - stored: %d received: %d', storedRecord.seqNumber, peerRecord.seqNumber)
83
84
  return false
84
85
  }
85
86
  }
86
87
  }
87
88
 
89
+ const addresses = await filterMultiaddrs(peerId, multiaddrs, this.addressFilter, true)
90
+
88
91
  // Replace unsigned addresses by the new ones from the record
89
92
  // TODO: Once we have ttls for the addresses, we should merge these in
90
93
  updatedPeer = await this.store.patchOrCreate(peerId, {
91
- addresses: await filterMultiaddrs(peerId, multiaddrs, this.addressFilter, true),
94
+ addresses,
92
95
  peerRecordEnvelope: envelope.marshal()
93
96
  })
94
97
 
95
- log(`stored provided peer record for ${peerRecord.peerId.toString(base58btc)}`)
98
+ log('stored provided peer record for %p', peerRecord.peerId)
96
99
  } finally {
97
- log('consumePeerRecord release write lock')
100
+ log.trace('consumePeerRecord release write lock')
98
101
  release()
99
102
  }
100
103
 
101
- this.dispatchEvent(new CustomEvent(EVENT_NAME, {
102
- detail: { peerId, multiaddrs: updatedPeer.addresses.map(({ multiaddr }) => multiaddr) }
104
+ this.dispatchEvent(new CustomEvent<PeerMultiaddrsChangeData>(EVENT_NAME, {
105
+ detail: {
106
+ peerId,
107
+ multiaddrs: updatedPeer.addresses.map(({ multiaddr }) => multiaddr),
108
+ oldMultiaddrs: peer == null ? [] : peer.addresses.map(({ multiaddr }) => multiaddr)
109
+ }
103
110
  }))
104
111
 
105
112
  return true
106
113
  }
107
114
 
108
115
  async getRawEnvelope (peerId: PeerId) {
109
- log('getRawEnvelope await read lock')
116
+ log.trace('getRawEnvelope await read lock')
110
117
  const release = await this.store.lock.readLock()
111
- log('getRawEnvelope got read lock')
118
+ log.trace('getRawEnvelope got read lock')
112
119
 
113
120
  try {
114
121
  const peer = await this.store.load(peerId)
@@ -119,7 +126,7 @@ export class PeerStoreAddressBook {
119
126
  throw err
120
127
  }
121
128
  } finally {
122
- log('getRawEnvelope release read lock')
129
+ log.trace('getRawEnvelope release read lock')
123
130
  release()
124
131
  }
125
132
  }
@@ -141,9 +148,9 @@ export class PeerStoreAddressBook {
141
148
  async get (peerId: PeerId) {
142
149
  peerId = peerIdFromPeerId(peerId)
143
150
 
144
- log('get wait for read lock')
151
+ log.trace('get wait for read lock')
145
152
  const release = await this.store.lock.readLock()
146
- log('get got read lock')
153
+ log.trace('get got read lock')
147
154
 
148
155
  try {
149
156
  const peer = await this.store.load(peerId)
@@ -154,7 +161,7 @@ export class PeerStoreAddressBook {
154
161
  throw err
155
162
  }
156
163
  } finally {
157
- log('get release read lock')
164
+ log.trace('get release read lock')
158
165
  release()
159
166
  }
160
167
 
@@ -169,11 +176,12 @@ export class PeerStoreAddressBook {
169
176
  throw errcode(new Error('multiaddrs must be an array of Multiaddrs'), codes.ERR_INVALID_PARAMETERS)
170
177
  }
171
178
 
172
- log('set await write lock')
179
+ log.trace('set await write lock')
173
180
  const release = await this.store.lock.writeLock()
174
- log('set got write lock')
181
+ log.trace('set got write lock')
175
182
 
176
183
  let hasPeer = false
184
+ let peer: Peer | undefined
177
185
  let updatedPeer
178
186
 
179
187
  try {
@@ -185,7 +193,7 @@ export class PeerStoreAddressBook {
185
193
  }
186
194
 
187
195
  try {
188
- const peer = await this.store.load(peerId)
196
+ peer = await this.store.load(peerId)
189
197
  hasPeer = true
190
198
 
191
199
  if (new Set([
@@ -203,21 +211,28 @@ export class PeerStoreAddressBook {
203
211
 
204
212
  updatedPeer = await this.store.patchOrCreate(peerId, { addresses })
205
213
 
206
- log(`set multiaddrs for ${peerId.toString(base58btc)}`)
214
+ log('set multiaddrs for %p', peerId)
207
215
  } finally {
216
+ log.trace('set multiaddrs for %p', peerId)
208
217
  log('set release write lock')
209
218
  release()
210
219
  }
211
220
 
212
- this.dispatchEvent(new CustomEvent(EVENT_NAME, {
213
- detail: { peerId, multiaddrs: updatedPeer.addresses.map(addr => addr.multiaddr) }
221
+ this.dispatchEvent(new CustomEvent<PeerMultiaddrsChangeData>(EVENT_NAME, {
222
+ detail: {
223
+ peerId,
224
+ multiaddrs: updatedPeer.addresses.map(addr => addr.multiaddr),
225
+ oldMultiaddrs: peer == null ? [] : peer.addresses.map(({ multiaddr }) => multiaddr)
226
+ }
214
227
  }))
215
228
 
216
229
  // Notify the existence of a new peer
217
230
  if (!hasPeer) {
218
- this.dispatchEvent(new CustomEvent('peer', {
231
+ this.dispatchEvent(new CustomEvent<PeerInfo>('peer', {
219
232
  detail: {
220
- peerId
233
+ id: peerId,
234
+ multiaddrs: updatedPeer.addresses.map(addr => addr.multiaddr),
235
+ protocols: updatedPeer.protocols
221
236
  }
222
237
  }))
223
238
  }
@@ -231,11 +246,12 @@ export class PeerStoreAddressBook {
231
246
  throw errcode(new Error('multiaddrs must be an array of Multiaddrs'), codes.ERR_INVALID_PARAMETERS)
232
247
  }
233
248
 
234
- log('add await write lock')
249
+ log.trace('add await write lock')
235
250
  const release = await this.store.lock.writeLock()
236
- log('add got write lock')
251
+ log.trace('add got write lock')
237
252
 
238
253
  let hasPeer
254
+ let peer: Peer | undefined
239
255
  let updatedPeer
240
256
 
241
257
  try {
@@ -247,7 +263,7 @@ export class PeerStoreAddressBook {
247
263
  }
248
264
 
249
265
  try {
250
- const peer = await this.store.load(peerId)
266
+ peer = await this.store.load(peerId)
251
267
  hasPeer = true
252
268
 
253
269
  if (new Set([
@@ -264,20 +280,28 @@ export class PeerStoreAddressBook {
264
280
 
265
281
  updatedPeer = await this.store.mergeOrCreate(peerId, { addresses })
266
282
 
267
- log(`added multiaddrs for ${peerId.toString(base58btc)}`)
283
+ log('added multiaddrs for %p', peerId)
268
284
  } finally {
269
- log('set release write lock')
285
+ log.trace('set release write lock')
270
286
  release()
271
287
  }
272
288
 
273
- this.dispatchEvent(new CustomEvent(EVENT_NAME, {
274
- detail: { peerId, multiaddrs: updatedPeer.addresses.map(addr => addr.multiaddr) }
289
+ this.dispatchEvent(new CustomEvent<PeerMultiaddrsChangeData>(EVENT_NAME, {
290
+ detail: {
291
+ peerId,
292
+ multiaddrs: updatedPeer.addresses.map(addr => addr.multiaddr),
293
+ oldMultiaddrs: peer == null ? [] : peer.addresses.map(({ multiaddr }) => multiaddr)
294
+ }
275
295
  }))
276
296
 
277
297
  // Notify the existence of a new peer
278
298
  if (hasPeer === true) {
279
- this.dispatchEvent(new CustomEvent('peer', {
280
- detail: { peerId }
299
+ this.dispatchEvent(new CustomEvent<PeerInfo>('peer', {
300
+ detail: {
301
+ id: peerId,
302
+ multiaddrs: updatedPeer.addresses.map(addr => addr.multiaddr),
303
+ protocols: updatedPeer.protocols
304
+ }
281
305
  }))
282
306
  }
283
307
  }
@@ -285,46 +309,39 @@ export class PeerStoreAddressBook {
285
309
  async delete (peerId: PeerId) {
286
310
  peerId = peerIdFromPeerId(peerId)
287
311
 
288
- log('delete await write lock')
312
+ log.trace('delete await write lock')
289
313
  const release = await this.store.lock.writeLock()
290
- log('delete got write lock')
314
+ log.trace('delete got write lock')
291
315
 
292
- let has
316
+ let peer: Peer | undefined
293
317
 
294
318
  try {
295
- has = await this.store.has(peerId)
319
+ try {
320
+ peer = await this.store.load(peerId)
321
+ } catch (err: any) {
322
+ if (err.code !== codes.ERR_NOT_FOUND) {
323
+ throw err
324
+ }
325
+ }
296
326
 
297
327
  await this.store.patchOrCreate(peerId, {
298
328
  addresses: []
299
329
  })
300
330
  } finally {
301
- log('delete release write lock')
331
+ log.trace('delete release write lock')
302
332
  release()
303
333
  }
304
334
 
305
- if (has) {
306
- this.dispatchEvent(new CustomEvent(EVENT_NAME, {
307
- detail: { peerId, multiaddrs: [] }
335
+ if (peer != null) {
336
+ this.dispatchEvent(new CustomEvent<PeerMultiaddrsChangeData>(EVENT_NAME, {
337
+ detail: {
338
+ peerId,
339
+ multiaddrs: [],
340
+ oldMultiaddrs: peer == null ? [] : peer.addresses.map(({ multiaddr }) => multiaddr)
341
+ }
308
342
  }))
309
343
  }
310
344
  }
311
-
312
- async getMultiaddrsForPeer (peerId: PeerId, addressSorter: AddressSorter = (mas) => mas) {
313
- const addresses = await this.get(peerId)
314
-
315
- return addressSorter(
316
- addresses
317
- ).map((address) => {
318
- const multiaddr = address.multiaddr
319
- const idString = multiaddr.getPeerId()
320
-
321
- if (idString === peerId.toString()) {
322
- return multiaddr
323
- }
324
-
325
- return multiaddr.encapsulate(`/p2p/${peerId.toString(base58btc)}`)
326
- })
327
- }
328
345
  }
329
346
 
330
347
  async function filterMultiaddrs (peerId: PeerId, multiaddrs: Multiaddr[], addressFilter: AddressFilter, isCertified: boolean = false) {
package/src/index.ts CHANGED
@@ -5,86 +5,78 @@ import { PeerStoreKeyBook } from './key-book.js'
5
5
  import { PeerStoreMetadataBook } from './metadata-book.js'
6
6
  import { PeerStoreProtoBook } from './proto-book.js'
7
7
  import { PersistentStore, Store } from './store.js'
8
- import type { PeerStore, Address, AddressBook, KeyBook, MetadataBook, ProtoBook, PeerStoreEvents } from '@libp2p/interfaces/peer-store'
8
+ import type { PeerStore, AddressBook, KeyBook, MetadataBook, ProtoBook, PeerStoreEvents, PeerStoreInit, Peer } from '@libp2p/interfaces/peer-store'
9
9
  import type { PeerId } from '@libp2p/interfaces/peer-id'
10
- import type { Multiaddr } from '@multiformats/multiaddr'
11
- import type { Datastore } from 'interface-datastore'
12
- import { base58btc } from 'multiformats/bases/base58'
10
+ import type { Components } from '@libp2p/interfaces/components'
13
11
 
14
12
  const log = logger('libp2p:peer-store')
15
13
 
16
- export interface AddressFilter {
17
- (peerId: PeerId, multiaddr: Multiaddr): Promise<boolean>
18
- }
19
-
20
- export interface AddressSorter {
21
- (addresses: Address[]): Address[]
22
- }
23
-
24
- export interface PeerStoreOptions {
25
- peerId: PeerId
26
- datastore: Datastore
27
- addressFilter?: AddressFilter
28
- }
29
-
30
14
  /**
31
15
  * An implementation of PeerStore that stores data in a Datastore
32
16
  */
33
- export class PeerStoreImpl extends EventEmitter<PeerStoreEvents> implements PeerStore {
17
+ export class PersistentPeerStore extends EventEmitter<PeerStoreEvents> implements PeerStore {
34
18
  public addressBook: AddressBook
35
19
  public keyBook: KeyBook
36
20
  public metadataBook: MetadataBook
37
21
  public protoBook: ProtoBook
38
22
 
39
- private readonly peerId: PeerId
23
+ private readonly components: Components
40
24
  private readonly store: Store
41
25
 
42
- constructor (options: PeerStoreOptions) {
26
+ constructor (components: Components, init: PeerStoreInit = {}) {
43
27
  super()
44
28
 
45
- const { peerId, datastore, addressFilter } = options
46
-
47
- this.peerId = peerId
48
- this.store = new PersistentStore(datastore)
29
+ this.components = components
30
+ this.store = new PersistentStore(components.getDatastore())
49
31
 
50
- this.addressBook = new PeerStoreAddressBook(this.dispatchEvent.bind(this), this.store, addressFilter)
32
+ this.addressBook = new PeerStoreAddressBook(this.dispatchEvent.bind(this), this.store, init.addressFilter ?? components.getConnectionGater().filterMultiaddrForPeer)
51
33
  this.keyBook = new PeerStoreKeyBook(this.dispatchEvent.bind(this), this.store)
52
34
  this.metadataBook = new PeerStoreMetadataBook(this.dispatchEvent.bind(this), this.store)
53
35
  this.protoBook = new PeerStoreProtoBook(this.dispatchEvent.bind(this), this.store)
54
36
  }
55
37
 
56
- async * getPeers () {
57
- log('getPeers await read lock')
38
+ async forEach (fn: (peer: Peer) => void) {
39
+ log.trace('getPeers await read lock')
58
40
  const release = await this.store.lock.readLock()
59
- log('getPeers got read lock')
41
+ log.trace('getPeers got read lock')
60
42
 
61
43
  try {
62
44
  for await (const peer of this.store.all()) {
63
- if (peer.id.toString(base58btc) === this.peerId.toString(base58btc)) {
64
- // Remove self peer if present
45
+ if (peer.id.equals(this.components.getPeerId())) {
46
+ // Skip self peer if present
65
47
  continue
66
48
  }
67
49
 
68
- yield peer
50
+ fn(peer)
69
51
  }
70
52
  } finally {
71
- log('getPeers release read lock')
53
+ log.trace('getPeers release read lock')
72
54
  release()
73
55
  }
74
56
  }
75
57
 
58
+ async all (): Promise<Peer[]> {
59
+ const output: Peer[] = []
60
+
61
+ await this.forEach(peer => {
62
+ output.push(peer)
63
+ })
64
+
65
+ return output
66
+ }
67
+
76
68
  /**
77
69
  * Delete the information of the given peer in every book
78
70
  */
79
71
  async delete (peerId: PeerId) {
80
- log('delete await write lock')
72
+ log.trace('delete await write lock')
81
73
  const release = await this.store.lock.writeLock()
82
- log('delete got write lock')
74
+ log.trace('delete got write lock')
83
75
 
84
76
  try {
85
77
  await this.store.delete(peerId)
86
78
  } finally {
87
- log('delete release write lock')
79
+ log.trace('delete release write lock')
88
80
  release()
89
81
  }
90
82
  }
@@ -93,14 +85,14 @@ export class PeerStoreImpl extends EventEmitter<PeerStoreEvents> implements Peer
93
85
  * Get the stored information of a given peer
94
86
  */
95
87
  async get (peerId: PeerId) {
96
- log('get await read lock')
88
+ log.trace('get await read lock')
97
89
  const release = await this.store.lock.readLock()
98
- log('get got read lock')
90
+ log.trace('get got read lock')
99
91
 
100
92
  try {
101
93
  return await this.store.load(peerId)
102
94
  } finally {
103
- log('get release read lock')
95
+ log.trace('get release read lock')
104
96
  release()
105
97
  }
106
98
  }
@@ -109,19 +101,15 @@ export class PeerStoreImpl extends EventEmitter<PeerStoreEvents> implements Peer
109
101
  * Returns true if we have a record of the peer
110
102
  */
111
103
  async has (peerId: PeerId) {
112
- log('has await read lock')
104
+ log.trace('has await read lock')
113
105
  const release = await this.store.lock.readLock()
114
- log('has got read lock')
106
+ log.trace('has got read lock')
115
107
 
116
108
  try {
117
109
  return await this.store.has(peerId)
118
110
  } finally {
119
- log('has release read lock')
111
+ log.trace('has release read lock')
120
112
  release()
121
113
  }
122
114
  }
123
115
  }
124
-
125
- export function createPeerStore (opts: PeerStoreOptions): PeerStore {
126
- return new PeerStoreImpl(opts)
127
- }
package/src/key-book.ts CHANGED
@@ -5,7 +5,7 @@ import { peerIdFromPeerId } from '@libp2p/peer-id'
5
5
  import { equals as uint8arrayEquals } from 'uint8arrays/equals'
6
6
  import { CustomEvent } from '@libp2p/interfaces'
7
7
  import type { Store } from './store.js'
8
- import type { PeerStore, KeyBook } from '@libp2p/interfaces/src/peer-store'
8
+ import type { PeerStore, KeyBook, PeerPublicKeyChangeData, Peer } from '@libp2p/interfaces/peer-store'
9
9
  import type { PeerId } from '@libp2p/interfaces/peer-id'
10
10
 
11
11
  const log = logger('libp2p:peer-store:key-book')
@@ -35,17 +35,18 @@ export class PeerStoreKeyBook implements KeyBook {
35
35
  throw errcode(new Error('publicKey must be an instance of PublicKey'), codes.ERR_INVALID_PARAMETERS)
36
36
  }
37
37
 
38
- log('set await write lock')
38
+ log.trace('set await write lock')
39
39
  const release = await this.store.lock.writeLock()
40
- log('set got write lock')
40
+ log.trace('set got write lock')
41
41
 
42
42
  let updatedKey = false
43
+ let peer: Peer | undefined
43
44
 
44
45
  try {
45
46
  try {
46
- const existing = await this.store.load(peerId)
47
+ peer = await this.store.load(peerId)
47
48
 
48
- if ((existing.pubKey != null) && uint8arrayEquals(existing.pubKey, publicKey)) {
49
+ if ((peer.pubKey != null) && uint8arrayEquals(peer.pubKey, publicKey)) {
49
50
  return
50
51
  }
51
52
  } catch (err: any) {
@@ -59,13 +60,17 @@ export class PeerStoreKeyBook implements KeyBook {
59
60
  })
60
61
  updatedKey = true
61
62
  } finally {
62
- log('set release write lock')
63
+ log.trace('set release write lock')
63
64
  release()
64
65
  }
65
66
 
66
67
  if (updatedKey) {
67
- this.dispatchEvent(new CustomEvent(EVENT_NAME, {
68
- detail: { peerId, pubKey: publicKey }
68
+ this.dispatchEvent(new CustomEvent<PeerPublicKeyChangeData>(EVENT_NAME, {
69
+ detail: {
70
+ peerId,
71
+ publicKey: publicKey,
72
+ oldPublicKey: peer == null ? undefined : peer.pubKey
73
+ }
69
74
  }))
70
75
  }
71
76
  }
@@ -76,9 +81,9 @@ export class PeerStoreKeyBook implements KeyBook {
76
81
  async get (peerId: PeerId) {
77
82
  peerId = peerIdFromPeerId(peerId)
78
83
 
79
- log('get await write lock')
84
+ log.trace('get await write lock')
80
85
  const release = await this.store.lock.readLock()
81
- log('get got write lock')
86
+ log.trace('get got write lock')
82
87
 
83
88
  try {
84
89
  const peer = await this.store.load(peerId)
@@ -97,21 +102,39 @@ export class PeerStoreKeyBook implements KeyBook {
97
102
  async delete (peerId: PeerId) {
98
103
  peerId = peerIdFromPeerId(peerId)
99
104
 
100
- log('delete await write lock')
105
+ log.trace('delete await write lock')
101
106
  const release = await this.store.lock.writeLock()
102
- log('delete got write lock')
107
+ log.trace('delete got write lock')
108
+
109
+ let peer: Peer | undefined
103
110
 
104
111
  try {
112
+ try {
113
+ peer = await this.store.load(peerId)
114
+ } catch (err: any) {
115
+ if (err.code !== codes.ERR_NOT_FOUND) {
116
+ throw err
117
+ }
118
+ }
119
+
105
120
  await this.store.patchOrCreate(peerId, {
106
121
  pubKey: undefined
107
122
  })
123
+ } catch (err: any) {
124
+ if (err.code !== codes.ERR_NOT_FOUND) {
125
+ throw err
126
+ }
108
127
  } finally {
109
- log('delete release write lock')
128
+ log.trace('delete release write lock')
110
129
  release()
111
130
  }
112
131
 
113
- this.dispatchEvent(new CustomEvent(EVENT_NAME, {
114
- detail: { peerId, pubKey: undefined }
132
+ this.dispatchEvent(new CustomEvent<PeerPublicKeyChangeData>(EVENT_NAME, {
133
+ detail: {
134
+ peerId,
135
+ publicKey: undefined,
136
+ oldPublicKey: peer == null ? undefined : peer.pubKey
137
+ }
115
138
  }))
116
139
  }
117
140
  }