blind-peer 2.8.1 → 2.8.3

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 (5) hide show
  1. package/README.md +3 -5
  2. package/bin.js +114 -40
  3. package/index.js +77 -54
  4. package/lib/db.js +23 -21
  5. package/package.json +7 -4
package/README.md CHANGED
@@ -71,18 +71,16 @@ blind.addAutobaseBackground(autobase1)
71
71
 
72
72
  // Add another core
73
73
  blind.addCore(core1, autobase1.wakeupCapability.key)
74
-
75
74
  ```
76
75
 
77
76
  Related services:
78
77
 
79
- https://github.com/holepunchto/autobase-discovery
80
- https://github.com/HDegroote/dht-prometheus
81
-
78
+ https://github.com/holepunchto/autobase-discovery
79
+ https://github.com/HDegroote/dht-prometheus
82
80
 
83
81
  ## Programmatic Usage
84
82
 
85
- ``` js
83
+ ```js
86
84
  const BlindPeer = require('blind-peer')
87
85
  ```
88
86
 
package/bin.js CHANGED
@@ -16,20 +16,50 @@ const BlindPeer = require('.')
16
16
  const SERVICE_NAME = 'blind-peer'
17
17
  const DEFAULT_STORAGE_LIMIT_MB = 100_000
18
18
 
