libp2p 0.35.8 → 0.36.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.
- package/dist/index.min.js +55 -0
- package/dist/src/circuit/auto-relay.d.ts +8 -10
- package/dist/src/circuit/auto-relay.d.ts.map +1 -1
- package/dist/src/config.d.ts +2 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/connection-manager/auto-dialler.d.ts +1 -1
- package/dist/src/connection-manager/auto-dialler.d.ts.map +1 -1
- package/dist/src/connection-manager/index.d.ts +1 -2
- package/dist/src/connection-manager/index.d.ts.map +1 -1
- package/dist/src/content-routing/utils.d.ts +3 -3
- package/dist/src/content-routing/utils.d.ts.map +1 -1
- package/dist/src/dialer/dial-request.d.ts.map +1 -1
- package/dist/src/dialer/index.d.ts +12 -7
- package/dist/src/dialer/index.d.ts.map +1 -1
- package/dist/src/errors.d.ts +2 -0
- package/dist/src/fetch/constants.d.ts +2 -0
- package/dist/src/fetch/constants.d.ts.map +1 -0
- package/dist/src/fetch/index.d.ts +76 -0
- package/dist/src/fetch/index.d.ts.map +1 -0
- package/dist/src/fetch/proto.d.ts +134 -0
- package/dist/src/identify/index.d.ts +4 -4
- package/dist/src/identify/index.d.ts.map +1 -1
- package/dist/src/index.d.ts +116 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/metrics/index.d.ts +9 -4
- package/dist/src/metrics/index.d.ts.map +1 -1
- package/dist/src/metrics/tracked-map.d.ts +6 -1
- package/dist/src/metrics/tracked-map.d.ts.map +1 -1
- package/dist/src/peer-routing.d.ts +1 -1
- package/dist/src/peer-routing.d.ts.map +1 -1
- package/dist/src/peer-store/address-book.d.ts +30 -84
- package/dist/src/peer-store/address-book.d.ts.map +1 -1
- package/dist/src/peer-store/index.d.ts +28 -94
- package/dist/src/peer-store/index.d.ts.map +1 -1
- package/dist/src/peer-store/key-book.d.ts +31 -15
- package/dist/src/peer-store/key-book.d.ts.map +1 -1
- package/dist/src/peer-store/metadata-book.d.ts +33 -29
- package/dist/src/peer-store/metadata-book.d.ts.map +1 -1
- package/dist/src/peer-store/pb/peer.d.ts +222 -0
- package/dist/src/peer-store/proto-book.d.ts +27 -28
- package/dist/src/peer-store/proto-book.d.ts.map +1 -1
- package/dist/src/peer-store/store.d.ts +73 -0
- package/dist/src/peer-store/store.d.ts.map +1 -0
- package/dist/src/peer-store/types.d.ts +202 -0
- package/dist/src/peer-store/types.d.ts.map +1 -0
- package/dist/src/ping/index.d.ts.map +1 -1
- package/dist/src/record/peer-record/index.d.ts +2 -2
- package/dist/src/record/peer-record/index.d.ts.map +1 -1
- package/dist/src/registrar.d.ts +5 -5
- package/dist/src/registrar.d.ts.map +1 -1
- package/dist/src/types.d.ts +90 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/upgrader.d.ts +8 -2
- package/dist/src/upgrader.d.ts.map +1 -1
- package/package.json +23 -26
- package/src/circuit/auto-relay.js +52 -38
- package/src/config.js +2 -0
- package/src/connection-manager/auto-dialler.js +20 -8
- package/src/connection-manager/index.js +42 -22
- package/src/content-routing/utils.js +4 -4
- package/src/dialer/dial-request.js +4 -1
- package/src/dialer/index.js +38 -8
- package/src/errors.js +2 -0
- package/src/fetch/README.md +36 -0
- package/src/fetch/constants.js +6 -0
- package/src/fetch/index.js +159 -0
- package/src/fetch/proto.d.ts +134 -0
- package/src/fetch/proto.js +333 -0
- package/src/fetch/proto.proto +15 -0
- package/src/identify/index.js +47 -38
- package/src/index.js +72 -27
- package/src/metrics/index.js +15 -8
- package/src/metrics/tracked-map.js +40 -14
- package/src/peer-routing.js +4 -1
- package/src/peer-store/address-book.js +254 -226
- package/src/peer-store/index.js +79 -110
- package/src/peer-store/key-book.js +99 -54
- package/src/peer-store/metadata-book.js +171 -101
- package/src/peer-store/pb/peer.d.ts +222 -0
- package/src/peer-store/pb/peer.js +643 -0
- package/src/peer-store/pb/peer.proto +31 -0
- package/src/peer-store/proto-book.js +171 -105
- package/src/peer-store/store.js +263 -0
- package/src/peer-store/types.ts +245 -0
- package/src/ping/index.js +6 -0
- package/src/record/peer-record/index.js +1 -1
- package/src/record/utils.js +1 -1
- package/src/registrar.js +4 -4
- package/src/types.ts +98 -0
- package/src/upgrader.js +32 -2
- package/dist/src/peer-store/book.d.ts +0 -81
- package/dist/src/peer-store/book.d.ts.map +0 -1
- package/dist/src/peer-store/persistent/consts.d.ts +0 -6
- package/dist/src/peer-store/persistent/consts.d.ts.map +0 -1
- package/dist/src/peer-store/persistent/index.d.ts +0 -129
- package/dist/src/peer-store/persistent/index.d.ts.map +0 -1
- package/dist/src/peer-store/persistent/pb/address-book.d.ts +0 -198
- package/dist/src/peer-store/persistent/pb/proto-book.d.ts +0 -59
- package/src/peer-store/book.js +0 -124
- package/src/peer-store/persistent/consts.js +0 -15
- package/src/peer-store/persistent/index.js +0 -408
- package/src/peer-store/persistent/pb/address-book.d.ts +0 -198
- package/src/peer-store/persistent/pb/address-book.js +0 -522
- package/src/peer-store/persistent/pb/address-book.proto +0 -27
- package/src/peer-store/persistent/pb/proto-book.d.ts +0 -59
- package/src/peer-store/persistent/pb/proto-book.js +0 -157
- package/src/peer-store/persistent/pb/proto-book.proto +0 -5
|
@@ -1,171 +1,237 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const debug = require('debug')
|
|
4
|
-
const log = Object.assign(debug('libp2p:peer-store:proto-book'), {
|
|
5
|
-
error: debug('libp2p:peer-store:proto-book:err')
|
|
6
|
-
})
|
|
7
4
|
const errcode = require('err-code')
|
|
5
|
+
const { codes } = require('../errors')
|
|
8
6
|
const PeerId = require('peer-id')
|
|
9
7
|
|
|
10
|
-
const Book = require('./book')
|
|
11
|
-
|
|
12
|
-
const {
|
|
13
|
-
codes: { ERR_INVALID_PARAMETERS }
|
|
14
|
-
} = require('../errors')
|
|
15
|
-
|
|
16
8
|
/**
|
|
17
|
-
* @typedef {import('./')} PeerStore
|
|
9
|
+
* @typedef {import('./types').PeerStore} PeerStore
|
|
10
|
+
* @typedef {import('./types').ProtoBook} ProtoBook
|
|
18
11
|
*/
|
|
19
12
|
|
|
13
|
+
const log = Object.assign(debug('libp2p:peer-store:proto-book'), {
|
|
14
|
+
error: debug('libp2p:peer-store:proto-book:err')
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const EVENT_NAME = 'change:protocols'
|
|
18
|
+
|
|
20
19
|
/**
|
|
21
|
-
* @
|
|
22
|
-
*
|
|
23
|
-
* @fires ProtoBook#change:protocols
|
|
20
|
+
* @implements {ProtoBook}
|
|
24
21
|
*/
|
|
25
|
-
class
|
|
22
|
+
class PersistentProtoBook {
|
|
26
23
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* @class
|
|
31
|
-
* @param {PeerStore} peerStore
|
|
24
|
+
* @param {PeerStore["emit"]} emit
|
|
25
|
+
* @param {import('./types').Store} store
|
|
32
26
|
*/
|
|
33
|
-
constructor (
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
27
|
+
constructor (emit, store) {
|
|
28
|
+
this._emit = emit
|
|
29
|
+
this._store = store
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param {PeerId} peerId
|
|
34
|
+
*/
|
|
35
|
+
async get (peerId) {
|
|
36
|
+
log('get wait for read lock')
|
|
37
|
+
const release = await this._store.lock.readLock()
|
|
38
|
+
log('get got read lock')
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
const peer = await this._store.load(peerId)
|
|
42
|
+
|
|
43
|
+
return peer.protocols
|
|
44
|
+
} catch (/** @type {any} */ err) {
|
|
45
|
+
if (err.code !== codes.ERR_NOT_FOUND) {
|
|
46
|
+
throw err
|
|
47
|
+
}
|
|
48
|
+
} finally {
|
|
49
|
+
log('get release read lock')
|
|
50
|
+
release()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return []
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
/**
|
|
54
|
-
* Set known protocols of a provided peer.
|
|
55
|
-
* If the peer was not known before, it will be added.
|
|
56
|
-
*
|
|
57
|
-
* @override
|
|
58
57
|
* @param {PeerId} peerId
|
|
59
58
|
* @param {string[]} protocols
|
|
60
|
-
* @returns {ProtoBook}
|
|
61
59
|
*/
|
|
62
|
-
set (peerId, protocols) {
|
|
60
|
+
async set (peerId, protocols) {
|
|
63
61
|
if (!PeerId.isPeerId(peerId)) {
|
|
64
62
|
log.error('peerId must be an instance of peer-id to store data')
|
|
65
|
-
throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS)
|
|
63
|
+
throw errcode(new Error('peerId must be an instance of peer-id'), codes.ERR_INVALID_PARAMETERS)
|
|
66
64
|
}
|
|
67
65
|
|
|
68
|
-
if (!protocols) {
|
|
66
|
+
if (!Array.isArray(protocols)) {
|
|
69
67
|
log.error('protocols must be provided to store data')
|
|
70
|
-
throw errcode(new Error('protocols must be provided'), ERR_INVALID_PARAMETERS)
|
|
68
|
+
throw errcode(new Error('protocols must be provided'), codes.ERR_INVALID_PARAMETERS)
|
|
71
69
|
}
|
|
72
70
|
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
71
|
+
log('set await write lock')
|
|
72
|
+
const release = await this._store.lock.writeLock()
|
|
73
|
+
log('set got write lock')
|
|
74
|
+
|
|
75
|
+
let updatedPeer
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
try {
|
|
79
|
+
const peer = await this._store.load(peerId)
|
|
80
|
+
|
|
81
|
+
if (new Set([
|
|
82
|
+
...protocols
|
|
83
|
+
]).size === peer.protocols.length) {
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
} catch (/** @type {any} */ err) {
|
|
87
|
+
if (err.code !== codes.ERR_NOT_FOUND) {
|
|
88
|
+
throw err
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
updatedPeer = await this._store.patchOrCreate(peerId, {
|
|
93
|
+
protocols
|
|
94
|
+
})
|
|
89
95
|
|
|
90
|
-
|
|
91
|
-
|
|
96
|
+
log(`stored provided protocols for ${peerId.toB58String()}`)
|
|
97
|
+
} finally {
|
|
98
|
+
log('set release write lock')
|
|
99
|
+
release()
|
|
100
|
+
}
|
|
92
101
|
|
|
93
|
-
|
|
102
|
+
this._emit(EVENT_NAME, { peerId, protocols: updatedPeer.protocols })
|
|
94
103
|
}
|
|
95
104
|
|
|
96
105
|
/**
|
|
97
|
-
* Adds known protocols of a provided peer.
|
|
98
|
-
* If the peer was not known before, it will be added.
|
|
99
|
-
*
|
|
100
106
|
* @param {PeerId} peerId
|
|
101
107
|
* @param {string[]} protocols
|
|
102
|
-
* @returns {ProtoBook}
|
|
103
108
|
*/
|
|
104
|
-
add (peerId, protocols) {
|
|
109
|
+
async add (peerId, protocols) {
|
|
105
110
|
if (!PeerId.isPeerId(peerId)) {
|
|
106
111
|
log.error('peerId must be an instance of peer-id to store data')
|
|
107
|
-
throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS)
|
|
112
|
+
throw errcode(new Error('peerId must be an instance of peer-id'), codes.ERR_INVALID_PARAMETERS)
|
|
108
113
|
}
|
|
109
114
|
|
|
110
|
-
if (!protocols) {
|
|
115
|
+
if (!Array.isArray(protocols)) {
|
|
111
116
|
log.error('protocols must be provided to store data')
|
|
112
|
-
throw errcode(new Error('protocols must be provided'), ERR_INVALID_PARAMETERS)
|
|
117
|
+
throw errcode(new Error('protocols must be provided'), codes.ERR_INVALID_PARAMETERS)
|
|
113
118
|
}
|
|
114
119
|
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
|
|
120
|
+
log('add await write lock')
|
|
121
|
+
const release = await this._store.lock.writeLock()
|
|
122
|
+
log('add got write lock')
|
|
123
|
+
|
|
124
|
+
let updatedPeer
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
try {
|
|
128
|
+
const peer = await this._store.load(peerId)
|
|
129
|
+
|
|
130
|
+
if (new Set([
|
|
131
|
+
...peer.protocols,
|
|
132
|
+
...protocols
|
|
133
|
+
]).size === peer.protocols.length) {
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
} catch (/** @type {any} */ err) {
|
|
137
|
+
if (err.code !== codes.ERR_NOT_FOUND) {
|
|
138
|
+
throw err
|
|
139
|
+
}
|
|
140
|
+
}
|
|
118
141
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
return this
|
|
123
|
-
}
|
|
142
|
+
updatedPeer = await this._store.mergeOrCreate(peerId, {
|
|
143
|
+
protocols
|
|
144
|
+
})
|
|
124
145
|
|
|
125
|
-
|
|
126
|
-
|
|
146
|
+
log(`added provided protocols for ${peerId.toB58String()}`)
|
|
147
|
+
} finally {
|
|
148
|
+
log('add release write lock')
|
|
149
|
+
release()
|
|
150
|
+
}
|
|
127
151
|
|
|
128
|
-
|
|
152
|
+
this._emit(EVENT_NAME, { peerId, protocols: updatedPeer.protocols })
|
|
129
153
|
}
|
|
130
154
|
|
|
131
155
|
/**
|
|
132
|
-
* Removes known protocols of a provided peer.
|
|
133
|
-
* If the protocols did not exist before, nothing will be done.
|
|
134
|
-
*
|
|
135
156
|
* @param {PeerId} peerId
|
|
136
157
|
* @param {string[]} protocols
|
|
137
|
-
* @returns {ProtoBook}
|
|
138
158
|
*/
|
|
139
|
-
remove (peerId, protocols) {
|
|
159
|
+
async remove (peerId, protocols) {
|
|
140
160
|
if (!PeerId.isPeerId(peerId)) {
|
|
141
161
|
log.error('peerId must be an instance of peer-id to store data')
|
|
142
|
-
throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS)
|
|
162
|
+
throw errcode(new Error('peerId must be an instance of peer-id'), codes.ERR_INVALID_PARAMETERS)
|
|
143
163
|
}
|
|
144
164
|
|
|
145
|
-
if (!protocols) {
|
|
165
|
+
if (!Array.isArray(protocols)) {
|
|
146
166
|
log.error('protocols must be provided to store data')
|
|
147
|
-
throw errcode(new Error('protocols must be provided'), ERR_INVALID_PARAMETERS)
|
|
167
|
+
throw errcode(new Error('protocols must be provided'), codes.ERR_INVALID_PARAMETERS)
|
|
148
168
|
}
|
|
149
169
|
|
|
150
|
-
|
|
151
|
-
const
|
|
170
|
+
log('remove await write lock')
|
|
171
|
+
const release = await this._store.lock.writeLock()
|
|
172
|
+
log('remove got write lock')
|
|
173
|
+
|
|
174
|
+
let updatedPeer
|
|
175
|
+
|
|
176
|
+
try {
|
|
177
|
+
try {
|
|
178
|
+
const peer = await this._store.load(peerId)
|
|
179
|
+
const protocolSet = new Set(peer.protocols)
|
|
180
|
+
|
|
181
|
+
for (const protocol of protocols) {
|
|
182
|
+
protocolSet.delete(protocol)
|
|
183
|
+
}
|
|
152
184
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
].filter((p) => !protocols.includes(p)))
|
|
185
|
+
if (peer.protocols.length === protocolSet.size) {
|
|
186
|
+
return
|
|
187
|
+
}
|
|
157
188
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
189
|
+
protocols = Array.from(protocolSet)
|
|
190
|
+
} catch (/** @type {any} */ err) {
|
|
191
|
+
if (err.code !== codes.ERR_NOT_FOUND) {
|
|
192
|
+
throw err
|
|
193
|
+
}
|
|
161
194
|
}
|
|
162
195
|
|
|
163
|
-
this.
|
|
164
|
-
|
|
196
|
+
updatedPeer = await this._store.patchOrCreate(peerId, {
|
|
197
|
+
protocols
|
|
198
|
+
})
|
|
199
|
+
} finally {
|
|
200
|
+
log('remove release write lock')
|
|
201
|
+
release()
|
|
165
202
|
}
|
|
166
203
|
|
|
167
|
-
|
|
204
|
+
this._emit(EVENT_NAME, { peerId, protocols: updatedPeer.protocols })
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* @param {PeerId} peerId
|
|
209
|
+
*/
|
|
210
|
+
async delete (peerId) {
|
|
211
|
+
log('delete await write lock')
|
|
212
|
+
const release = await this._store.lock.writeLock()
|
|
213
|
+
log('delete got write lock')
|
|
214
|
+
let has
|
|
215
|
+
|
|
216
|
+
try {
|
|
217
|
+
has = await this._store.has(peerId)
|
|
218
|
+
|
|
219
|
+
await this._store.patchOrCreate(peerId, {
|
|
220
|
+
protocols: []
|
|
221
|
+
})
|
|
222
|
+
} catch (/** @type {any} */ err) {
|
|
223
|
+
if (err.code !== codes.ERR_NOT_FOUND) {
|
|
224
|
+
throw err
|
|
225
|
+
}
|
|
226
|
+
} finally {
|
|
227
|
+
log('delete release write lock')
|
|
228
|
+
release()
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (has) {
|
|
232
|
+
this._emit(EVENT_NAME, { peerId, protocols: [] })
|
|
233
|
+
}
|
|
168
234
|
}
|
|
169
235
|
}
|
|
170
236
|
|
|
171
|
-
module.exports =
|
|
237
|
+
module.exports = PersistentProtoBook
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const debug = require('debug')
|
|
4
|
+
const PeerId = require('peer-id')
|
|
5
|
+
const errcode = require('err-code')
|
|
6
|
+
const { codes } = require('../errors')
|
|
7
|
+
const { Key } = require('interface-datastore/key')
|
|
8
|
+
const { base32 } = require('multiformats/bases/base32')
|
|
9
|
+
const { keys: { unmarshalPublicKey, marshalPublicKey } } = require('libp2p-crypto')
|
|
10
|
+
const { Multiaddr } = require('multiaddr')
|
|
11
|
+
const { Peer: PeerPB } = require('./pb/peer')
|
|
12
|
+
// @ts-expect-error no types
|
|
13
|
+
const mortice = require('mortice')
|
|
14
|
+
const { equals: uint8arrayEquals } = require('uint8arrays/equals')
|
|
15
|
+
|
|
16
|
+
const log = Object.assign(debug('libp2p:peer-store:store'), {
|
|
17
|
+
error: debug('libp2p:peer-store:store:err')
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @typedef {import('./types').PeerStore} PeerStore
|
|
22
|
+
* @typedef {import('./types').EventName} EventName
|
|
23
|
+
* @typedef {import('./types').Peer} Peer
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
const NAMESPACE_COMMON = '/peers/'
|
|
27
|
+
|
|
28
|
+
class PersistentStore {
|
|
29
|
+
/**
|
|
30
|
+
* @param {import('interface-datastore').Datastore} datastore
|
|
31
|
+
*/
|
|
32
|
+
constructor (datastore) {
|
|
33
|
+
this._datastore = datastore
|
|
34
|
+
this.lock = mortice('peer-store', {
|
|
35
|
+
singleProcess: true
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {PeerId} peerId
|
|
41
|
+
* @returns {Key}
|
|
42
|
+
*/
|
|
43
|
+
_peerIdToDatastoreKey (peerId) {
|
|
44
|
+
if (!PeerId.isPeerId(peerId)) {
|
|
45
|
+
log.error('peerId must be an instance of peer-id to store data')
|
|
46
|
+
throw errcode(new Error('peerId must be an instance of peer-id'), codes.ERR_INVALID_PARAMETERS)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const b32key = peerId.toString()
|
|
50
|
+
return new Key(`${NAMESPACE_COMMON}${b32key}`)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @param {PeerId} peerId
|
|
55
|
+
*/
|
|
56
|
+
async has (peerId) {
|
|
57
|
+
return this._datastore.has(this._peerIdToDatastoreKey(peerId))
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {PeerId} peerId
|
|
62
|
+
*/
|
|
63
|
+
async delete (peerId) {
|
|
64
|
+
await this._datastore.delete(this._peerIdToDatastoreKey(peerId))
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @param {PeerId} peerId
|
|
69
|
+
* @returns {Promise<import('./types').Peer>} peer
|
|
70
|
+
*/
|
|
71
|
+
async load (peerId) {
|
|
72
|
+
const buf = await this._datastore.get(this._peerIdToDatastoreKey(peerId))
|
|
73
|
+
const peer = PeerPB.decode(buf)
|
|
74
|
+
const pubKey = peer.pubKey ? unmarshalPublicKey(peer.pubKey) : peerId.pubKey
|
|
75
|
+
const metadata = new Map()
|
|
76
|
+
|
|
77
|
+
for (const meta of peer.metadata) {
|
|
78
|
+
metadata.set(meta.key, meta.value)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
...peer,
|
|
83
|
+
id: peerId,
|
|
84
|
+
pubKey,
|
|
85
|
+
addresses: peer.addresses.map(({ multiaddr, isCertified }) => ({
|
|
86
|
+
multiaddr: new Multiaddr(multiaddr),
|
|
87
|
+
isCertified: isCertified || false
|
|
88
|
+
})),
|
|
89
|
+
metadata,
|
|
90
|
+
peerRecordEnvelope: peer.peerRecordEnvelope || undefined
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @param {Peer} peer
|
|
96
|
+
*/
|
|
97
|
+
async save (peer) {
|
|
98
|
+
if (peer.pubKey != null && peer.id.pubKey != null && !uint8arrayEquals(peer.pubKey.bytes, peer.id.pubKey.bytes)) {
|
|
99
|
+
log.error('peer publicKey bytes do not match peer id publicKey bytes')
|
|
100
|
+
throw errcode(new Error('publicKey bytes do not match peer id publicKey bytes'), codes.ERR_INVALID_PARAMETERS)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// dedupe addresses
|
|
104
|
+
const addressSet = new Set()
|
|
105
|
+
|
|
106
|
+
const buf = PeerPB.encode({
|
|
107
|
+
addresses: peer.addresses
|
|
108
|
+
.filter(address => {
|
|
109
|
+
if (addressSet.has(address.multiaddr.toString())) {
|
|
110
|
+
return false
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
addressSet.add(address.multiaddr.toString())
|
|
114
|
+
return true
|
|
115
|
+
})
|
|
116
|
+
.sort((a, b) => {
|
|
117
|
+
return a.multiaddr.toString().localeCompare(b.multiaddr.toString())
|
|
118
|
+
})
|
|
119
|
+
.map(({ multiaddr, isCertified }) => ({
|
|
120
|
+
multiaddr: multiaddr.bytes,
|
|
121
|
+
isCertified
|
|
122
|
+
})),
|
|
123
|
+
protocols: peer.protocols.sort(),
|
|
124
|
+
pubKey: peer.pubKey ? marshalPublicKey(peer.pubKey) : undefined,
|
|
125
|
+
metadata: [...peer.metadata.keys()].sort().map(key => ({ key, value: peer.metadata.get(key) })),
|
|
126
|
+
peerRecordEnvelope: peer.peerRecordEnvelope
|
|
127
|
+
}).finish()
|
|
128
|
+
|
|
129
|
+
await this._datastore.put(this._peerIdToDatastoreKey(peer.id), buf)
|
|
130
|
+
|
|
131
|
+
return this.load(peer.id)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* @param {PeerId} peerId
|
|
136
|
+
* @param {Partial<Peer>} data
|
|
137
|
+
*/
|
|
138
|
+
async patch (peerId, data) {
|
|
139
|
+
const peer = await this.load(peerId)
|
|
140
|
+
|
|
141
|
+
return await this._patch(peerId, data, peer)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* @param {PeerId} peerId
|
|
146
|
+
* @param {Partial<Peer>} data
|
|
147
|
+
*/
|
|
148
|
+
async patchOrCreate (peerId, data) {
|
|
149
|
+
/** @type {Peer} */
|
|
150
|
+
let peer
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
peer = await this.load(peerId)
|
|
154
|
+
} catch (/** @type {any} */ err) {
|
|
155
|
+
if (err.code !== codes.ERR_NOT_FOUND) {
|
|
156
|
+
throw err
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
peer = { id: peerId, addresses: [], protocols: [], metadata: new Map() }
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return await this._patch(peerId, data, peer)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* @param {PeerId} peerId
|
|
167
|
+
* @param {Partial<Peer>} data
|
|
168
|
+
* @param {Peer} peer
|
|
169
|
+
*/
|
|
170
|
+
async _patch (peerId, data, peer) {
|
|
171
|
+
return await this.save({
|
|
172
|
+
...peer,
|
|
173
|
+
...data,
|
|
174
|
+
id: peerId
|
|
175
|
+
})
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @param {PeerId} peerId
|
|
180
|
+
* @param {Partial<Peer>} data
|
|
181
|
+
*/
|
|
182
|
+
async merge (peerId, data) {
|
|
183
|
+
const peer = await this.load(peerId)
|
|
184
|
+
|
|
185
|
+
return this._merge(peerId, data, peer)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* @param {PeerId} peerId
|
|
190
|
+
* @param {Partial<Peer>} data
|
|
191
|
+
*/
|
|
192
|
+
async mergeOrCreate (peerId, data) {
|
|
193
|
+
/** @type {Peer} */
|
|
194
|
+
let peer
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
peer = await this.load(peerId)
|
|
198
|
+
} catch (/** @type {any} */ err) {
|
|
199
|
+
if (err.code !== codes.ERR_NOT_FOUND) {
|
|
200
|
+
throw err
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
peer = { id: peerId, addresses: [], protocols: [], metadata: new Map() }
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return await this._merge(peerId, data, peer)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* @param {PeerId} peerId
|
|
211
|
+
* @param {Partial<Peer>} data
|
|
212
|
+
* @param {Peer} peer
|
|
213
|
+
*/
|
|
214
|
+
async _merge (peerId, data, peer) {
|
|
215
|
+
// if the peer has certified addresses, use those in
|
|
216
|
+
// favour of the supplied versions
|
|
217
|
+
/** @type {Map<string, boolean>} */
|
|
218
|
+
const addresses = new Map()
|
|
219
|
+
|
|
220
|
+
;(data.addresses || []).forEach(addr => {
|
|
221
|
+
addresses.set(addr.multiaddr.toString(), addr.isCertified)
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
peer.addresses.forEach(({ multiaddr, isCertified }) => {
|
|
225
|
+
const addrStr = multiaddr.toString()
|
|
226
|
+
addresses.set(addrStr, Boolean(addresses.get(addrStr) || isCertified))
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
return await this.save({
|
|
230
|
+
id: peerId,
|
|
231
|
+
addresses: Array.from(addresses.entries()).map(([addrStr, isCertified]) => {
|
|
232
|
+
return {
|
|
233
|
+
multiaddr: new Multiaddr(addrStr),
|
|
234
|
+
isCertified
|
|
235
|
+
}
|
|
236
|
+
}),
|
|
237
|
+
protocols: Array.from(new Set([
|
|
238
|
+
...(peer.protocols || []),
|
|
239
|
+
...(data.protocols || [])
|
|
240
|
+
])),
|
|
241
|
+
metadata: new Map([
|
|
242
|
+
...(peer.metadata ? peer.metadata.entries() : []),
|
|
243
|
+
...(data.metadata ? data.metadata.entries() : [])
|
|
244
|
+
]),
|
|
245
|
+
pubKey: data.pubKey || (peer != null ? peer.pubKey : undefined),
|
|
246
|
+
peerRecordEnvelope: data.peerRecordEnvelope || (peer != null ? peer.peerRecordEnvelope : undefined)
|
|
247
|
+
})
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
async * all () {
|
|
251
|
+
for await (const key of this._datastore.queryKeys({
|
|
252
|
+
prefix: NAMESPACE_COMMON
|
|
253
|
+
})) {
|
|
254
|
+
// /peers/${peer-id-as-libp2p-key-cid-string-in-base-32}
|
|
255
|
+
const base32Str = key.toString().split('/')[2]
|
|
256
|
+
const buf = base32.decode(base32Str)
|
|
257
|
+
|
|
258
|
+
yield this.load(PeerId.createFromBytes(buf))
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
module.exports = PersistentStore
|