blind-peer 3.1.0 → 3.4.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/index.js +196 -3
- package/package.json +6 -5
package/index.js
CHANGED
|
@@ -5,6 +5,7 @@ const ReadyResource = require('ready-resource')
|
|
|
5
5
|
const Hyperswarm = require('hyperswarm')
|
|
6
6
|
const ProtomuxRPC = require('protomux-rpc')
|
|
7
7
|
const c = require('compact-encoding')
|
|
8
|
+
const BlindPeerMuxer = require('blind-peer-muxer')
|
|
8
9
|
const b4a = require('b4a')
|
|
9
10
|
const crypto = require('hypercore-crypto')
|
|
10
11
|
const safetyCatch = require('safety-catch')
|
|
@@ -14,8 +15,10 @@ const IdEnc = require('hypercore-id-encoding')
|
|
|
14
15
|
|
|
15
16
|
const BlindPeerDB = require('./lib/db.js')
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
// Enable Small wants in Hypercore. Must be before anywhere that uses Hypercore
|
|
19
|
+
Hypercore.enable(Hypercore.SMALL_WANTS)
|
|
20
|
+
|
|
21
|
+
const { AddCoreEncoding, DeleteCoreEncoding } = require('blind-peer-encodings')
|
|
19
22
|
|
|
20
23
|
class CoreTracker {
|
|
21
24
|
constructor(blindPeer, core) {
|
|
@@ -228,7 +231,10 @@ class BlindPeer extends ReadyResource {
|
|
|
228
231
|
bytesGcd: 0,
|
|
229
232
|
coresAdded: 0,
|
|
230
233
|
activations: 0,
|
|
231
|
-
wakeups: 0
|
|
234
|
+
wakeups: 0,
|
|
235
|
+
addCoresRx: 0,
|
|
236
|
+
muxerPaired: 0,
|
|
237
|
+
muxerErrors: 0
|
|
232
238
|
}
|
|
233
239
|
}
|
|
234
240
|
|
|
@@ -426,6 +432,23 @@ class BlindPeer extends ReadyResource {
|
|
|
426
432
|
|
|
427
433
|
rpc.respond('add-core', AddCoreEncoding, this._onaddcore.bind(this, conn))
|
|
428
434
|
rpc.respond('delete-core', DeleteCoreEncoding, this._ondeletecore.bind(this, conn))
|
|
435
|
+
|
|
436
|
+
const self = this
|
|
437
|
+
BlindPeerMuxer.pair(conn, function () {
|
|
438
|
+
self.emit('muxer-paired', conn)
|
|
439
|
+
self.stats.muxerPaired++
|
|
440
|
+
new BlindPeerMuxer(conn, {
|
|
441
|
+
async oncores(request) {
|
|
442
|
+
try {
|
|
443
|
+
await self._onaddcores(conn, request)
|
|
444
|
+
} catch (e) {
|
|
445
|
+
self.stats.muxerErrors++
|
|
446
|
+
self.emit('muxer-error', e, conn)
|
|
447
|
+
throw e
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
})
|
|
451
|
+
})
|
|
429
452
|
}
|
|
430
453
|
|
|
431
454
|
async _activateCore(stream, record) {
|
|
@@ -497,6 +520,7 @@ class BlindPeer extends ReadyResource {
|
|
|
497
520
|
const replicationLag = core.length - core.contiguousLength
|
|
498
521
|
if (replicationLag > this.replicationLagThreshold || core.length === 0) {
|
|
499
522
|
activeSession = this.swarm.join(core.discoveryKey, { server: true, client: true })
|
|
523
|
+
this.emit('core-client-mode-changed', core, true)
|
|
500
524
|
} else {
|
|
501
525
|
activeSession = this.swarm.join(core.discoveryKey, { server: true, client: false })
|
|
502
526
|
}
|
|
@@ -549,6 +573,100 @@ class BlindPeer extends ReadyResource {
|
|
|
549
573
|
return coreRecord
|
|
550
574
|
}
|
|
551
575
|
|
|
576
|
+
async _onaddcores(stream, request) {
|
|
577
|
+
this.stats.addCoresRx++
|
|
578
|
+
const priority = Math.min(request.priority, 1) // 2 is reserved for trusted peers
|
|
579
|
+
const { cores, referrer } = request
|
|
580
|
+
|
|
581
|
+
if (request.announce !== false && !this._isTrustedPeer(stream.remotePublicKey)) {
|
|
582
|
+
// Note: we can't use the original downgrade-announce event because that assumes a 'record' object
|
|
583
|
+
this.emit('add-cores-downgrade-announce', {
|
|
584
|
+
request,
|
|
585
|
+
remotePublicKey: stream.remotePublicKey
|
|
586
|
+
})
|
|
587
|
+
request.announce = false
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
this.emit('add-cores-received', stream, request)
|
|
591
|
+
|
|
592
|
+
const discKeys = []
|
|
593
|
+
const overview = new Map()
|
|
594
|
+
for (const c of cores) {
|
|
595
|
+
const discoveryKey = crypto.discoveryKey(c.key)
|
|
596
|
+
discKeys.push(discoveryKey)
|
|
597
|
+
const id = IdEnc.normalize(discoveryKey)
|
|
598
|
+
overview.set(id, {
|
|
599
|
+
key: c.key,
|
|
600
|
+
discoveryKey,
|
|
601
|
+
remoteLength: c.length,
|
|
602
|
+
announce: request.announce,
|
|
603
|
+
priority,
|
|
604
|
+
referrer,
|
|
605
|
+
ownLength: 0, // set later
|
|
606
|
+
ownContigLength: 0, // set later
|
|
607
|
+
needsActivation: false // changed later if needed
|
|
608
|
+
})
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
const recordsToAdd = []
|
|
612
|
+
const infos = await this.store.storage.getInfos(discKeys)
|
|
613
|
+
for (let i = 0; i < infos.length; i++) {
|
|
614
|
+
const id = IdEnc.normalize(discKeys[i])
|
|
615
|
+
const storageInfo = infos[i]
|
|
616
|
+
const entry = overview.get(id)
|
|
617
|
+
|
|
618
|
+
// Note: just the null check does not suffice for storageInfo, because we already try
|
|
619
|
+
// loading some keys from other contexts, like when the system core of an autobase is
|
|
620
|
+
// used as a referrer.
|
|
621
|
+
if (
|
|
622
|
+
storageInfo === null ||
|
|
623
|
+
entry.announce ||
|
|
624
|
+
(storageInfo.head === null && entry.remoteLength > 0)
|
|
625
|
+
) {
|
|
626
|
+
entry.needsActivation = true
|
|
627
|
+
recordsToAdd.push({
|
|
628
|
+
key: entry.key,
|
|
629
|
+
priority: entry.priority,
|
|
630
|
+
announce: entry.announce,
|
|
631
|
+
referrer: entry.referrer
|
|
632
|
+
})
|
|
633
|
+
} else {
|
|
634
|
+
entry.ownLength = storageInfo.head?.length || 0
|
|
635
|
+
entry.ownContigLength = storageInfo.hints?.contiguousLength || 0
|
|
636
|
+
if (entry.ownLength !== entry.remoteLength) entry.needsActivation = true
|
|
637
|
+
if (entry.ownLength > entry.ownContigLength) entry.needsActivation = true
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
// Note: not race condition safe when called with the same cores at a similar time,
|
|
642
|
+
// but it's no problem if we do add the same core twice
|
|
643
|
+
for (const record of recordsToAdd) this.db.addCore(record)
|
|
644
|
+
if (recordsToAdd.length > 0) await this.flush() // flush now as important data
|
|
645
|
+
|
|
646
|
+
if (referrer) {
|
|
647
|
+
const muxer = stream.userData
|
|
648
|
+
const core = this.store.get({ key: referrer })
|
|
649
|
+
await core.ready()
|
|
650
|
+
const discoveryKey = core.discoveryKey
|
|
651
|
+
await core.close()
|
|
652
|
+
await this._onwakeup(discoveryKey, muxer)
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
for (const r of recordsToAdd) this.emit('add-new-core', r, true, stream)
|
|
656
|
+
|
|
657
|
+
const activateProms = []
|
|
658
|
+
for (const entry of overview.values()) {
|
|
659
|
+
if (!entry.needsActivation) continue
|
|
660
|
+
this.stats.coresAdded++
|
|
661
|
+
this.emit('add-core', entry, true, stream)
|
|
662
|
+
activateProms.push(this._activateCore(stream, entry))
|
|
663
|
+
}
|
|
664
|
+
await Promise.all(activateProms)
|
|
665
|
+
|
|
666
|
+
this.emit('add-cores-done', stream, request)
|
|
667
|
+
return null
|
|
668
|
+
}
|
|
669
|
+
|
|
552
670
|
async _ondeletecore(stream, { key }) {
|
|
553
671
|
if (!this._isTrustedPeer(stream.remotePublicKey)) {
|
|
554
672
|
this.emit('delete-blocked', stream, { key })
|
|
@@ -679,6 +797,81 @@ class BlindPeer extends ReadyResource {
|
|
|
679
797
|
this.set(self.nrAnnouncedCores)
|
|
680
798
|
}
|
|
681
799
|
})
|
|
800
|
+
|
|
801
|
+
new promClient.Gauge({
|
|
802
|
+
// eslint-disable-line no-new
|
|
803
|
+
name: 'blind_peer_muxer_errors',
|
|
804
|
+
help: 'The amount of errors on the protomux muxer',
|
|
805
|
+
collect() {
|
|
806
|
+
this.set(self.stats.muxerErrors)
|
|
807
|
+
}
|
|
808
|
+
})
|
|
809
|
+
new promClient.Gauge({
|
|
810
|
+
// eslint-disable-line no-new
|
|
811
|
+
name: 'blind_peer_muxer_paired',
|
|
812
|
+
help: 'The amount of blind-peer-muxer sessions paired',
|
|
813
|
+
collect() {
|
|
814
|
+
this.set(self.stats.muxerPaired)
|
|
815
|
+
}
|
|
816
|
+
})
|
|
817
|
+
new promClient.Gauge({
|
|
818
|
+
// eslint-disable-line no-new
|
|
819
|
+
name: 'blind_peer_add_cores_rx',
|
|
820
|
+
help: 'The amount of add-cores requests received',
|
|
821
|
+
collect() {
|
|
822
|
+
this.set(self.stats.addCoresRx)
|
|
823
|
+
}
|
|
824
|
+
})
|
|
825
|
+
if (self.rocks.stats) {
|
|
826
|
+
new promClient.Gauge({
|
|
827
|
+
// eslint-disable-line no-new
|
|
828
|
+
name: 'blind_peer_rocks_gets',
|
|
829
|
+
help: 'The amount of get ops from RocksDB',
|
|
830
|
+
collect() {
|
|
831
|
+
this.set(self.rocks.stats.gets)
|
|
832
|
+
}
|
|
833
|
+
})
|
|
834
|
+
new promClient.Gauge({
|
|
835
|
+
// eslint-disable-line no-new
|
|
836
|
+
name: 'blind_peer_rocks_puts',
|
|
837
|
+
help: 'The amount of put ops to RocksDB',
|
|
838
|
+
collect() {
|
|
839
|
+
this.set(self.rocks.stats.puts)
|
|
840
|
+
}
|
|
841
|
+
})
|
|
842
|
+
new promClient.Gauge({
|
|
843
|
+
// eslint-disable-line no-new
|
|
844
|
+
name: 'blind_peer_rocks_deletes',
|
|
845
|
+
help: 'The amount of delete ops from RocksDB',
|
|
846
|
+
collect() {
|
|
847
|
+
this.set(self.rocks.stats.deletes)
|
|
848
|
+
}
|
|
849
|
+
})
|
|
850
|
+
new promClient.Gauge({
|
|
851
|
+
// eslint-disable-line no-new
|
|
852
|
+
name: 'blind_peer_rocks_range_deletes',
|
|
853
|
+
help: 'The amount of range delete ops from RocksDB',
|
|
854
|
+
collect() {
|
|
855
|
+
this.set(self.rocks.stats.rangeDeletes)
|
|
856
|
+
}
|
|
857
|
+
})
|
|
858
|
+
new promClient.Gauge({
|
|
859
|
+
// eslint-disable-line no-new
|
|
860
|
+
name: 'blind_peer_rocks_read_batches',
|
|
861
|
+
help: 'The amount of read batches from RocksDB',
|
|
862
|
+
collect() {
|
|
863
|
+
this.set(self.rocks.stats.readBatches)
|
|
864
|
+
}
|
|
865
|
+
})
|
|
866
|
+
new promClient.Gauge({
|
|
867
|
+
// eslint-disable-line no-new
|
|
868
|
+
name: 'blind_peer_rocks_write_batches',
|
|
869
|
+
help: 'The amount of write batches to RocksDB',
|
|
870
|
+
collect() {
|
|
871
|
+
this.set(self.rocks.stats.writeBatches)
|
|
872
|
+
}
|
|
873
|
+
})
|
|
874
|
+
}
|
|
682
875
|
}
|
|
683
876
|
}
|
|
684
877
|
|
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blind-peer",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "Blind peers help keep hypercores available",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"autobase": "^7.0.18",
|
|
8
8
|
"b4a": "^1.6.7",
|
|
9
|
-
"blind-peer-encodings": "^3.1.
|
|
9
|
+
"blind-peer-encodings": "^3.1.1",
|
|
10
|
+
"blind-peer-muxer": "^1.0.0",
|
|
10
11
|
"compact-encoding": "^2.16.0",
|
|
11
12
|
"corestore": "^7.4.4",
|
|
12
|
-
"hypercore": "^11.0
|
|
13
|
+
"hypercore": "^11.26.0",
|
|
13
14
|
"hypercore-crypto": "^3.5.0",
|
|
14
15
|
"hypercore-id-encoding": "^1.3.0",
|
|
15
16
|
"hyperdb": "^5.0.0",
|
|
@@ -26,13 +27,13 @@
|
|
|
26
27
|
"devDependencies": {
|
|
27
28
|
"bare-events": "^2.8.2",
|
|
28
29
|
"bare-process": "^4.2.2",
|
|
29
|
-
"
|
|
30
|
+
"bare-prom-client": "^15.1.3",
|
|
31
|
+
"blind-peering": "^2.0.0",
|
|
30
32
|
"brittle": "^3.7.0",
|
|
31
33
|
"debounceify": "^1.1.0",
|
|
32
34
|
"hyperdht": "^6.20.1",
|
|
33
35
|
"prettier": "^3.6.2",
|
|
34
36
|
"prettier-config-holepunch": "^2.0.0",
|
|
35
|
-
"bare-prom-client": "^15.1.3",
|
|
36
37
|
"test-tmp": "^1.3.0",
|
|
37
38
|
"which-runtime": "^1.3.2"
|
|
38
39
|
},
|