19
- const cmd = command('blind-peer',
19
+ const cmd = command(
20
+ 'blind-peer',
20
21
  flag('--storage|-s [path]', 'Storage path, defaults to ./blind-peer'),
21
- flag('--port|-p [int]', 'DHT Port to try to bind to. Only relevant when that port is not firewalled. (defaults to a random port)'),
22
- flag('--trusted-peer|-t [trusted-peer]', 'Public key of a trusted peer (allowed to set announce: true). Can be more than 1.').multiple(),
22
+ flag(
23
+ '--port|-p [int]',
24
+ 'DHT Port to try to bind to. Only relevant when that port is not firewalled. (defaults to a random port)'
25
+ ),
26
+ flag(
27
+ '--trusted-peer|-t [trusted-peer]',
28
+ 'Public key of a trusted peer (allowed to set announce: true). Can be more than 1.'
29
+ ).multiple(),
23
30
  flag('--debug|-d', 'Enable debug mode (more logs)'),
24
- flag(`--max-storage|-m [int]', 'Max storage usage, in Mb (defaults to ${DEFAULT_STORAGE_LIMIT_MB})`),
25
- flag('--autodiscovery-rpc-key [autodiscovery-rpc-key]', 'Public key where the autodiscovery service is listening. When set, the autodiscovery-seed must also be set. Can be hex or z32.'),
26
- flag('--autodiscovery-seed [autodiscovery-seed]', '64-byte seed used to authenticate to the autodiscovery service. Can be hex or z32.'),
27
- flag('--autodiscovery-service-name [autodiscovery-service-name]', `Name under which to register the service (default ${SERVICE_NAME})`),
28
- flag('--scraper-public-key [scraper-public-key]', 'Public key of a dht-prometheus scraper. Can be hex or z32.'),
29
- flag('--scraper-secret [scraper-secret]', 'Secret of the dht-prometheus scraper. Can be hex or z32.'),
31
+ flag(
32
+ `--max-storage|-m [int]', 'Max storage usage, in Mb (defaults to ${DEFAULT_STORAGE_LIMIT_MB})`
33
+ ),
34
+ flag(
35
+ '--autodiscovery-rpc-key [autodiscovery-rpc-key]',
36
+ 'Public key where the autodiscovery service is listening. When set, the autodiscovery-seed must also be set. Can be hex or z32.'
37
+ ),
38
+ flag(
39
+ '--autodiscovery-seed [autodiscovery-seed]',
40
+ '64-byte seed used to authenticate to the autodiscovery service. Can be hex or z32.'
41
+ ),
42
+ flag(
43
+ '--autodiscovery-service-name [autodiscovery-service-name]',
44
+ `Name under which to register the service (default ${SERVICE_NAME})`
45
+ ),
46
+ flag(
47
+ '--scraper-public-key [scraper-public-key]',
48
+ 'Public key of a dht-prometheus scraper. Can be hex or z32.'
49
+ ),
50
+ flag(
51
+ '--scraper-secret [scraper-secret]',
52
+ 'Secret of the dht-prometheus scraper. Can be hex or z32.'
53
+ ),
30
54
  flag('--scraper-alias [scraper-alias]', '(optional) Alias with which to register to the scraper'),
31
- flag('--log-streams', '(Temporary, Advanced): enable debug logs on the UDX streams managed by the dht'),
32
- flag('--repl [repl]', 'Expose a repl-swarm at the passed-in seed (32 bytes in hex or z32 notation). Use for debugging only.'),
55
+ flag(
56
+ '--log-streams',
57
+ '(Temporary, Advanced): enable debug logs on the UDX streams managed by the dht'
58
+ ),
59
+ flag(
60
+ '--repl [repl]',
61
+ 'Expose a repl-swarm at the passed-in seed (32 bytes in hex or z32 notation). Use for debugging only.'
62
+ ),
33
63
  async function ({ flags }) {
34
64
  const debug = flags.debug
35
65
  const logger = pino({
@@ -44,55 +74,75 @@ const cmd = command('blind-peer',
44
74
  const port = flags.port ? parseInt(flags.port) : null
45
75
 
46
76
  const maxBytes = 1_000_000 * parseInt(flags.maxStorage || DEFAULT_STORAGE_LIMIT_MB)
47
- const trustedPubKeys = (flags.trustedPeer || []).map(k => idEnc.decode(k))
77
+ const trustedPubKeys = (flags.trustedPeer || []).map((k) => idEnc.decode(k))
48
78
 
49
79
  const blindPeer = new BlindPeer(storage, { trustedPubKeys, maxBytes, port })
50
80
 
51
- blindPeer.on('flush-error', e => {
81
+ blindPeer.on('flush-error', (e) => {
52
82
  logger.warn(`Error while flushing the db: ${e.stack}`)
53
83
  })
54
84
 
55
- blindPeer.on('add-core', (record, _, stream) => {
85
+ blindPeer.on('add-new-core', (record, _, stream) => {
56
86
  try {
57
- logger.info(`add-core request received from peer ${streamToStr(stream)} for record ${recordToStr(record)}`)
87
+ if (record.announce) {
88
+ logger.info(
89
+ `add-core request received from peer ${streamToStr(stream)} for record ${recordToStr(record)}`
90
+ )
91
+ } else {
92
+ logger.debug(
93
+ `add-core request received from peer ${streamToStr(stream)} for record ${recordToStr(record)}`
94
+ )
95
+ }
58
96
  } catch (e) {
59
97
  logger.info(`Invalid add-core request received: ${e.stack}`)
60
98
  logger.info(record)
61
99
  }
62
100
  })
63
101
  blindPeer.on('delete-blocked', (stream, { key }) => {
64
- logger.info(`Blocked delete-core request from untrusted peer ${streamToStr(stream)} for core ${idEnc.normalize(key)}`)
102
+ logger.info(
103
+ `Blocked delete-core request from untrusted peer ${streamToStr(stream)} for core ${idEnc.normalize(key)}`
104
+ )
65
105
  })
66
106
  blindPeer.on('delete-core', (stream, { key, existing }) => {
67
- logger.info(`Received delete-core request from trusted peer ${streamToStr(stream)} for core ${idEnc.normalize(key)}. Existing: ${existing}`)
107
+ logger.info(
108
+ `Received delete-core request from trusted peer ${streamToStr(stream)} for core ${idEnc.normalize(key)}. Existing: ${existing}`
109
+ )
68
110
  })
69
111
  blindPeer.on('delete-core-end', (stream, { key, announced }) => {
70
- logger.info(`Completed delete-core request from trusted peer ${streamToStr(stream)} for core ${idEnc.normalize(key)}. Was announced: ${announced}`)
112
+ logger.info(
113
+ `Completed delete-core request from trusted peer ${streamToStr(stream)} for core ${idEnc.normalize(key)}. Was announced: ${announced}`
114
+ )
71
115
  })
72
116
 
73
117
  blindPeer.on('downgrade-announce', ({ record, remotePublicKey }) => {
74
118
  try {
75
- logger.info(`Downgraded announce for peer ${idEnc.normalize(remotePublicKey)} because the peer is not trusted (Original: ${recordToStr(record)})`)
119
+ logger.info(
120
+ `Downgraded announce for peer ${idEnc.normalize(remotePublicKey)} because the peer is not trusted (Original: ${recordToStr(record)})`
121
+ )
76
122
  } catch (e) {
77
123
  logger.error(`Unexpected error while logging downgrade-announce: ${e.stack}`)
78
124
  }
79
125
  })
80
126
 
81
- blindPeer.on('announce-core', core => {
127
+ blindPeer.on('announce-core', (core) => {
82
128
  logger.info(`Started announcing core ${coreToInfo(core, true)}`)
83
129
  })
84
- blindPeer.on('core-downloaded', core => {
130
+ blindPeer.on('core-downloaded', (core) => {
85
131
  logger.info(`Announced core fully downloaded: ${coreToInfo(core, true)}`)
86
132
  })
87
- blindPeer.on('core-append', core => {
133
+ blindPeer.on('core-append', (core) => {
88
134
  logger.info(`Detected announced-core length update: ${coreToInfo(core, true)}`)
89
135
  })
90
136
 
91
137
  blindPeer.on('gc-start', ({ bytesToClear }) => {
92
- logger.info(`Starting GC, trying to clear ${byteSize(bytesToClear)} (bytes allocated: ${byteSize(blindPeer.digest.bytesAllocated)} of ${byteSize(blindPeer.maxBytes)})`)
138
+ logger.info(
139
+ `Starting GC, trying to clear ${byteSize(bytesToClear)} (bytes allocated: ${byteSize(blindPeer.digest.bytesAllocated)} of ${byteSize(blindPeer.maxBytes)})`
140
+ )
93
141
  })
94
142
  blindPeer.on('gc-done', ({ bytesCleared }) => {
95
- logger.info(`Completed GC, cleared ${byteSize(bytesCleared)} bytes (bytes allocated: ${byteSize(blindPeer.digest.bytesAllocated)} of ${byteSize(blindPeer.maxBytes)})`)
143
+ logger.info(
144
+ `Completed GC, cleared ${byteSize(bytesCleared)} bytes (bytes allocated: ${byteSize(blindPeer.digest.bytesAllocated)} of ${byteSize(blindPeer.maxBytes)})`
145
+ )
96
146
  })
97
147
  if (debug) {
98
148
  blindPeer.on('core-activity', (core) => {
@@ -104,12 +154,16 @@ const cmd = command('blind-peer',
104
154
  const address = `${from.stream?.rawStream?.remoteHost}:${from.stream?.rawStream?.remotePort}`
105
155
  const remotePubKey = idEnc.normalize(from.stream.remotePublicKey)
106
156
  const key = idEnc.normalize(core.key)
107
- logger.warn(`Received invalid request for core ${key} from peer ${remotePubKey} at ${address} (${err.stack})`)
157
+ logger.warn(
158
+ `Received invalid request for core ${key} from peer ${remotePubKey} at ${address} (${err.stack})`
159
+ )
108
160
  })
109
161
 
110
162
  logger.info(`Using storage '${storage}'`)
111
163
  if (trustedPubKeys.length > 0) {
112
- logger.info(`Trusted public keys:\n -${[...blindPeer.trustedPubKeys].map(idEnc.normalize).join('\n -')}`)
164
+ logger.info(
165
+ `Trusted public keys:\n -${[...blindPeer.trustedPubKeys].map(idEnc.normalize).join('\n -')}`
166
+ )
113
167
  }
114
168
 
115
169
  let instrumentation = null
@@ -158,11 +212,16 @@ const cmd = command('blind-peer',
158
212
  const pendingWrites = stream._wreqs.length - stream._wfree.length
159
213
  if (pendingWrites >= 100) {
160
214
  nrBigStreams++
161
- logger.warn(`Stream ${stream.id} (remote id: ${stream.remoteId}) has ${pendingWrites} pending writes:\nStream JSON: ${JSON.stringify(stream.toJSON(), null, 1)}\nSocket json: ${stream.socket ? JSON.stringify(stream.socket.toJSON(), null, 1) : 'none'}\nhex streamhandle: ${b4a.toString(stream._handle, 'hex')}\nhex socket handle: ${stream.socket ? b4a.toString(stream.socket._handle, 'hex') : 'none'}`)
215
+ logger.warn(
216
+ `Stream ${stream.id} (remote id: ${stream.remoteId}) has ${pendingWrites} pending writes:\nStream JSON: ${JSON.stringify(stream.toJSON(), null, 1)}\nSocket json: ${stream.socket ? JSON.stringify(stream.socket.toJSON(), null, 1) : 'none'}\nhex streamhandle: ${b4a.toString(stream._handle, 'hex')}\nhex socket handle: ${stream.socket ? b4a.toString(stream.socket._handle, 'hex') : 'none'}`
217
+ )
162
218
  }
163
219
  }
164
- if (nrBigStreams > 0) logger.warn(`Total streams with many pending writes: ${nrBigStreams}`)
165
- } catch (e) { // we don't want to crash the process with our debugging
220
+ if (nrBigStreams > 0) {
221
+ logger.warn(`Total streams with many pending writes: ${nrBigStreams}`)
222
+ }
223
+ } catch (e) {
224
+ // we don't want to crash the process with our debugging
166
225
  logger.warn(`logStreams errored unexpectedly: ${e.stack}`)
167
226
  }
168
227
  }, 30_000)
@@ -170,8 +229,12 @@ const cmd = command('blind-peer',
170
229
 
171
230
  await blindPeer.listen()
172
231
 
173
- logger.info(`Blind peer listening, local address is ${blindPeer.swarm.dht.localAddress().host}:${blindPeer.swarm.dht.localAddress().port}`)
174
- logger.info(`Bytes allocated: ${byteSize(blindPeer.digest.bytesAllocated)} of ${byteSize(blindPeer.maxBytes)}`)
232
+ logger.info(
233
+ `Blind peer listening, local address is ${blindPeer.swarm.dht.localAddress().host}:${blindPeer.swarm.dht.localAddress().port}`
234
+ )
235
+ logger.info(
236
+ `Bytes allocated: ${byteSize(blindPeer.digest.bytesAllocated)} of ${byteSize(blindPeer.maxBytes)}`
237
+ )
175
238
 
176
239
  if (flags.autodiscoveryRpcKey) {
177
240
  const autodiscoveryRpcKey = idEnc.decode(flags.autodiscoveryRpcKey)
@@ -180,11 +243,20 @@ const cmd = command('blind-peer',
180
243
  const registerClient = new RegisterClient(autodiscoveryRpcKey, blindPeer.swarm.dht, seed)
181
244
 
182
245
  // No need to block on this, so we run it in the background
183
- logger.info(`Registering own RPC key rpc key ${idEnc.normalize(blindPeer.publicKey)} with service '${serviceName}' at autodiscovery service ${idEnc.normalize(autodiscoveryRpcKey)} (using public key ${idEnc.normalize(registerClient.keyPair.publicKey)})`)
184
- registerClient.putService(blindPeer.publicKey, serviceName)
185
- .then(() => { logger.info('Successfully requested to be added to the autodiscovery service') })
186
- .catch(e => { logger.warn(`Failed to register to the autodiscovery service: ${e.stack}`) })
187
- .finally(() => { registerClient.close().catch(safetyCatch) })
246
+ logger.info(
247
+ `Registering own RPC key rpc key ${idEnc.normalize(blindPeer.publicKey)} with service '${serviceName}' at autodiscovery service ${idEnc.normalize(autodiscoveryRpcKey)} (using public key ${idEnc.normalize(registerClient.keyPair.publicKey)})`
248
+ )
249
+ registerClient
250
+ .putService(blindPeer.publicKey, serviceName)
251
+ .then(() => {
252
+ logger.info('Successfully requested to be added to the autodiscovery service')
253
+ })
254
+ .catch((e) => {
255
+ logger.warn(`Failed to register to the autodiscovery service: ${e.stack}`)
256
+ })
257
+ .finally(() => {
258
+ registerClient.close().catch(safetyCatch)
259
+ })
188
260
  }
189
261
 
190
262
  if (flags.scraperPublicKey) {
@@ -195,7 +267,9 @@ const cmd = command('blind-peer',
195
267
  const scraperSecret = idEnc.decode(flags.scraperSecret)
196
268
 
197
269
  let prometheusAlias = flags.scraperAlias
198
- if (prometheusAlias && prometheusAlias.length > 99) throw new Error('The Prometheus alias must have length less than 100')
270
+ if (prometheusAlias && prometheusAlias.length > 99) {
271
+ throw new Error('The Prometheus alias must have length less than 100')
272
+ }
199
273
  if (!prometheusAlias) {
200
274
  prometheusAlias = `blind-peer-${idEnc.normalize(swarm.keyPair.publicKey)}`.slice(0, 99)
201
275
  }
@@ -219,17 +293,17 @@ const cmd = command('blind-peer',
219
293
  }
220
294
  )
221
295
 
222
- function recordToStr (record) {
296
+ function recordToStr(record) {
223
297
  const discKey = hypCrypto.discoveryKey(record.key)
224
298
  return `DB Record for discovery key ${idEnc.normalize(discKey)} with priority: ${record.priority}. Announcing? ${record.announce}`
225
299
  }
226
300
 
227
- function streamToStr (stream) {
301
+ function streamToStr(stream) {
228
302
  const pubKey = idEnc.normalize(stream.remotePublicKey)
229
303
  return `${pubKey}`
230
304
  }
231
305
 
232
- function coreToInfo (core, includePublicKey = false) {
306
+ function coreToInfo(core, includePublicKey = false) {
233
307
  const discKey = hypCrypto.discoveryKey(core.key)
234
308
  let res = `Discovery key ${idEnc.normalize(discKey)} (${core.contiguousLength} / ${core.length}, ${core.peers.length} peers)`
235
309
  if (includePublicKey) res += `. Public key: ${idEnc.normalize(core.key)}`
package/index.js CHANGED
@@ -18,7 +18,7 @@ const { AddCoreEncoding } = require('blind-peer-encodings')
18
18
  const { DeleteCoreEncoding } = require('blind-peer-encodings')
19
19
 
20
20
  class CoreTracker {
21
- constructor (blindPeer, core) {
21
+ constructor(blindPeer, core) {
22
22
  this.blindPeer = blindPeer
23
23
  this.core = core
24
24
  this.destroyed = false
@@ -40,7 +40,7 @@ class CoreTracker {
40
40
  this.core.on('append', onupdate)
41
41
  }
42
42
 
43
- _onupdate () {
43
+ _onupdate() {
44
44
  this.updated = true
45
45
  if (!this.record) return
46
46
 
@@ -50,7 +50,7 @@ class CoreTracker {
50
50
  this.blindPeer.flush().then(this.announceToReferrerBound, safetyCatch)
51
51
  }
52
52
 
53
- _onactive () {
53
+ _onactive() {
54
54
  this.activated = true
55
55
 
56
56
  if (this.record) {
@@ -60,7 +60,8 @@ class CoreTracker {
60
60
  this.blindPeer.emit('core-activity', this.core, this.record)
61
61
  }
62
62
 
63
- gc () { // TODO: support gc-ing till less than last block (required hypercore to support getting byteLength at arbitrary versions)
63
+ gc() {
64
+ // TODO: support gc-ing till less than last block (required hypercore to support getting byteLength at arbitrary versions)
64
65
  const bytesCleared = this.core.byteLength
65
66
  const blocksCleared = this.core.length
66
67
  this.record.bytesAllocated = this.core.byteLength - bytesCleared
@@ -76,7 +77,7 @@ class CoreTracker {
76
77
  return bytesCleared
77
78
  }
78
79
 
79
- async refresh () {
80
+ async refresh() {
80
81
  await this.core.ready()
81
82
  if (this.destroyed) return
82
83
 
@@ -93,11 +94,14 @@ class CoreTracker {
93
94
  if (this.activated) this._onactive()
94
95
  }
95
96
 
96
- announceToReferrer () {
97
+ announceToReferrer() {
97
98
  if (!this.record || !this.record.referrer) return
98
- if (!this.referrerDiscoveryKey) this.referrerDiscoveryKey = crypto.discoveryKey(this.record.referrer)
99
+ if (!this.referrerDiscoveryKey)
100
+ this.referrerDiscoveryKey = crypto.discoveryKey(this.record.referrer)
99
101
 
100
- const sessions = this.blindPeer.wakeup.getSessions(null, { discoveryKey: this.referrerDiscoveryKey })
102
+ const sessions = this.blindPeer.wakeup.getSessions(null, {
103
+ discoveryKey: this.referrerDiscoveryKey
104
+ })
101
105
  if (sessions.length === 0) return
102
106
 
103
107
  const wakeup = [{ key: this.core.key, length: this.core.length }]
@@ -116,21 +120,21 @@ class CoreTracker {
116
120
  }
117
121
  }
118
122
 
119
- destroy () {
123
+ destroy() {
120
124
  if (this.destroyed) return
121
125
  this.destroyed = true
122
126
  }
123
127
  }
124
128
 
125
129
  class WakeupHandler {
126
- constructor (db, key, discoveryKey) {
130
+ constructor(db, key, discoveryKey) {
127
131
  this.db = db
128
132
  this.key = key
129
133
  this.discoveryKey = discoveryKey
130
134
  this.active = false
131
135
  }
132
136
 
133
- async onpeeractive (peer, session) {
137
+ async onpeeractive(peer, session) {
134
138
  const referrer = this.key
135
139
  const query = {
136
140
  gte: { referrer },
@@ -150,7 +154,10 @@ class WakeupHandler {
150
154
  }
151
155
 
152
156
  class BlindPeer extends ReadyResource {
153
- constructor (rocks, { swarm, store, wakeup, maxBytes = 100_000_000_000, enableGc = true, trustedPubKeys, port } = {}) {
157
+ constructor(
158
+ rocks,
159
+ { swarm, store, wakeup, maxBytes = 100_000_000_000, enableGc = true, trustedPubKeys, port } = {}
160
+ ) {
154
161
  super()
155
162
 
156
163
  this.rocks = typeof rocks === 'string' ? new RocksDB(rocks) : rocks
@@ -181,36 +188,39 @@ class BlindPeer extends ReadyResource {
181
188
  }
182
189
  }
183
190
 
184
- get encryptionPublicKey () {
191
+ get encryptionPublicKey() {
185
192
  return this.db.encryptionKeyPair.publicKey
186
193
  }
187
194
 
188
- get publicKey () {
195
+ get publicKey() {
189
196
  return this.swarm.keyPair.publicKey
190
197
  }
191
198
 
192
- get digest () {
199
+ get digest() {
193
200
  return this.db.digest
194
201
  }
195
202
 
196
- get nrAnnouncedCores () {
203
+ get nrAnnouncedCores() {
197
204
  return this.announcedCores.size
198
205
  }
199
206
 
200
- addTrustedPubKey (key) {
207
+ addTrustedPubKey(key) {
201
208
  this.trustedPubKeys.add(IdEnc.normalize(key))
202
209
  }
203
210
 
204
- _isTrustedPeer (key) {
211
+ _isTrustedPeer(key) {
205
212
  return this.trustedPubKeys.has(IdEnc.normalize(key))
206
213
  }
207
214
 
208
- async _open () {
215
+ async _open() {
209
216
  await this.store.ready()
210
217
 
211
218
  // legacy, we can remove once current ones are upgraded
212
219
  const { secretKey } = await this.store.createKeyPair('blind-mirror-swarm')
213
- this.db = new BlindPeerDB(this.rocks.session(), { swarming: secretKey.subarray(0, 32), encryption: null })
220
+ this.db = new BlindPeerDB(this.rocks.session(), {
221
+ swarming: secretKey.subarray(0, 32),
222
+ encryption: null
223
+ })
214
224
  await this.db.ready()
215
225
 
216
226
  // We don't need to track our own db, so we set this handler after the db core opened
@@ -218,7 +228,8 @@ class BlindPeer extends ReadyResource {
218
228
 
219
229
  if (this.swarm === null) {
220
230
  const swarmOpts = { keyPair: this.db.swarmingKeyPair }
221
- if (this._port) swarmOpts.port = typeof this._port === 'number' ? [this._port, this._port + 64] : this._port
231
+ if (this._port)
232
+ swarmOpts.port = typeof this._port === 'number' ? [this._port, this._port + 64] : this._port
222
233
  this.swarm = new Hyperswarm(swarmOpts)
223
234
  }
224
235
  this.swarm.on('connection', this._onconnection.bind(this))
@@ -232,7 +243,7 @@ class BlindPeer extends ReadyResource {
232
243
  this.flushInterval = setInterval(this.flush.bind(this), 10_000)
233
244
  }
234
245
 
235
- async _onwakeup (discoveryKey, muxer) {
246
+ async _onwakeup(discoveryKey, muxer) {
236
247
  this.stats.wakeups++
237
248
 
238
249
  const auth = await this.store.storage.getAuth(discoveryKey)
@@ -256,16 +267,17 @@ class BlindPeer extends ReadyResource {
256
267
  stream.once('close', () => w.destroy())
257
268
  }
258
269
 
259
- async listen () {
270
+ async listen() {
260
271
  if (!this.opened) await this.ready()
261
272
  return this.swarm.listen()
262
273
  }
263
274
 
264
- needsGc () {
275
+ needsGc() {
265
276
  return this.digest.bytesAllocated >= this.maxBytes
266
277
  }
267
278
 
268
- async _gc () { // Do not call directly (assumes lock)
279
+ async _gc() {
280
+ // Do not call directly (assumes lock)
269
281
  if (!this.needsGc()) return
270
282
 
271
283
  const bytesToClear = this.digest.bytesAllocated - this.maxBytes
@@ -302,7 +314,7 @@ class BlindPeer extends ReadyResource {
302
314
  this.emit('gc-done', { bytesCleared })
303
315
  }
304
316
 
305
- _onreferrerupdates (updates) {
317
+ _onreferrerupdates(updates) {
306
318
  const pending = new Set()
307
319
 
308
320
  for (const u of updates) {
@@ -319,7 +331,7 @@ class BlindPeer extends ReadyResource {
319
331
  }
320
332
  }
321
333
 
322
- _oncoreopen (core) {
334
+ _oncoreopen(core) {
323
335
  const session = new Hypercore({ core, weak: true })
324
336
  const id = b4a.toString(core.discoveryKey, 'hex')
325
337
  const tracker = new CoreTracker(this, session)
@@ -338,7 +350,8 @@ class BlindPeer extends ReadyResource {
338
350
  })
339
351
  }
340
352
 
341
- async flush () { // not allowed to throw
353
+ async flush() {
354
+ // not allowed to throw
342
355
  if (!(await this.lock.lock())) return
343
356
  try {
344
357
  if (this.enableGc && this.needsGc()) await this._gc()
@@ -351,7 +364,7 @@ class BlindPeer extends ReadyResource {
351
364
  }
352
365
  }
353
366
 
354
- _onconnection (conn) {
367
+ _onconnection(conn) {
355
368
  if (this.closing) {
356
369
  conn.destroy()
357
370
  return
@@ -369,7 +382,7 @@ class BlindPeer extends ReadyResource {
369
382
  rpc.respond('delete-core', DeleteCoreEncoding, this._ondeletecore.bind(this, conn))
370
383
  }
371
384
 
372
- async _activateCore (stream, record) {
385
+ async _activateCore(stream, record) {
373
386
  this.stats.activations++
374
387
 
375
388
  const core = this.store.get({ key: record.key })
@@ -391,7 +404,7 @@ class BlindPeer extends ReadyResource {
391
404
  stream.on('close', () => core.close().catch(safetyCatch))
392
405
  }
393
406
 
394
- async _announceCore (key) {
407
+ async _announceCore(key) {
395
408
  const coreId = IdEnc.normalize(key)
396
409
  if (this.announcedCores.has(coreId)) return
397
410
 
@@ -417,7 +430,7 @@ class BlindPeer extends ReadyResource {
417
430
  this.emit('announce-core', core)
418
431
  }
419
432
 
420
- async _onaddcore (stream, record) {
433
+ async _onaddcore(stream, record) {
421
434
  if (!this.opened) await this.ready()
422
435
 
423
436
  record.priority = Math.min(record.priority, 1) // 2 is reserved for trusted peers
@@ -426,12 +439,14 @@ class BlindPeer extends ReadyResource {
426
439
  record.announce = false
427
440
  }
428
441
 
429
- // We only add it to the db the first time (prio, announce etc can't be changed)
442
+ // We only add it to the db the first time, except if announce changed
430
443
  // Note: not race condition safe, but it's no problem if we do add the same core twice
431
444
  const existing = await this.db.getCoreRecord(record.key)
432
- if (!existing) {
445
+ const upgradeToAnnounce = existing && !existing.announce && record.announce
446
+ if (!existing || upgradeToAnnounce) {
433
447
  this.db.addCore(record)
434
448
  await this.flush() // flush now as important data
449
+ this.emit('add-new-core', record, true, stream)
435
450
  }
436
451
 
437
452
  if (record.referrer) {
@@ -456,13 +471,13 @@ class BlindPeer extends ReadyResource {
456
471
  return coreRecord
457
472
  }
458
473
 
459
- async _ondeletecore (stream, { key }) {
474
+ async _ondeletecore(stream, { key }) {
460
475
  if (!this._isTrustedPeer(stream.remotePublicKey)) {
461
476
  this.emit('delete-blocked', stream, { key })
462
477
  throw new Error('Only trusted peers can delete cores')
463
478
  }
464
479
 
465
- const existing = await this.db.getCoreRecord(key) !== null
480
+ const existing = (await this.db.getCoreRecord(key)) !== null
466
481
  this.emit('delete-core', stream, { key, existing })
467
482
  if (!existing) return false
468
483
 
@@ -501,7 +516,7 @@ class BlindPeer extends ReadyResource {
501
516
  return true
502
517
  }
503
518
 
504
- async _close () {
519
+ async _close() {
505
520
  clearInterval(this.flushInterval)
506
521
  if (this.ownsWakeup) this.wakeup.destroy()
507
522
  if (this.ownsSwarm) await this.swarm.destroy()
@@ -511,68 +526,76 @@ class BlindPeer extends ReadyResource {
511
526
  await this.rocks.close()
512
527
  }
513
528
 
514
- registerMetrics (promClient) {
529
+ registerMetrics(promClient) {
515
530
  const self = this
516
- new promClient.Gauge({ // eslint-disable-line no-new
531
+ new promClient.Gauge({
532
+ // eslint-disable-line no-new
517
533
  name: 'blind_peer_bytes_allocated',
518
534
  help: 'The amount of bytes allocated by the hyperdb (as reported in its digest)',
519
- collect () {
535
+ collect() {
520
536
  this.set(self.digest.bytesAllocated)
521
537
  }
522
538
  })
523
539
 
524
- new promClient.Gauge({ // eslint-disable-line no-new
540
+ new promClient.Gauge({
541
+ // eslint-disable-line no-new
525
542
  name: 'blind_peer_cores',
526
543
  help: 'The amount of cores (as reported in its digest)',
527
- collect () {
544
+ collect() {
528
545
  this.set(self.digest.cores)
529
546
  }
530
547
  })
531
548
 
532
- new promClient.Gauge({ // eslint-disable-line no-new
549
+ new promClient.Gauge({
550
+ // eslint-disable-line no-new
533
551
  name: 'blind_peer_cores_added',
534
552
  help: 'The total amount of add-core RPC requests that have been processed',
535
- collect () {
553
+ collect() {
536
554
  this.set(self.stats.coresAdded)
537
555
  }
538
556
  })
539
557
 
540
- new promClient.Gauge({ // eslint-disable-line no-new
558
+ new promClient.Gauge({
559
+ // eslint-disable-line no-new
541
560
  name: 'blind_peer_bytes_gcd',
542
561
  help: 'The total amount of bytes garbage collected since the process started',
543
- collect () {
562
+ collect() {
544
563
  this.set(self.stats.bytesGcd)
545
564
  }
546
565
  })
547
566
 
548
- new promClient.Gauge({ // eslint-disable-line no-new
567
+ new promClient.Gauge({
568
+ // eslint-disable-line no-new
549
569
  name: 'blind_peer_core_activations',
550
570
  help: 'The total amount of hypercore activations since the process started',
551
- collect () {
571
+ collect() {
552
572
  this.set(self.stats.activations)
553
573
  }
554
574
  })
555
575
 
556
- new promClient.Gauge({ // eslint-disable-line no-new
576
+ new promClient.Gauge({
577
+ // eslint-disable-line no-new
557
578
  name: 'blind_peer_wakeups',
558
579
  help: 'The total amount of hypercore wakeups since the process started',
559
- collect () {
580
+ collect() {
560
581
  this.set(self.stats.wakeups)
561
582
  }
562
583
  })
563
584
 
564
- new promClient.Gauge({ // eslint-disable-line no-new
585
+ new promClient.Gauge({
586
+ // eslint-disable-line no-new
565
587
  name: 'blind_peer_db_flushes',
566
588
  help: 'The total amount of database flushes since the process started',
567
- collect () {
589
+ collect() {
568
590
  this.set(self.db.stats.flushes)
569
591
  }
570
592
  })
571
593
 
572
- new promClient.Gauge({ // eslint-disable-line no-new
594
+ new promClient.Gauge({
595
+ // eslint-disable-line no-new
573
596
  name: 'blind_peer_announced_cores',
574
597
  help: 'The amount of announced cores',
575
- collect () {
598
+ collect() {
576
599
  this.set(self.nrAnnouncedCores)
577
600
  }
578
601
  })
package/lib/db.js CHANGED
@@ -8,7 +8,7 @@ const { definition: spec } = require('blind-peer-encodings')
8
8
  const MAX_PRIO = 2
9
9
 
10
10
  module.exports = class BlindPeerDB extends ReadyResource {
11
- constructor (db, auth) {
11
+ constructor(db, auth) {
12
12
  super()
13
13
 
14
14
  this.db = HyperDB.rocks(db, spec)
@@ -29,19 +29,19 @@ module.exports = class BlindPeerDB extends ReadyResource {
29
29
  this.ready().catch(noop)
30
30
  }
31
31
 
32
- find (col, q) {
32
+ find(col, q) {
33
33
  return this.db.find(col, q)
34
34
  }
35
35
 
36
- get (col, q) {
36
+ get(col, q) {
37
37
  return this.db.get(col, q)
38
38
  }
39
39
 
40
- getCoreRecord (key) {
40
+ getCoreRecord(key) {
41
41
  return this.get('@blind-peer/cores', { key })
42
42
  }
43
43
 
44
- async _open () {
44
+ async _open() {
45
45
  await this.db.ready()
46
46
 
47
47
  const auth = await this.db.get('@blind-peer/auth')
@@ -63,7 +63,8 @@ module.exports = class BlindPeerDB extends ReadyResource {
63
63
  await this.db.flush()
64
64
  }
65
65
 
66
- async flush () { // The caller is responsible for ensuring this runs in a lock
66
+ async flush() {
67
+ // The caller is responsible for ensuring this runs in a lock
67
68
  if (!this.opened) await this.ready()
68
69
 
69
70
  const coresAdding = this.coresAdding
@@ -96,9 +97,7 @@ module.exports = class BlindPeerDB extends ReadyResource {
96
97
  if (existing) {
97
98
  if (!info.announce && (info.priority || 0) <= existing.priority) continue // would be a downgrade, which we never want
98
99
 
99
- existing.priority = Math.min(
100
- Math.max(info.priority || 0, existing.priority)
101
- )
100
+ existing.priority = Math.min(Math.max(info.priority || 0, existing.priority))
102
101
  existing.announce = info.announce || existing.announce
103
102
  existing.updated = time
104
103
  existing.active = time
@@ -128,7 +127,7 @@ module.exports = class BlindPeerDB extends ReadyResource {
128
127
 
129
128
  const updated = c.length !== core.length
130
129
 
131
- bytesAllocated += (core.bytesAllocated - c.bytesAllocated)
130
+ bytesAllocated += core.bytesAllocated - c.bytesAllocated
132
131
 
133
132
  c.length = core.length
134
133
  c.bytesAllocated = core.bytesAllocated
@@ -153,38 +152,41 @@ module.exports = class BlindPeerDB extends ReadyResource {
153
152
  await tx.flush()
154
153
  }
155
154
 
156
- async hasCore (key) {
155
+ async hasCore(key) {
157
156
  key = IdEnc.decode(key)
158
- return await this.db.get('@blind-peer/cores', { key }) !== null
157
+ return (await this.db.get('@blind-peer/cores', { key })) !== null
159
158
  }
160
159
 
161
- addCore (info) {
160
+ addCore(info) {
162
161
  this.coresAdding.push(info)
163
162
  }
164
163
 
165
- deleteCore (key) {
164
+ deleteCore(key) {
166
165
  this.coresDeleting.push(key)
167
166
  }
168
167
 
169
- updateCore (core, id) { // TODO: id is technically optional
168
+ updateCore(core, id) {
169
+ // TODO: id is technically optional
170
170
  this.coresUpdated.set(id, core)
171
171
  }
172
172
 
173
- updated () {
174
- return this.coresAdding.length > 0 || this.coresUpdated.size > 0 || this.coresDeleting.length > 0
173
+ updated() {
174
+ return (
175
+ this.coresAdding.length > 0 || this.coresUpdated.size > 0 || this.coresDeleting.length > 0
176
+ )
175
177
  }
176
178
 
177
- createGcCandidateReadStream () {
179
+ createGcCandidateReadStream() {
178
180
  return this.db.find('@blind-peer/cores-by-activity')
179
181
  }
180
182
 
181
- createAnnouncingCoresStream () {
183
+ createAnnouncingCoresStream() {
182
184
  return this.db.find('@blind-peer/cores-by-announce')
183
185
  }
184
186
 
185
- async _close () {
187
+ async _close() {
186
188
  await this.db.close()
187
189
  }
188
190
  }
189
191
 
190
- function noop () {}
192
+ function noop() {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blind-peer",
3
- "version": "2.8.1",
3
+ "version": "2.8.3",
4
4
  "description": "Blind peers help keep hypercores available",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -33,12 +33,13 @@
33
33
  "tiny-byte-size": "^1.1.0"
34
34
  },
35
35
  "devDependencies": {
36
- "blind-peering": "^1.12.0",
36
+ "blind-peering": "^1.13.0",
37
37
  "brittle": "^3.7.0",
38
38
  "debounceify": "^1.1.0",
39
39
  "hyperdht": "^6.20.1",
40
+ "prettier": "^3.6.2",
41
+ "prettier-config-holepunch": "^2.0.0",
40
42
  "prom-client": "^15.1.3",
41
- "standard": "^17.1.2",
42
43
  "test-tmp": "^1.3.0"
43
44
  },
44
45
  "files": [
@@ -47,7 +48,9 @@
47
48
  "lib/"
48
49
  ],
49
50
  "scripts": {
50
- "test": "standard && brittle test/*.js"
51
+ "format": "prettier --write .",
52
+ "test": "prettier --check . && brittle test/*.js",
53
+ "test:bare": "bare test/basic.js"
51
54
  },
52
55
  "repository": {
53
56
  "type": "git",