blind-peer 2.9.5 → 3.0.1

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 (4) hide show
  1. package/README.md +7 -38
  2. package/package.json +4 -20
  3. package/bare-bin.js +0 -3
  4. package/bin.js +0 -334
package/README.md CHANGED
@@ -4,54 +4,23 @@ Blind peers help keep hypercores available.
4
4
 
5
5
  For the client side responsible for requesting cores be kept by Blind Peers, see [blind-peering](https://github.com/holepunchto/blind-peering).
6
6
 
7
- ## Installation
7
+ To run the server as a CLI, see [blind-peer-cli](https://github.com/holepunchto/blind-peer-cli).
8
8
 
9
- Install globally to use the `blind-peer` command:
9
+ ## Installation
10
10
 
11
11
  ```
12
- npm install -g blind-peer
12
+ npm install blind-peer
13
13
  ```
14
14
 
15
15
  ## Usage
16
16
 
17
- Run a blind peer:
18
-
19
- ```
20
- blind-peer
21
- ```
22
-
23
- ### Command Line Options
24
-
25
- - `--storage|-s [path]` - Storage path, defaults to ./blind-peer
26
- - `--port|-p [int]` - DHT Port to try to bind to. Only relevant when that port is not firewalled. (defaults to a random port)
27
- - `--trusted-peer|-t [trusted-peer]` - Public key of a trusted peer (allowed to set announce: true). Can be specified multiple times.
28
- - `--debug|-d` - Enable debug mode (more logs). Can be specified multiple times.
29
- - `--max-storage|-m [int]` - Max storage usage, in Mb (defaults to 100000)
30
- - `--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.
31
- - `--autodiscovery-seed [autodiscovery-seed]` - 64-byte seed used to authenticate to the autodiscovery service. Can be hex or z32.
32
- - `--autodiscovery-service-name [autodiscovery-service-name]` - Name under which to register the service (default blind-peer)
33
- - `--scraper-public-key [scraper-public-key]` - Public key of a dht-prometheus scraper. Can be hex or z32.
34
- - `--scraper-secret [scraper-secret]` - Secret of the dht-prometheus scraper. Can be hex or z32.
35
- - `--scraper-alias [scraper-alias]` - (optional) Alias with which to register to the scraper
36
-
37
- ### Output
38
-
39
- When started, ndjson (pino) will be emitted for events. An example startup will look like:
40
-
41
- ```jsonl
42
- {"level":30,"time":1751662694931,"pid":96069,"hostname":"L293","msg":"Starting blind peer"}
43
- {"level":30,"time":1751662694932,"pid":96069,"hostname":"L293","msg":"Using storage 'blind-peer'"}
44
- {"level":30,"time":1751662696936,"pid":96069,"hostname":"L293","msg":"Blind peer listening, local address is 10.0.0.214:49741"}
45
- {"level":30,"time":1751662696936,"pid":96069,"hostname":"L293","msg":"Bytes allocated: 0B of 100GB"}
46
- {"level":30,"time":1751662696936,"pid":96069,"hostname":"L293","msg":"Listening at es4n7ty45odd1udfqyi9xz58mrbheuhdnxgdufsn9gz6e5uhsqco"}
47
- {"level":30,"time":1751662696936,"pid":96069,"hostname":"L293","msg":"Encryption public key is ur7d9r7s3zf1ryibixt5139bep67y94s5bg4gckzo1p6qgtwwfyy"}
48
- ```
17
+ to run a blind-peer server, use [blind-peer-cli](https://github.com/holepunchto/blind-peer-cli).
49
18
 
50
19
  ### Using a Blind Peer
51
20
 
52
- To use a blind peer, use [blind-peering](https://github.com/holepunchto/blind-peering)
21
+ To talk to a blind peer, use [blind-peering](https://github.com/holepunchto/blind-peering)
53
22
 
54
- Here is an example, using the key from above
23
+ Here is an example:
55
24
 
56
25
  ```js
57
26
  import BlindPeering from 'blind-peering'
@@ -63,7 +32,7 @@ const store = new Corestore(Pear.config.storage)
63
32
  const swarm = new Hyperswarm()
64
33
  const wakeup = new Wakeup()
65
34
 
66
- const DEFAULT_BLIND_PEER_KEYS = ['es4n7ty45odd1udfqyi9xz58mrbheuhdnxgdufsn9gz6e5uhsqco']
35
+ const DEFAULT_BLIND_PEER_KEYS = ['es4n7ty45odd1udfqyi9xz58mrbheuhdnxgdufsn9gz6e5uhsqco'] // replace with your own key
67
36
  const blind = new BlindPeering(swarm, store, { wakeup, mirrors: DEFAULT_BLIND_PEER_KEYS })
68
37
 
69
38
  // Add your autobase
package/package.json CHANGED
@@ -1,38 +1,27 @@
1
1
  {
2
2
  "name": "blind-peer",
3
- "version": "2.9.5",
3
+ "version": "3.0.1",
4
4
  "description": "Blind peers help keep hypercores available",
5
5
  "main": "index.js",
6
- "bin": {
7
- "blind-peer": "bin.js",
8
- "blind-peer-bare": "bare-bin.js"
9
- },
10
6
  "dependencies": {
11
7
  "autobase": "^7.0.18",
12
- "autobase-discovery": "^1.0.0",
13
8
  "b4a": "^1.6.7",
14
9
  "blind-peer-encodings": "^3.1.0",
15
10
  "compact-encoding": "^2.16.0",
16
11
  "corestore": "^7.4.4",
17
- "graceful-goodbye": "^1.3.3",
18
- "hyper-instrument": "^3.0.0",
19
12
  "hypercore": "^11.0.12",
20
13
  "hypercore-crypto": "^3.5.0",
21
14
  "hypercore-id-encoding": "^1.3.0",
22
- "hyperdb": "^4.9.4",
15
+ "hyperdb": "^5.0.0",
23
16
  "hyperschema": "^1.10.3",
24
17
  "hyperswarm": "^4.13.1",
25
- "paparam": "^1.8.0",
26
- "pino": "^9.6.0",
27
- "pino-bare": "^0.0.1",
28
18
  "protomux-rpc": "^1.7.1",
29
19
  "protomux-wakeup": "^2.9.0",
30
20
  "ready-resource": "^1.1.2",
31
21
  "repl-swarm": "^2.3.0",
32
22
  "rocksdb-native": "^3.1.6",
33
23
  "safety-catch": "^1.0.2",
34
- "scope-lock": "^1.2.4",
35
- "tiny-byte-size": "^1.1.0"
24
+ "scope-lock": "^1.2.4"
36
25
  },
37
26
  "devDependencies": {
38
27
  "bare-events": "^2.8.2",
@@ -43,12 +32,11 @@
43
32
  "hyperdht": "^6.20.1",
44
33
  "prettier": "^3.6.2",
45
34
  "prettier-config-holepunch": "^2.0.0",
46
- "prom-client": "^15.1.3",
35
+ "bare-prom-client": "^15.1.3",
47
36
  "test-tmp": "^1.3.0",
48
37
  "which-runtime": "^1.3.2"
49
38
  },
50
39
  "files": [
51
- "bin.js",
52
40
  "index.js",
53
41
  "lib/"
54
42
  ],
@@ -69,10 +57,6 @@
69
57
  },
70
58
  "homepage": "https://github.com/holepunchto/blind-peer",
71
59
  "imports": {
72
- "pino": {
73
- "bare": "pino-bare",
74
- "default": "pino"
75
- },
76
60
  "events": {
77
61
  "bare": "bare-events",
78
62
  "default": "events"
package/bare-bin.js DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env bare
2
-
3
- require('./bin')
package/bin.js DELETED
@@ -1,334 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const { command, flag } = require('paparam')
4
- const goodbye = require('graceful-goodbye')
5
- const idEnc = require('hypercore-id-encoding')
6
- const Instrumentation = require('hyper-instrument')
7
- const RegisterClient = require('autobase-discovery/client/register')
8
- const safetyCatch = require('safety-catch')
9
- const byteSize = require('tiny-byte-size')
10
- const pino = require('pino')
11
- const b4a = require('b4a')
12
- const hypCrypto = require('hypercore-crypto')
13
- const { version: ownVersion } = require('./package.json')
14
-
15
- const BlindPeer = require('.')
16
-
17
- const SERVICE_NAME = 'blind-peer'
18
- const DEFAULT_STORAGE_LIMIT_MB = 100_000
19
-
20
- const cmd = command(
21
- 'blind-peer',
22
- flag('--storage|-s [path]', 'Storage path, defaults to ./blind-peer'),
23
- flag(
24
- '--port|-p [int]',
25
- 'DHT Port to try to bind to. Only relevant when that port is not firewalled. (defaults to a random port)'
26
- ),
27
- flag(
28
- '--trusted-peer|-t [trusted-peer]',
29
- 'Public key of a trusted peer (allowed to set announce: true). Can be more than 1.'
30
- ).multiple(),
31
- flag('--debug|-d', 'Enable debug mode (more logs)'),
32
- flag(
33
- `--max-storage|-m [int]', 'Max storage usage, in Mb (defaults to ${DEFAULT_STORAGE_LIMIT_MB})`
34
- ),
35
- flag(
36
- '--autodiscovery-rpc-key [autodiscovery-rpc-key]',
37
- 'Public key where the autodiscovery service is listening. When set, the autodiscovery-seed must also be set. Can be hex or z32.'
38
- ),
39
- flag(
40
- '--autodiscovery-seed [autodiscovery-seed]',
41
- '64-byte seed used to authenticate to the autodiscovery service. Can be hex or z32.'
42
- ),
43
- flag(
44
- '--autodiscovery-service-name [autodiscovery-service-name]',
45
- `Name under which to register the service (default ${SERVICE_NAME})`
46
- ),
47
- flag(
48
- '--scraper-public-key [scraper-public-key]',
49
- 'Public key of a dht-prometheus scraper. Can be hex or z32.'
50
- ),
51
- flag(
52
- '--scraper-secret [scraper-secret]',
53
- 'Secret of the dht-prometheus scraper. Can be hex or z32.'
54
- ),
55
- flag('--scraper-alias [scraper-alias]', '(optional) Alias with which to register to the scraper'),
56
- flag(
57
- '--log-streams',
58
- '(Temporary, Advanced): enable debug logs on the UDX streams managed by the dht'
59
- ),
60
- flag(
61
- '--repl [repl]',
62
- 'Expose a repl-swarm at the passed-in seed (32 bytes in hex or z32 notation). Use for debugging only.'
63
- ),
64
- flag(
65
- '--auto-shutdown-minutes [auto-shutdown-minutes]',
66
- '(Temporary, Advanced) Automatically shut the process down after X minutes, with a variation of 20%'
67
- ),
68
- async function ({ flags }) {
69
- const debug = flags.debug
70
- const logger = pino({
71
- level: debug ? 'debug' : 'info',
72
- name: 'blind-peer'
73
- })
74
- logger.info('Starting blind peer')
75
-
76
- const logStreams = flags.logStreams
77
-
78
- const storage = flags.storage || 'blind-peer'
79
- const port = flags.port ? parseInt(flags.port) : null
80
-
81
- const maxBytes = 1_000_000 * parseInt(flags.maxStorage || DEFAULT_STORAGE_LIMIT_MB)
82
- const trustedPubKeys = (flags.trustedPeer || []).map((k) => idEnc.decode(k))
83
-
84
- const blindPeer = new BlindPeer(storage, { trustedPubKeys, maxBytes, port })
85
-
86
- blindPeer.on('flush-error', (e) => {
87
- logger.warn(`Error while flushing the db: ${e.stack}`)
88
- })
89
-
90
- blindPeer.on('add-new-core', (record, _, stream) => {
91
- try {
92
- if (record.announce) {
93
- logger.info(
94
- `add-core request received from peer ${streamToStr(stream)} for record ${recordToStr(record)}`
95
- )
96
- } else {
97
- logger.debug(
98
- `add-core request received from peer ${streamToStr(stream)} for record ${recordToStr(record)}`
99
- )
100
- }
101
- } catch (e) {
102
- logger.info(`Invalid add-core request received: ${e.stack}`)
103
- logger.info(record)
104
- }
105
- })
106
- blindPeer.on('delete-blocked', (stream, { key }) => {
107
- logger.info(
108
- `Blocked delete-core request from untrusted peer ${streamToStr(stream)} for core ${idEnc.normalize(key)}`
109
- )
110
- })
111
- blindPeer.on('delete-core', (stream, { key, existing }) => {
112
- logger.info(
113
- `Received delete-core request from trusted peer ${streamToStr(stream)} for core ${idEnc.normalize(key)}. Existing: ${existing}`
114
- )
115
- })
116
- blindPeer.on('delete-core-end', (stream, { key, announced }) => {
117
- logger.info(
118
- `Completed delete-core request from trusted peer ${streamToStr(stream)} for core ${idEnc.normalize(key)}. Was announced: ${announced}`
119
- )
120
- })
121
-
122
- blindPeer.on('downgrade-announce', ({ record, remotePublicKey }) => {
123
- try {
124
- logger.info(
125
- `Downgraded announce for peer ${idEnc.normalize(remotePublicKey)} because the peer is not trusted (Original: ${recordToStr(record)})`
126
- )
127
- } catch (e) {
128
- logger.error(`Unexpected error while logging downgrade-announce: ${e.stack}`)
129
- }
130
- })
131
-
132
- blindPeer.on('announce-core', (core) => {
133
- logger.info(`Started announcing core ${coreToInfo(core, true)}`)
134
- })
135
- blindPeer.on('announced-initial-cores', () => {
136
- logger.info(`Announced all initial cores`)
137
- })
138
- blindPeer.on('core-downloaded', (core) => {
139
- logger.info(`Announced core fully downloaded: ${coreToInfo(core, true)}`)
140
- })
141
- blindPeer.on('core-append', (core) => {
142
- logger.info(`Detected announced-core length update: ${coreToInfo(core, true)}`)
143
- })
144
-
145
- blindPeer.on('gc-start', ({ bytesToClear }) => {
146
- logger.info(
147
- `Starting GC, trying to clear ${byteSize(bytesToClear)} (bytes allocated: ${byteSize(blindPeer.digest.bytesAllocated)} of ${byteSize(blindPeer.maxBytes)})`
148
- )
149
- })
150
- blindPeer.on('gc-done', ({ bytesCleared }) => {
151
- logger.info(
152
- `Completed GC, cleared ${byteSize(bytesCleared)} bytes (bytes allocated: ${byteSize(blindPeer.digest.bytesAllocated)} of ${byteSize(blindPeer.maxBytes)})`
153
- )
154
- })
155
- if (debug) {
156
- blindPeer.on('core-activity', (core) => {
157
- logger.debug(`Core activity for ${coreToInfo(core)}`)
158
- })
159
- }
160
-
161
- blindPeer.on('invalid-request', (core, err, req, from) => {
162
- const address = `${from.stream?.rawStream?.remoteHost}:${from.stream?.rawStream?.remotePort}`
163
- const remotePubKey = idEnc.normalize(from.stream.remotePublicKey)
164
- const key = idEnc.normalize(core.key)
165
- logger.warn(
166
- `Received invalid request for core ${key} from peer ${remotePubKey} at ${address} (${err.stack})`
167
- )
168
- })
169
-
170
- logger.info(`Using storage '${storage}'`)
171
- if (trustedPubKeys.length > 0) {
172
- logger.info(
173
- `Trusted public keys:\n -${[...blindPeer.trustedPubKeys].map(idEnc.normalize).join('\n -')}`
174
- )
175
- }
176
-
177
- let instrumentation = null
178
- goodbye(async () => {
179
- if (instrumentation) {
180
- logger.info('Closing instrumentation')
181
- await instrumentation.close()
182
- }
183
- logger.info('Shutting down blind peer')
184
- await blindPeer.close()
185
- logger.info('Shut down blind peer')
186
- })
187
-
188
- if (flags.repl) {
189
- const seed = idEnc.decode(flags.repl)
190
- logger.warn('Setting up REPL swarm, enabling remote access to this process')
191
- const replSwarm = require('repl-swarm')
192
- replSwarm({ seed, logSeed: false, blindPeer, instrumentation })
193
- }
194
-
195
- await blindPeer.ready() // needed to be able to access the swarm object
196
- blindPeer.swarm.on('ban', (peerInfo, err) => {
197
- logger.warn(`Banned peer: ${b4a.toString(peerInfo.publicKey, 'hex')}.\n${err.stack}`)
198
- })
199
- if (debug) {
200
- blindPeer.swarm.on('connection', (conn, peerInfo) => {
201
- const key = idEnc.normalize(peerInfo.publicKey)
202
- logger.debug(`Opened connection to ${key}`)
203
- conn.on('close', () => logger.debug(`Closed connection to ${key}`))
204
- conn.on('error', (err) => {
205
- if (err.code === 'ECONNRESET') {
206
- logger.debug(`Connection error with ${key}: ${err.stack}`)
207
- return
208
- }
209
- logger.info(`Connection error with ${key}: ${err.stack}`)
210
- })
211
- })
212
- }
213
-
214
- if (logStreams) {
215
- logger.warn('Advanced debugging option log-streams enabled')
216
- setInterval(() => {
217
- try {
218
- let nrBigStreams = 0
219
- for (const stream of blindPeer.swarm.dht.rawStreams) {
220
- const pendingWrites = stream._wreqs.length - stream._wfree.length
221
- if (pendingWrites >= 100) {
222
- nrBigStreams++
223
- logger.warn(
224
- `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'}`
225
- )
226
- }
227
- }
228
- if (nrBigStreams > 0) {
229
- logger.warn(`Total streams with many pending writes: ${nrBigStreams}`)
230
- }
231
- } catch (e) {
232
- // we don't want to crash the process with our debugging
233
- logger.warn(`logStreams errored unexpectedly: ${e.stack}`)
234
- }
235
- }, 30_000)
236
- }
237
-
238
- await blindPeer.listen()
239
-
240
- logger.info(
241
- `Blind peer listening, local address is ${blindPeer.swarm.dht.localAddress().host}:${blindPeer.swarm.dht.localAddress().port}`
242
- )
243
- logger.info(
244
- `Bytes allocated: ${byteSize(blindPeer.digest.bytesAllocated)} of ${byteSize(blindPeer.maxBytes)}`
245
- )
246
-
247
- if (flags.autodiscoveryRpcKey) {
248
- const autodiscoveryRpcKey = idEnc.decode(flags.autodiscoveryRpcKey)
249
- const seed = idEnc.decode(flags.autodiscoverySeed)
250
- const serviceName = flags.autodiscoveryServiceName || SERVICE_NAME
251
- const registerClient = new RegisterClient(autodiscoveryRpcKey, blindPeer.swarm.dht, seed)
252
-
253
- // No need to block on this, so we run it in the background
254
- logger.info(
255
- `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)})`
256
- )
257
- registerClient
258
- .putService(blindPeer.publicKey, serviceName)
259
- .then(() => {
260
- logger.info('Successfully requested to be added to the autodiscovery service')
261
- })
262
- .catch((e) => {
263
- logger.warn(`Failed to register to the autodiscovery service: ${e.stack}`)
264
- })
265
- .finally(() => {
266
- registerClient.close().catch(safetyCatch)
267
- })
268
- }
269
-
270
- if (flags.scraperPublicKey) {
271
- const swarm = blindPeer.swarm
272
- logger.info('Setting up instrumentation')
273
-
274
- const scraperPublicKey = idEnc.decode(flags.scraperPublicKey)
275
- const scraperSecret = idEnc.decode(flags.scraperSecret)
276
-
277
- let prometheusAlias = flags.scraperAlias
278
- if (prometheusAlias && prometheusAlias.length > 99) {
279
- throw new Error('The Prometheus alias must have length less than 100')
280
- }
281
- if (!prometheusAlias) {
282
- prometheusAlias = `blind-peer-${idEnc.normalize(swarm.keyPair.publicKey)}`.slice(0, 99)
283
- }
284
-
285
- instrumentation = new Instrumentation({
286
- swarm,
287
- corestore: blindPeer.store,
288
- scraperPublicKey,
289
- prometheusAlias,
290
- scraperSecret,
291
- prometheusServiceName: SERVICE_NAME,
292
- version: ownVersion
293
- })
294
-
295
- blindPeer.registerMetrics(instrumentation.promClient)
296
- instrumentation.registerLogger(logger)
297
- await instrumentation.ready()
298
- }
299
-
300
- logger.info(`Listening at ${idEnc.normalize(blindPeer.publicKey)}`)
301
- logger.info(`Encryption public key is ${idEnc.normalize(blindPeer.encryptionPublicKey)}`)
302
-
303
- if (flags.autoShutdownMinutes) {
304
- const delay = flags.autoShutdownMinutes * (1 + Math.random() / 5)
305
- logger.warn(`Automatically shutting down the process in ${delay} minutes`)
306
- setTimeout(
307
- () => {
308
- logger.warn('Auto-shutdown triggered. Shutting down...')
309
- goodbye.exit()
310
- },
311
- delay * 60 * 1000
312
- )
313
- }
314
- }
315
- )
316
-
317
- function recordToStr(record) {
318
- const discKey = hypCrypto.discoveryKey(record.key)
319
- return `DB Record for discovery key ${idEnc.normalize(discKey)} with priority: ${record.priority}. Announcing? ${record.announce}`
320
- }
321
-
322
- function streamToStr(stream) {
323
- const pubKey = idEnc.normalize(stream.remotePublicKey)
324
- return `${pubKey}`
325
- }
326
-
327
- function coreToInfo(core, includePublicKey = false) {
328
- const discKey = hypCrypto.discoveryKey(core.key)
329
- let res = `Discovery key ${idEnc.normalize(discKey)} (${core.contiguousLength} / ${core.length}, ${core.peers.length} peers)`
330
- if (includePublicKey) res += `. Public key: ${idEnc.normalize(core.key)}`
331
- return res
332
- }
333
-
334
- cmd.parse()