blind-peer 0.0.3 → 2.7.4
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/README.md +70 -2
- package/bin.js +165 -6
- package/index.js +425 -87
- package/lib/db.js +164 -0
- package/package.json +39 -14
- package/.github/workflows/test-node.yml +0 -23
- package/build.js +0 -102
- package/client.js +0 -31
- package/example/autobase.mjs +0 -66
- package/example/blind-peer.mjs +0 -6
- package/example/post.mjs +0 -25
- package/spec/hyperdb/db.json +0 -19
- package/spec/hyperdb/index.js +0 -83
- package/spec/hyperdb/messages.js +0 -234
- package/spec/hyperschema/index.js +0 -199
- package/spec/hyperschema/schema.json +0 -107
package/index.js
CHANGED
|
@@ -1,137 +1,475 @@
|
|
|
1
|
-
const AutobaseLightWriter = require('autobase-light-writer')
|
|
2
|
-
const HyperDB = require('hyperdb')
|
|
3
1
|
const Corestore = require('corestore')
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
2
|
+
const Hypercore = require('hypercore')
|
|
3
|
+
const RocksDB = require('rocksdb-native')
|
|
4
|
+
const ReadyResource = require('ready-resource')
|
|
7
5
|
const Hyperswarm = require('hyperswarm')
|
|
8
6
|
const ProtomuxRPC = require('protomux-rpc')
|
|
9
7
|
const c = require('compact-encoding')
|
|
8
|
+
const b4a = require('b4a')
|
|
9
|
+
const crypto = require('hypercore-crypto')
|
|
10
|
+
const safetyCatch = require('safety-catch')
|
|
11
|
+
const Wakeup = require('protomux-wakeup')
|
|
12
|
+
const ScopeLock = require('scope-lock')
|
|
13
|
+
const IdEnc = require('hypercore-id-encoding')
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
const BlindPeerDB = require('./lib/db.js')
|
|
16
|
+
|
|
17
|
+
const { AddCoreEncoding } = require('blind-peer-encodings')
|
|
18
|
+
|
|
19
|
+
class CoreTracker {
|
|
20
|
+
constructor (blindPeer, core) {
|
|
21
|
+
this.blindPeer = blindPeer
|
|
22
|
+
this.core = core
|
|
23
|
+
this.destroyed = false
|
|
24
|
+
this.record = null
|
|
25
|
+
this.activated = false
|
|
26
|
+
this.updated = false
|
|
27
|
+
this.id = null
|
|
28
|
+
this.referrerDiscoveryKey = null
|
|
29
|
+
this.channel = null
|
|
30
|
+
this.downloadRange = null
|
|
31
|
+
this.announceToReferrerBound = this.announceToReferrer.bind(this)
|
|
32
|
+
|
|
33
|
+
const onupdate = this._onupdate.bind(this)
|
|
34
|
+
const onactive = this._onactive.bind(this)
|
|
35
|
+
|
|
36
|
+
this.core.on('upload', onactive)
|
|
37
|
+
this.core.on('download', onactive)
|
|
38
|
+
this.core.on('truncate', onupdate)
|
|
39
|
+
this.core.on('append', onupdate)
|
|
17
40
|
}
|
|
18
41
|
|
|
19
|
-
|
|
20
|
-
this.
|
|
42
|
+
_onupdate () {
|
|
43
|
+
this.updated = true
|
|
44
|
+
if (!this.record) return
|
|
21
45
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
46
|
+
this.record.length = this.core.length
|
|
47
|
+
this.record.bytesAllocated = this.core.byteLength - this.record.bytesCleared
|
|
48
|
+
this.blindPeer.db.updateCore(this.record, this.id)
|
|
49
|
+
this.blindPeer.flush().then(this.announceToReferrerBound, safetyCatch)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
_onactive () {
|
|
53
|
+
this.activated = true
|
|
54
|
+
|
|
55
|
+
if (this.record) {
|
|
56
|
+
this.blindPeer.db.updateCore(this.record, this.id)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
this.blindPeer.emit('core-activity', this.core, this.record)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
gc () { // TODO: support gc-ing till less than last block (required hypercore to support getting byteLength at arbitrary versions)
|
|
63
|
+
const bytesCleared = this.core.byteLength
|
|
64
|
+
const blocksCleared = this.core.length
|
|
65
|
+
this.record.bytesAllocated = this.core.byteLength - bytesCleared
|
|
66
|
+
this.record.blocksCleared = blocksCleared
|
|
67
|
+
this.record.bytesCleared = bytesCleared
|
|
68
|
+
|
|
69
|
+
if (this.downloadRange) this.downloadRange.destroy()
|
|
70
|
+
this.downloadRange = this.core.download({ start: this.record.blocksCleared, end: -1 })
|
|
71
|
+
|
|
72
|
+
this.core.clear(0, blocksCleared).catch(safetyCatch)
|
|
73
|
+
this.blindPeer.db.updateCore(this.record, this.id)
|
|
26
74
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
75
|
+
return bytesCleared
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async refresh () {
|
|
79
|
+
await this.core.ready()
|
|
80
|
+
if (this.destroyed) return
|
|
81
|
+
|
|
82
|
+
this.id = this.core.id
|
|
83
|
+
this.channel = 'hypercore/alpha##' + b4a.toString(this.core.discoveryKey, 'hex')
|
|
84
|
+
|
|
85
|
+
const record = await this.blindPeer.db.get('@blind-peer/cores', { key: this.core.key })
|
|
86
|
+
if (this.destroyed || this.record || !record) return
|
|
31
87
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
88
|
+
this.record = record
|
|
89
|
+
this.core.download({ start: this.record.blocksCleared, end: -1 })
|
|
90
|
+
|
|
91
|
+
if (this.updated) this._onupdate()
|
|
92
|
+
if (this.activated) this._onactive()
|
|
36
93
|
}
|
|
37
94
|
|
|
38
|
-
|
|
39
|
-
|
|
95
|
+
announceToReferrer () {
|
|
96
|
+
if (!this.record || !this.record.referrer) return
|
|
97
|
+
if (!this.referrerDiscoveryKey) this.referrerDiscoveryKey = crypto.discoveryKey(this.record.referrer)
|
|
98
|
+
|
|
99
|
+
const sessions = this.blindPeer.wakeup.getSessions(null, { discoveryKey: this.referrerDiscoveryKey })
|
|
100
|
+
if (sessions.length === 0) return
|
|
101
|
+
|
|
102
|
+
const wakeup = [{ key: this.core.key, length: this.core.length }]
|
|
103
|
+
|
|
104
|
+
for (const s of sessions) {
|
|
105
|
+
for (const peer of s.peers) {
|
|
106
|
+
const mux = peer.stream.userData
|
|
40
107
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
108
|
+
// already replicating with that peer
|
|
109
|
+
if (mux._infos.get(this.channel)) {
|
|
110
|
+
continue
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
s.announceByStream(peer.stream, wakeup)
|
|
114
|
+
}
|
|
45
115
|
}
|
|
46
116
|
}
|
|
47
117
|
|
|
48
|
-
|
|
49
|
-
|
|
118
|
+
destroy () {
|
|
119
|
+
if (this.destroyed) return
|
|
120
|
+
this.destroyed = true
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
class WakeupHandler {
|
|
125
|
+
constructor (db, key, discoveryKey) {
|
|
126
|
+
this.db = db
|
|
127
|
+
this.key = key
|
|
128
|
+
this.discoveryKey = discoveryKey
|
|
129
|
+
this.active = false
|
|
50
130
|
}
|
|
51
131
|
|
|
52
|
-
async
|
|
132
|
+
async onpeeractive (peer, session) {
|
|
133
|
+
const referrer = this.key
|
|
134
|
+
const query = {
|
|
135
|
+
gte: { referrer },
|
|
136
|
+
lte: { referrer },
|
|
137
|
+
reverse: true,
|
|
138
|
+
limit: 32
|
|
139
|
+
}
|
|
140
|
+
|
|
53
141
|
try {
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
142
|
+
const latest = await this.db.find('@blind-peer/cores-by-referrer', query).toArray()
|
|
143
|
+
if (peer.removed) return
|
|
144
|
+
session.announce(peer, latest)
|
|
145
|
+
} catch {
|
|
146
|
+
// do nothing
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
56
150
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
})
|
|
151
|
+
class BlindPeer extends ReadyResource {
|
|
152
|
+
constructor (rocks, { swarm, store, wakeup, maxBytes = 100_000_000_000, enableGc = true, trustedPubKeys, port } = {}) {
|
|
153
|
+
super()
|
|
61
154
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
155
|
+
this.rocks = typeof rocks === 'string' ? new RocksDB(rocks) : rocks
|
|
156
|
+
this.store = store || new Corestore(this.rocks, { active: false })
|
|
157
|
+
this.swarm = swarm || null
|
|
158
|
+
this._port = port || null
|
|
159
|
+
this.trustedPubKeys = new Set()
|
|
160
|
+
for (const k of trustedPubKeys || []) this.addTrustedPubKey(k)
|
|
65
161
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
162
|
+
this.wakeup = wakeup || new Wakeup(this._onwakeup.bind(this))
|
|
163
|
+
this.ownsWakeup = !wakeup
|
|
164
|
+
this.ownsSwarm = !swarm
|
|
165
|
+
this.ownsStore = !store
|
|
166
|
+
this.db = null
|
|
167
|
+
this.activeReplication = new Map()
|
|
168
|
+
this.activeWakeup = new Map()
|
|
169
|
+
this.flushInterval = null
|
|
170
|
+
this.maxBytes = maxBytes
|
|
171
|
+
this.enableGc = enableGc
|
|
172
|
+
this.lock = new ScopeLock({ debounce: true })
|
|
173
|
+
this.announcedCores = new Map()
|
|
69
174
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
} catch (err) {
|
|
74
|
-
console.log(err)
|
|
175
|
+
this.stats = {
|
|
176
|
+
bytesGcd: 0,
|
|
177
|
+
coresAdded: 0
|
|
75
178
|
}
|
|
76
179
|
}
|
|
77
180
|
|
|
181
|
+
get encryptionPublicKey () {
|
|
182
|
+
return this.db.encryptionKeyPair.publicKey
|
|
183
|
+
}
|
|
184
|
+
|
|
78
185
|
get publicKey () {
|
|
79
|
-
return this.swarm.
|
|
186
|
+
return this.swarm.keyPair.publicKey
|
|
80
187
|
}
|
|
81
188
|
|
|
82
|
-
|
|
83
|
-
this.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
189
|
+
get digest () {
|
|
190
|
+
return this.db.digest
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
addTrustedPubKey (key) {
|
|
194
|
+
this.trustedPubKeys.add(IdEnc.normalize(key))
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
_isTrustedPeer (key) {
|
|
198
|
+
return this.trustedPubKeys.has(IdEnc.normalize(key))
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async _open () {
|
|
202
|
+
await this.store.ready()
|
|
203
|
+
// legacy, we can remove once current ones are upgraded
|
|
204
|
+
const { secretKey } = await this.store.createKeyPair('blind-mirror-swarm')
|
|
205
|
+
this.db = new BlindPeerDB(this.rocks.session(), { swarming: secretKey.subarray(0, 32), encryption: null })
|
|
206
|
+
await this.db.ready()
|
|
207
|
+
|
|
208
|
+
if (this.swarm === null) {
|
|
209
|
+
const swarmOpts = { keyPair: this.db.swarmingKeyPair }
|
|
210
|
+
if (this._port) swarmOpts.port = this._port
|
|
211
|
+
this.swarm = new Hyperswarm(swarmOpts)
|
|
212
|
+
}
|
|
87
213
|
this.swarm.on('connection', this._onconnection.bind(this))
|
|
214
|
+
|
|
215
|
+
const announceProms = []
|
|
216
|
+
for await (const record of this.db.createAnnouncingCoresStream()) {
|
|
217
|
+
announceProms.push(this._announceCore(record.key))
|
|
218
|
+
}
|
|
219
|
+
await Promise.all(announceProms)
|
|
220
|
+
|
|
221
|
+
this.store.watch(this._oncoreopen.bind(this))
|
|
222
|
+
|
|
223
|
+
this.flushInterval = setInterval(this.flush.bind(this), 10_000)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async _onwakeup (discoveryKey, muxer) {
|
|
227
|
+
const auth = await this.store.storage.getAuth(discoveryKey)
|
|
228
|
+
if (!auth) return
|
|
229
|
+
|
|
230
|
+
const stream = muxer.stream
|
|
231
|
+
const handler = new WakeupHandler(this.db, auth.key, discoveryKey)
|
|
232
|
+
const w = this.wakeup.session(auth.key, handler)
|
|
233
|
+
|
|
234
|
+
if (w.getPeer(stream)) {
|
|
235
|
+
w.destroy()
|
|
236
|
+
return
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
w.addStream(stream)
|
|
240
|
+
|
|
241
|
+
for (const peer of w.peers) {
|
|
242
|
+
if (peer.active) handler.onpeeractive(peer, w)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
stream.setMaxListeners(0)
|
|
246
|
+
stream.once('close', () => w.destroy())
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async listen () {
|
|
250
|
+
if (!this.opened) await this.ready()
|
|
88
251
|
return this.swarm.listen()
|
|
89
252
|
}
|
|
90
253
|
|
|
91
|
-
|
|
92
|
-
return
|
|
254
|
+
needsGc () {
|
|
255
|
+
return this.digest.bytesAllocated >= this.maxBytes
|
|
93
256
|
}
|
|
94
257
|
|
|
95
|
-
async
|
|
96
|
-
|
|
258
|
+
async _gc () { // Do not call directly (assumes lock)
|
|
259
|
+
if (!this.needsGc()) return
|
|
260
|
+
|
|
261
|
+
const bytesToClear = this.digest.bytesAllocated - this.maxBytes
|
|
262
|
+
let bytesCleared = 0
|
|
263
|
+
this.emit('gc-start', { bytesToClear })
|
|
264
|
+
|
|
265
|
+
for await (const record of this.db.createGcCandidateReadStream()) {
|
|
266
|
+
if (this.closing) return
|
|
267
|
+
if (bytesCleared >= bytesToClear) break
|
|
268
|
+
if (record.bytesAllocated === 0) continue
|
|
269
|
+
if (record.announce) continue // We never clear these ATM, since we do no book keeping on the cleared length of announced cores
|
|
97
270
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
271
|
+
const { key } = record
|
|
272
|
+
|
|
273
|
+
// Explicitly opening the core ensures an active replication
|
|
274
|
+
// session exists
|
|
275
|
+
const core = this.store.get({ key })
|
|
276
|
+
await core.ready()
|
|
277
|
+
if (this.closing) return
|
|
278
|
+
const id = b4a.toString(core.discoveryKey, 'hex')
|
|
279
|
+
|
|
280
|
+
try {
|
|
281
|
+
const tracker = this.activeReplication.get(id)
|
|
282
|
+
const coreBytesCleared = tracker.gc()
|
|
283
|
+
bytesCleared += coreBytesCleared
|
|
284
|
+
} finally {
|
|
285
|
+
await core.close().catch(safetyCatch)
|
|
286
|
+
}
|
|
104
287
|
}
|
|
105
288
|
|
|
106
|
-
const w = new AutobaseLightWriter(this.store.namespace(autobase), autobase, { active: false })
|
|
107
|
-
await w.ready()
|
|
108
|
-
const entry = { autobase, writer: w.local.key, blockEncryptionKey }
|
|
109
|
-
await this.db.insert('@blind-peer/mailbox', entry)
|
|
110
289
|
await this.db.flush()
|
|
111
|
-
|
|
290
|
+
if (this.closing) return
|
|
291
|
+
this.stats.bytesGcd += bytesCleared
|
|
292
|
+
this.emit('gc-done', { bytesCleared })
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
_onreferrerupdates (updates) {
|
|
296
|
+
const pending = new Set()
|
|
297
|
+
|
|
298
|
+
for (const u of updates) {
|
|
299
|
+
const id = b4a.toString(u.referrer, 'hex')
|
|
300
|
+
const w = this.activeWakeup.get(id)
|
|
301
|
+
if (!w) continue
|
|
302
|
+
|
|
303
|
+
w.queued.push(u)
|
|
304
|
+
pending.add(w)
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
for (const w of pending) {
|
|
308
|
+
w.flush()
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
_oncoreopen (core) {
|
|
313
|
+
const session = new Hypercore({ core, weak: true })
|
|
314
|
+
const id = b4a.toString(core.discoveryKey, 'hex')
|
|
315
|
+
const tracker = new CoreTracker(this, session)
|
|
316
|
+
|
|
317
|
+
this.activeReplication.set(id, tracker)
|
|
318
|
+
tracker.refresh().catch(safetyCatch)
|
|
319
|
+
|
|
320
|
+
session.on('close', () => {
|
|
321
|
+
tracker.destroy()
|
|
322
|
+
if (this.activeReplication.get(id) === tracker) {
|
|
323
|
+
this.activeReplication.delete(id)
|
|
324
|
+
}
|
|
325
|
+
})
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
async flush () { // not allowed to throw
|
|
329
|
+
if (!(await this.lock.lock())) return
|
|
330
|
+
try {
|
|
331
|
+
if (this.enableGc && this.needsGc()) await this._gc()
|
|
332
|
+
if (this.db.updated()) await this.db.flush()
|
|
333
|
+
} catch (e) {
|
|
334
|
+
safetyCatch(e)
|
|
335
|
+
} finally {
|
|
336
|
+
this.lock.unlock()
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
_onconnection (conn) {
|
|
341
|
+
if (this.closing) {
|
|
342
|
+
conn.destroy()
|
|
343
|
+
return
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (this.ownsStore) this.store.replicate(conn)
|
|
347
|
+
if (this.ownsWakeup) this.wakeup.addStream(conn)
|
|
348
|
+
|
|
349
|
+
const rpc = new ProtomuxRPC(conn, {
|
|
350
|
+
id: this.swarm.keyPair.publicKey,
|
|
351
|
+
valueEncoding: c.none
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
rpc.respond('add-core', AddCoreEncoding, this._onaddcore.bind(this, conn))
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
async _activateCore (stream, record) {
|
|
358
|
+
const core = this.store.get({ key: record.key })
|
|
359
|
+
await core.ready()
|
|
112
360
|
|
|
113
|
-
|
|
361
|
+
const tracker = this.activeReplication.get(b4a.toString(core.discoveryKey, 'hex'))
|
|
362
|
+
if (tracker && !tracker.record) await tracker.refresh()
|
|
363
|
+
|
|
364
|
+
if (record.announce) {
|
|
365
|
+
await this._announceCore(core.key)
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (stream.destroying) {
|
|
369
|
+
await core.close()
|
|
370
|
+
return
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
core.replicate(stream)
|
|
374
|
+
stream.on('close', () => core.close().catch(safetyCatch))
|
|
114
375
|
}
|
|
115
376
|
|
|
116
|
-
async
|
|
117
|
-
const
|
|
118
|
-
if (
|
|
377
|
+
async _announceCore (key) {
|
|
378
|
+
const coreId = IdEnc.normalize(key)
|
|
379
|
+
if (this.announcedCores.has(coreId)) return
|
|
380
|
+
|
|
381
|
+
const core = this.store.get({ key })
|
|
382
|
+
this.announcedCores.set(coreId, core)
|
|
119
383
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
384
|
+
core.on('append', () => {
|
|
385
|
+
this.emit('core-append', core)
|
|
386
|
+
})
|
|
387
|
+
core.on('download', () => {
|
|
388
|
+
if (core.length === core.contiguousLength) {
|
|
389
|
+
this.emit('core-downloaded', core)
|
|
390
|
+
}
|
|
123
391
|
})
|
|
124
|
-
await w.append(message)
|
|
125
|
-
const length = w.local.length
|
|
126
|
-
await w.close()
|
|
127
392
|
|
|
128
|
-
|
|
393
|
+
await core.ready()
|
|
394
|
+
this.swarm.join(core.discoveryKey, { server: true, client: false })
|
|
395
|
+
|
|
396
|
+
// WARNING: we do not yet handle the case where
|
|
397
|
+
// data of an announced core is cleared
|
|
398
|
+
core.download({ start: 0, end: -1 })
|
|
399
|
+
|
|
400
|
+
this.emit('announce-core', core)
|
|
129
401
|
}
|
|
130
402
|
|
|
131
|
-
async
|
|
132
|
-
if (this.
|
|
133
|
-
|
|
403
|
+
async _onaddcore (stream, record) {
|
|
404
|
+
if (!this.opened) await this.ready()
|
|
405
|
+
|
|
406
|
+
record.priority = Math.min(record.priority, 1) // 2 is reserved for trusted peers
|
|
407
|
+
if (record.announce !== false && !this._isTrustedPeer(stream.remotePublicKey)) {
|
|
408
|
+
this.emit('downgrade-announce', { record, remotePublicKey: stream.remotePublicKey })
|
|
409
|
+
record.announce = false
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
this.db.addCore(record)
|
|
413
|
+
await this.flush() // flush now as important data
|
|
414
|
+
|
|
415
|
+
if (record.referrer) {
|
|
416
|
+
// ensure referrer is allocated...
|
|
417
|
+
// TODO: move to a dedicated wakeup collection, insted of using a core since we moved away from that
|
|
418
|
+
// still works atm, cause dkey
|
|
419
|
+
const muxer = stream.userData
|
|
420
|
+
const core = this.store.get({ key: record.referrer })
|
|
421
|
+
await core.ready()
|
|
422
|
+
const discoveryKey = core.discoveryKey
|
|
423
|
+
await core.close()
|
|
424
|
+
|
|
425
|
+
await this._onwakeup(discoveryKey, muxer)
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
this.stats.coresAdded++
|
|
429
|
+
this.emit('add-core', record, true)
|
|
430
|
+
|
|
431
|
+
await this._activateCore(stream, record)
|
|
432
|
+
|
|
433
|
+
const coreRecord = await this.db.getCoreRecord(record.key)
|
|
434
|
+
return coreRecord
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
async _close () {
|
|
438
|
+
clearInterval(this.flushInterval)
|
|
439
|
+
if (this.ownsWakeup) this.wakeup.destroy()
|
|
440
|
+
if (this.ownsSwarm) await this.swarm.destroy()
|
|
441
|
+
await this.flush()
|
|
442
|
+
await this.db.close()
|
|
443
|
+
if (this.ownsStore) await this.store.close()
|
|
444
|
+
await this.rocks.close()
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
registerMetrics (promClient) {
|
|
448
|
+
const self = this
|
|
449
|
+
new promClient.Gauge({ // eslint-disable-line no-new
|
|
450
|
+
name: 'blind_peer_bytes_allocated',
|
|
451
|
+
help: 'The amount of bytes allocated by the hyperdb (as reported in its digest)',
|
|
452
|
+
collect () {
|
|
453
|
+
this.set(self.digest.bytesAllocated)
|
|
454
|
+
}
|
|
455
|
+
})
|
|
456
|
+
|
|
457
|
+
new promClient.Gauge({ // eslint-disable-line no-new
|
|
458
|
+
name: 'blind_peer_cores_added',
|
|
459
|
+
help: 'The total amount of add-core RPC requests that have been processed',
|
|
460
|
+
collect () {
|
|
461
|
+
this.set(self.stats.coresAdded)
|
|
462
|
+
}
|
|
463
|
+
})
|
|
464
|
+
|
|
465
|
+
new promClient.Gauge({ // eslint-disable-line no-new
|
|
466
|
+
name: 'blind_peer_bytes_gcd',
|
|
467
|
+
help: 'The total amount of bytes garbage collected since the process started',
|
|
468
|
+
collect () {
|
|
469
|
+
this.set(self.stats.bytesGcd)
|
|
470
|
+
}
|
|
471
|
+
})
|
|
134
472
|
}
|
|
135
473
|
}
|
|
136
474
|
|
|
137
|
-
|
|
475
|
+
module.exports = BlindPeer
|