hypercore 10.38.2 → 11.0.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/README.md +13 -30
- package/index.js +388 -444
- package/lib/audit.js +33 -41
- package/lib/bit-interlude.js +174 -0
- package/lib/bitfield.js +79 -87
- package/lib/block-store.js +12 -50
- package/lib/copy-prologue.js +236 -0
- package/lib/core.js +413 -746
- package/lib/download.js +42 -4
- package/lib/merkle-tree.js +263 -406
- package/lib/multisig.js +9 -6
- package/lib/mutex.js +4 -0
- package/lib/remote-bitfield.js +9 -9
- package/lib/replicator.js +247 -177
- package/lib/session-state.js +949 -0
- package/lib/verifier.js +20 -13
- package/package.json +2 -2
- package/lib/batch.js +0 -431
- package/lib/big-header.js +0 -55
- package/lib/oplog.js +0 -228
package/lib/replicator.js
CHANGED
|
@@ -51,6 +51,7 @@ const PRIORITY = {
|
|
|
51
51
|
class Attachable {
|
|
52
52
|
constructor () {
|
|
53
53
|
this.resolved = false
|
|
54
|
+
this.processing = false
|
|
54
55
|
this.refs = []
|
|
55
56
|
}
|
|
56
57
|
|
|
@@ -101,7 +102,12 @@ class Attachable {
|
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
gc () {
|
|
104
|
-
if (this.refs.length === 0) this._unref()
|
|
105
|
+
if (this.refs.length === 0 && !this.processing) this._unref()
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
processed () {
|
|
109
|
+
this.processing = false
|
|
110
|
+
this.gc()
|
|
105
111
|
}
|
|
106
112
|
|
|
107
113
|
_cancel (r, err) {
|
|
@@ -333,8 +339,28 @@ class RoundtripQueue {
|
|
|
333
339
|
}
|
|
334
340
|
}
|
|
335
341
|
|
|
342
|
+
class ProofRequest {
|
|
343
|
+
constructor (msg, proof, block, manifest) {
|
|
344
|
+
this.msg = msg
|
|
345
|
+
this.proof = proof
|
|
346
|
+
this.block = block
|
|
347
|
+
this.manifest = manifest
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
async fulfill () {
|
|
351
|
+
if (this.proof === null) return null
|
|
352
|
+
|
|
353
|
+
const proof = await this.proof.settle()
|
|
354
|
+
|
|
355
|
+
if (this.manifest) proof.manifest = this.manifest
|
|
356
|
+
if (this.block) proof.block.value = await this.block
|
|
357
|
+
|
|
358
|
+
return proof
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
336
362
|
class Peer {
|
|
337
|
-
constructor (replicator, protomux, channel,
|
|
363
|
+
constructor (replicator, protomux, channel, inflightRange) {
|
|
338
364
|
this.core = replicator.core
|
|
339
365
|
this.replicator = replicator
|
|
340
366
|
this.stream = protomux.stream
|
|
@@ -346,8 +372,6 @@ class Peer {
|
|
|
346
372
|
this.paused = false
|
|
347
373
|
this.removed = false
|
|
348
374
|
|
|
349
|
-
this.useSession = useSession
|
|
350
|
-
|
|
351
375
|
this.channel = channel
|
|
352
376
|
this.channel.userData = this
|
|
353
377
|
|
|
@@ -418,6 +442,7 @@ class Peer {
|
|
|
418
442
|
this.lastExtensionRecv = ''
|
|
419
443
|
|
|
420
444
|
replicator._ifAvailable++
|
|
445
|
+
replicator._active++
|
|
421
446
|
}
|
|
422
447
|
|
|
423
448
|
get remoteContiguousLength () {
|
|
@@ -490,16 +515,16 @@ class Peer {
|
|
|
490
515
|
return
|
|
491
516
|
}
|
|
492
517
|
|
|
493
|
-
if (this.core.
|
|
518
|
+
if (this.core.state.fork !== this.remoteFork) {
|
|
494
519
|
this.canUpgrade = false
|
|
495
520
|
}
|
|
496
521
|
|
|
497
522
|
this.needsSync = false
|
|
498
523
|
|
|
499
524
|
this.wireSync.send({
|
|
500
|
-
fork: this.core.
|
|
501
|
-
length: this.core.
|
|
502
|
-
remoteLength: this.core.
|
|
525
|
+
fork: this.core.state.fork,
|
|
526
|
+
length: this.core.state.length,
|
|
527
|
+
remoteLength: this.core.state.fork === this.remoteFork ? this.remoteLength : 0,
|
|
503
528
|
canUpgrade: this.canUpgrade,
|
|
504
529
|
uploading: true,
|
|
505
530
|
downloading: this.replicator.isDownloading(),
|
|
@@ -509,7 +534,7 @@ class Peer {
|
|
|
509
534
|
}
|
|
510
535
|
|
|
511
536
|
onopen ({ seeks, capability }) {
|
|
512
|
-
const expected = caps.replicate(this.stream.isInitiator === false, this.
|
|
537
|
+
const expected = caps.replicate(this.stream.isInitiator === false, this.core.key, this.stream.handshakeHash)
|
|
513
538
|
|
|
514
539
|
if (b4a.equals(capability, expected) !== true) { // TODO: change this to a rejection instead, less leakage
|
|
515
540
|
throw INVALID_CAPABILITY('Remote sent an invalid replication capability')
|
|
@@ -523,11 +548,11 @@ class Peer {
|
|
|
523
548
|
|
|
524
549
|
this.sendSync()
|
|
525
550
|
|
|
526
|
-
const contig = Math.min(this.core.
|
|
551
|
+
const contig = Math.min(this.core.state.length, this.core.header.hints.contiguousLength)
|
|
527
552
|
if (contig > 0) {
|
|
528
553
|
this.broadcastRange(0, contig, false)
|
|
529
554
|
|
|
530
|
-
if (contig === this.core.
|
|
555
|
+
if (contig === this.core.state.length) {
|
|
531
556
|
this.broadcastedNonSparse = true
|
|
532
557
|
}
|
|
533
558
|
}
|
|
@@ -536,6 +561,8 @@ class Peer {
|
|
|
536
561
|
this.replicator._addPeer(this)
|
|
537
562
|
|
|
538
563
|
this.protomux.uncork()
|
|
564
|
+
|
|
565
|
+
this.core.checkIfIdle()
|
|
539
566
|
}
|
|
540
567
|
|
|
541
568
|
onclose (isRemote) {
|
|
@@ -546,10 +573,6 @@ class Peer {
|
|
|
546
573
|
this.remoteUploading === true && this.replicator.downloading === true
|
|
547
574
|
|
|
548
575
|
if (this.remoteOpened === false) {
|
|
549
|
-
if (this.useSession) {
|
|
550
|
-
this.replicator._peerSessions--
|
|
551
|
-
this.replicator._closeSessionMaybe()
|
|
552
|
-
}
|
|
553
576
|
this.replicator._ifAvailable--
|
|
554
577
|
this.replicator.updateAll()
|
|
555
578
|
return
|
|
@@ -567,12 +590,7 @@ class Peer {
|
|
|
567
590
|
this.replicator._removePeer(this)
|
|
568
591
|
|
|
569
592
|
if (reopen) {
|
|
570
|
-
this.replicator._makePeer(this.protomux
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
if (this.useSession) {
|
|
574
|
-
this.replicator._peerSessions--
|
|
575
|
-
this.replicator._closeSessionMaybe()
|
|
593
|
+
this.replicator._makePeer(this.protomux)
|
|
576
594
|
}
|
|
577
595
|
}
|
|
578
596
|
|
|
@@ -588,7 +606,7 @@ class Peer {
|
|
|
588
606
|
|
|
589
607
|
async onsync ({ fork, length, remoteLength, canUpgrade, uploading, downloading, hasManifest }) {
|
|
590
608
|
const lengthChanged = length !== this.remoteLength
|
|
591
|
-
const sameFork = fork === this.core.
|
|
609
|
+
const sameFork = fork === this.core.state.fork
|
|
592
610
|
|
|
593
611
|
this.remoteSynced = true
|
|
594
612
|
this.remoteFork = fork
|
|
@@ -605,7 +623,7 @@ class Peer {
|
|
|
605
623
|
|
|
606
624
|
this.replicator._updateFork(this)
|
|
607
625
|
|
|
608
|
-
if (this.remoteLength > this.core.
|
|
626
|
+
if (this.remoteLength > this.core.state.length && this.lengthAcked === this.core.state.length) {
|
|
609
627
|
if (this.replicator._addUpgradeMaybe() !== null) this._update()
|
|
610
628
|
}
|
|
611
629
|
|
|
@@ -613,13 +631,13 @@ class Peer {
|
|
|
613
631
|
? this.canUpgrade && sameFork
|
|
614
632
|
: await this._canUpgrade(length, fork)
|
|
615
633
|
|
|
616
|
-
if (length === this.remoteLength && fork === this.core.
|
|
634
|
+
if (length === this.remoteLength && fork === this.core.state.fork) {
|
|
617
635
|
this.canUpgrade = upgrade
|
|
618
636
|
}
|
|
619
637
|
|
|
620
638
|
if (--this.syncsProcessing !== 0) return // ie not latest
|
|
621
639
|
|
|
622
|
-
if (this.needsSync === true || (this.core.
|
|
640
|
+
if (this.needsSync === true || (this.core.state.fork === this.remoteFork && this.core.state.length > this.remoteLength)) {
|
|
623
641
|
this.signalUpgrade()
|
|
624
642
|
}
|
|
625
643
|
|
|
@@ -627,18 +645,18 @@ class Peer {
|
|
|
627
645
|
}
|
|
628
646
|
|
|
629
647
|
_shouldUpdateCanUpgrade () {
|
|
630
|
-
return this.core.
|
|
631
|
-
this.core.
|
|
648
|
+
return this.core.state.fork === this.remoteFork &&
|
|
649
|
+
this.core.state.length > this.remoteLength &&
|
|
632
650
|
this.canUpgrade === false &&
|
|
633
651
|
this.syncsProcessing === 0
|
|
634
652
|
}
|
|
635
653
|
|
|
636
654
|
async _updateCanUpgradeAndSync () {
|
|
637
|
-
const { length, fork } = this.core.
|
|
655
|
+
const { length, fork } = this.core.state
|
|
638
656
|
|
|
639
657
|
const canUpgrade = await this._canUpgrade(this.remoteLength, this.remoteFork)
|
|
640
658
|
|
|
641
|
-
if (this.syncsProcessing > 0 || length !== this.core.
|
|
659
|
+
if (this.syncsProcessing > 0 || length !== this.core.state.length || fork !== this.core.state.fork) {
|
|
642
660
|
return
|
|
643
661
|
}
|
|
644
662
|
if (canUpgrade === this.canUpgrade) {
|
|
@@ -651,16 +669,16 @@ class Peer {
|
|
|
651
669
|
|
|
652
670
|
// Safe to call in the background - never fails
|
|
653
671
|
async _canUpgrade (remoteLength, remoteFork) {
|
|
654
|
-
if (remoteFork !== this.core.
|
|
672
|
+
if (remoteFork !== this.core.state.fork) return false
|
|
655
673
|
|
|
656
674
|
if (remoteLength === 0) return true
|
|
657
|
-
if (remoteLength >= this.core.
|
|
675
|
+
if (remoteLength >= this.core.state.length) return false
|
|
658
676
|
|
|
659
677
|
try {
|
|
660
678
|
// Rely on caching to make sure this is cheap...
|
|
661
679
|
const canUpgrade = await this.core.tree.upgradeable(remoteLength)
|
|
662
680
|
|
|
663
|
-
if (remoteFork !== this.core.
|
|
681
|
+
if (remoteFork !== this.core.state.fork) return false
|
|
664
682
|
|
|
665
683
|
return canUpgrade
|
|
666
684
|
} catch {
|
|
@@ -668,24 +686,24 @@ class Peer {
|
|
|
668
686
|
}
|
|
669
687
|
}
|
|
670
688
|
|
|
671
|
-
async _getProof (msg) {
|
|
672
|
-
|
|
689
|
+
async _getProof (batch, msg) {
|
|
690
|
+
let block = null
|
|
673
691
|
|
|
674
|
-
if (
|
|
692
|
+
if (msg.block) {
|
|
675
693
|
const index = msg.block.index
|
|
676
694
|
|
|
677
|
-
if (msg.fork !== this.core.
|
|
678
|
-
return null
|
|
695
|
+
if (msg.fork !== this.core.state.fork || !this.core.bitfield.get(index)) {
|
|
696
|
+
return new ProofRequest(msg, null, null, null)
|
|
679
697
|
}
|
|
680
698
|
|
|
681
|
-
|
|
699
|
+
block = this.core.blocks.get(batch, index)
|
|
682
700
|
}
|
|
683
701
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
702
|
+
const manifest = (msg.manifest && !this.core.compat) ? this.core.header.manifest : null
|
|
703
|
+
const treeBatch = this.core.state.createTreeBatch()
|
|
704
|
+
const proof = await this.core.tree.proof(batch, treeBatch, msg)
|
|
687
705
|
|
|
688
|
-
return proof
|
|
706
|
+
return new ProofRequest(msg, proof, block, manifest)
|
|
689
707
|
}
|
|
690
708
|
|
|
691
709
|
async onrequest (msg) {
|
|
@@ -703,6 +721,8 @@ class Peer {
|
|
|
703
721
|
return
|
|
704
722
|
}
|
|
705
723
|
|
|
724
|
+
if (this.replicator.destroyed) return
|
|
725
|
+
|
|
706
726
|
await this._handleRequest(msg)
|
|
707
727
|
}
|
|
708
728
|
|
|
@@ -720,7 +740,7 @@ class Peer {
|
|
|
720
740
|
}
|
|
721
741
|
|
|
722
742
|
async _handleRequests () {
|
|
723
|
-
if (this.receiverBusy) return
|
|
743
|
+
if (this.receiverBusy || this.replicator.destroyed) return
|
|
724
744
|
this.receiverBusy = true
|
|
725
745
|
this.protomux.cork()
|
|
726
746
|
|
|
@@ -734,45 +754,48 @@ class Peer {
|
|
|
734
754
|
}
|
|
735
755
|
|
|
736
756
|
async _handleRequest (msg) {
|
|
737
|
-
|
|
757
|
+
const batch = this.core.storage.read()
|
|
738
758
|
|
|
739
759
|
// TODO: could still be answerable if (index, fork) is an ancestor of the current fork
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
760
|
+
const req = msg.fork === this.core.state.fork
|
|
761
|
+
? await this._getProof(batch, msg)
|
|
762
|
+
: new ProofRequest(msg, null, null, null)
|
|
763
|
+
|
|
764
|
+
batch.tryFlush()
|
|
765
|
+
|
|
766
|
+
await this._fulfillRequest(req)
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
async _fulfillRequest (req) {
|
|
770
|
+
const proof = await req.fulfill()
|
|
748
771
|
|
|
749
772
|
// if cancelled do not reply
|
|
750
|
-
if (this.remoteRequests.get(msg.id) !== msg) {
|
|
773
|
+
if (this.remoteRequests.get(req.msg.id) !== req.msg) {
|
|
751
774
|
return
|
|
752
775
|
}
|
|
753
776
|
|
|
754
777
|
// sync from now on, so safe to delete from the map
|
|
755
|
-
this.remoteRequests.delete(msg.id)
|
|
778
|
+
this.remoteRequests.delete(req.msg.id)
|
|
756
779
|
|
|
757
780
|
if (proof === null) {
|
|
758
|
-
if (msg.manifest && this.core.header.manifest) {
|
|
781
|
+
if (req.msg.manifest && this.core.header.manifest) {
|
|
759
782
|
const manifest = this.core.header.manifest
|
|
760
|
-
this.wireData.send({ request: msg.id, fork: this.core.
|
|
783
|
+
this.wireData.send({ request: req.msg.id, fork: this.core.state.fork, block: null, hash: null, seek: null, upgrade: null, manifest })
|
|
761
784
|
incrementTx(this.stats.wireData, this.replicator.stats.wireData)
|
|
762
785
|
return
|
|
763
786
|
}
|
|
764
787
|
|
|
765
|
-
this.wireNoData.send({ request: msg.id })
|
|
788
|
+
this.wireNoData.send({ request: req.msg.id })
|
|
766
789
|
return
|
|
767
790
|
}
|
|
768
791
|
|
|
769
792
|
if (proof.block !== null) {
|
|
770
|
-
this.replicator.
|
|
793
|
+
this.replicator._onupload(proof.block.index, proof.block.value.byteLength, this)
|
|
771
794
|
}
|
|
772
795
|
|
|
773
796
|
this.wireData.send({
|
|
774
|
-
request: msg.id,
|
|
775
|
-
fork: msg.fork,
|
|
797
|
+
request: req.msg.id,
|
|
798
|
+
fork: req.msg.fork,
|
|
776
799
|
block: proof.block,
|
|
777
800
|
hash: proof.hash,
|
|
778
801
|
seek: proof.seek,
|
|
@@ -803,7 +826,7 @@ class Peer {
|
|
|
803
826
|
_checkIfConflict () {
|
|
804
827
|
this.paused = true
|
|
805
828
|
|
|
806
|
-
const length = Math.min(this.core.
|
|
829
|
+
const length = Math.min(this.core.state.length, this.remoteLength)
|
|
807
830
|
if (length === 0) return // pause and ignore
|
|
808
831
|
|
|
809
832
|
this.wireRequest.send({
|
|
@@ -829,7 +852,7 @@ class Peer {
|
|
|
829
852
|
}
|
|
830
853
|
|
|
831
854
|
const req = data.request > 0 ? this.replicator._inflight.get(data.request) : null
|
|
832
|
-
const reorg = data.fork > this.core.
|
|
855
|
+
const reorg = data.fork > this.core.state.fork
|
|
833
856
|
|
|
834
857
|
// no push atm, TODO: check if this satisfies another pending request
|
|
835
858
|
// allow reorg pushes tho as those are not written to storage so we'll take all the help we can get
|
|
@@ -847,11 +870,12 @@ class Peer {
|
|
|
847
870
|
if (isBlockRequest(req)) this.replicator._unmarkInflight(req.block.index)
|
|
848
871
|
|
|
849
872
|
this.paused = true
|
|
850
|
-
this.replicator.
|
|
873
|
+
this.replicator._oninvalid(err, req, data, this)
|
|
851
874
|
return
|
|
852
875
|
}
|
|
853
876
|
|
|
854
877
|
this.dataProcessing++
|
|
878
|
+
if (isBlockRequest(req)) this.replicator._markProcessing(req.block.index)
|
|
855
879
|
|
|
856
880
|
try {
|
|
857
881
|
if (!matchingRequest(req, data) || !(await this.core.verify(data, this))) {
|
|
@@ -877,9 +901,10 @@ class Peer {
|
|
|
877
901
|
}
|
|
878
902
|
|
|
879
903
|
this.replicator._onnodata(this, req)
|
|
880
|
-
this.replicator.
|
|
904
|
+
this.replicator._oninvalid(err, req, data, this)
|
|
881
905
|
return
|
|
882
906
|
} finally {
|
|
907
|
+
if (isBlockRequest(req)) this.replicator._markProcessed(req.block.index)
|
|
883
908
|
this.dataProcessing--
|
|
884
909
|
}
|
|
885
910
|
|
|
@@ -936,11 +961,10 @@ class Peer {
|
|
|
936
961
|
return
|
|
937
962
|
}
|
|
938
963
|
|
|
939
|
-
const contig = Math.min(this.core.
|
|
964
|
+
const contig = Math.min(this.core.state.length, this.core.header.hints.contiguousLength)
|
|
940
965
|
|
|
941
966
|
if (start + length < contig) {
|
|
942
|
-
|
|
943
|
-
this.missingBlocks.setRange(start, delta, false)
|
|
967
|
+
this.missingBlocks.setRange(start, contig, false)
|
|
944
968
|
return
|
|
945
969
|
}
|
|
946
970
|
|
|
@@ -950,7 +974,7 @@ class Peer {
|
|
|
950
974
|
length += rem
|
|
951
975
|
}
|
|
952
976
|
|
|
953
|
-
const end = start + Math.min(length, this.core.
|
|
977
|
+
const end = start + Math.min(length, this.core.state.length)
|
|
954
978
|
while (start < end) {
|
|
955
979
|
const local = bitfield.getBitfield(start)
|
|
956
980
|
|
|
@@ -1009,12 +1033,12 @@ class Peer {
|
|
|
1009
1033
|
this.missingBlocks.set(start, has && !bitfield.get(start))
|
|
1010
1034
|
} else {
|
|
1011
1035
|
const rangeStart = this.remoteBitfield.findFirst(!has, start)
|
|
1012
|
-
const
|
|
1036
|
+
const rangeEnd = length + start
|
|
1013
1037
|
|
|
1014
|
-
if (
|
|
1015
|
-
this.remoteBitfield.setRange(rangeStart,
|
|
1016
|
-
this.missingBlocks.setRange(rangeStart,
|
|
1017
|
-
if (has) this._clearLocalRange(rangeStart,
|
|
1038
|
+
if (rangeStart !== -1 && rangeStart < rangeEnd) {
|
|
1039
|
+
this.remoteBitfield.setRange(rangeStart, rangeEnd, has)
|
|
1040
|
+
this.missingBlocks.setRange(rangeStart, rangeEnd, has)
|
|
1041
|
+
if (has) this._clearLocalRange(rangeStart, rangeEnd - rangeStart)
|
|
1018
1042
|
}
|
|
1019
1043
|
}
|
|
1020
1044
|
|
|
@@ -1033,16 +1057,16 @@ class Peer {
|
|
|
1033
1057
|
|
|
1034
1058
|
async _onconflict () {
|
|
1035
1059
|
this.protomux.cork()
|
|
1036
|
-
if (this.remoteLength > 0 && this.core.
|
|
1060
|
+
if (this.remoteLength > 0 && this.core.state.fork === this.remoteFork) {
|
|
1037
1061
|
await this.onrequest({
|
|
1038
1062
|
id: 0,
|
|
1039
|
-
fork: this.core.
|
|
1063
|
+
fork: this.core.state.fork,
|
|
1040
1064
|
block: null,
|
|
1041
1065
|
hash: null,
|
|
1042
1066
|
seek: null,
|
|
1043
1067
|
upgrade: {
|
|
1044
1068
|
start: 0,
|
|
1045
|
-
length: Math.min(this.core.
|
|
1069
|
+
length: Math.min(this.core.state.length, this.remoteLength)
|
|
1046
1070
|
}
|
|
1047
1071
|
})
|
|
1048
1072
|
}
|
|
@@ -1074,7 +1098,7 @@ class Peer {
|
|
|
1074
1098
|
seek: null,
|
|
1075
1099
|
upgrade: needsUpgrade === false
|
|
1076
1100
|
? null
|
|
1077
|
-
: { start: this.core.
|
|
1101
|
+
: { start: this.core.state.length, length: this.remoteLength - this.core.state.length },
|
|
1078
1102
|
// remote manifest check can be removed eventually...
|
|
1079
1103
|
manifest: this.core.header.manifest === null && this.remoteHasManifest === true,
|
|
1080
1104
|
priority
|
|
@@ -1099,7 +1123,7 @@ class Peer {
|
|
|
1099
1123
|
// if replicator is updating the seeks etc, bail and wait for it to drain
|
|
1100
1124
|
if (this.replicator._updatesPending > 0) return false
|
|
1101
1125
|
|
|
1102
|
-
const { length, fork } = this.core.
|
|
1126
|
+
const { length, fork } = this.core.state
|
|
1103
1127
|
|
|
1104
1128
|
if (fork !== this.remoteFork) return false
|
|
1105
1129
|
|
|
@@ -1156,7 +1180,7 @@ class Peer {
|
|
|
1156
1180
|
}
|
|
1157
1181
|
|
|
1158
1182
|
_hasTreeParent (index) {
|
|
1159
|
-
if (this.remoteLength >= this.core.
|
|
1183
|
+
if (this.remoteLength >= this.core.state.length) return true
|
|
1160
1184
|
|
|
1161
1185
|
const ite = flatTree.iterator(index * 2)
|
|
1162
1186
|
|
|
@@ -1170,7 +1194,7 @@ class Peer {
|
|
|
1170
1194
|
length = left + span
|
|
1171
1195
|
|
|
1172
1196
|
// if larger than local AND larger than remote - they share the root so its ok
|
|
1173
|
-
if (length > this.core.
|
|
1197
|
+
if (length > this.core.state.length) {
|
|
1174
1198
|
if (length > this.remoteLength) return true
|
|
1175
1199
|
break
|
|
1176
1200
|
}
|
|
@@ -1201,7 +1225,7 @@ class Peer {
|
|
|
1201
1225
|
}
|
|
1202
1226
|
|
|
1203
1227
|
_requestBlock (b) {
|
|
1204
|
-
const { length, fork } = this.core.
|
|
1228
|
+
const { length, fork } = this.core.state
|
|
1205
1229
|
|
|
1206
1230
|
if (this._remoteHasBlock(b.index) === false || fork !== this.remoteFork) {
|
|
1207
1231
|
this._maybeWant(b.index)
|
|
@@ -1257,7 +1281,7 @@ class Peer {
|
|
|
1257
1281
|
}
|
|
1258
1282
|
|
|
1259
1283
|
_requestRange (r) {
|
|
1260
|
-
const { length, fork } = this.core.
|
|
1284
|
+
const { length, fork } = this.core.state
|
|
1261
1285
|
|
|
1262
1286
|
if (r.blocks) {
|
|
1263
1287
|
let min = -1
|
|
@@ -1275,7 +1299,7 @@ class Peer {
|
|
|
1275
1299
|
return false
|
|
1276
1300
|
}
|
|
1277
1301
|
|
|
1278
|
-
const end = Math.min(this.core.
|
|
1302
|
+
const end = Math.min(this.core.state.length, Math.min(r.end === -1 ? this.remoteLength : r.end, this.remoteLength))
|
|
1279
1303
|
if (end <= r.start || fork !== this.remoteFork) return false
|
|
1280
1304
|
|
|
1281
1305
|
const len = end - r.start
|
|
@@ -1368,7 +1392,7 @@ class Peer {
|
|
|
1368
1392
|
}
|
|
1369
1393
|
|
|
1370
1394
|
async _send (req) {
|
|
1371
|
-
const fork = this.core.
|
|
1395
|
+
const fork = this.core.state.fork
|
|
1372
1396
|
|
|
1373
1397
|
this.inflight++
|
|
1374
1398
|
this.replicator._inflight.add(req)
|
|
@@ -1380,11 +1404,11 @@ class Peer {
|
|
|
1380
1404
|
|
|
1381
1405
|
try {
|
|
1382
1406
|
if (req.block !== null && req.fork === fork) {
|
|
1383
|
-
req.block.nodes = await this.core.tree.missingNodes(2 * req.block.index)
|
|
1407
|
+
req.block.nodes = await this.core.tree.missingNodes(2 * req.block.index, this.core.state.length)
|
|
1384
1408
|
if (req.priority === PRIORITY.CANCELLED) return
|
|
1385
1409
|
}
|
|
1386
1410
|
if (req.hash !== null && req.fork === fork && req.hash.nodes === 0) {
|
|
1387
|
-
req.hash.nodes = await this.core.tree.missingNodes(req.hash.index)
|
|
1411
|
+
req.hash.nodes = await this.core.tree.missingNodes(req.hash.index, this.core.state.length)
|
|
1388
1412
|
if (req.priority === PRIORITY.CANCELLED) return
|
|
1389
1413
|
|
|
1390
1414
|
// nodes === 0, we already have it, bail
|
|
@@ -1407,23 +1431,15 @@ class Peer {
|
|
|
1407
1431
|
module.exports = class Replicator {
|
|
1408
1432
|
static Peer = Peer // hack to be able to access Peer from outside this module
|
|
1409
1433
|
|
|
1410
|
-
constructor (core,
|
|
1434
|
+
constructor (core, {
|
|
1411
1435
|
notDownloadingLinger = NOT_DOWNLOADING_SLACK,
|
|
1412
1436
|
eagerUpgrade = true,
|
|
1413
1437
|
allowFork = true,
|
|
1414
|
-
inflightRange = null
|
|
1415
|
-
onpeerupdate = noop,
|
|
1416
|
-
onupload = noop,
|
|
1417
|
-
oninvalid = noop
|
|
1438
|
+
inflightRange = null
|
|
1418
1439
|
} = {}) {
|
|
1419
|
-
this.key = key
|
|
1420
|
-
this.discoveryKey = core.crypto.discoveryKey(key)
|
|
1421
1440
|
this.core = core
|
|
1422
1441
|
this.eagerUpgrade = eagerUpgrade
|
|
1423
1442
|
this.allowFork = allowFork
|
|
1424
|
-
this.onpeerupdate = onpeerupdate
|
|
1425
|
-
this.onupload = onupload
|
|
1426
|
-
this.oninvalid = oninvalid
|
|
1427
1443
|
this.ondownloading = null // optional external hook for monitoring downloading status
|
|
1428
1444
|
this.peers = []
|
|
1429
1445
|
this.findingPeers = 0 // updateable from the outside
|
|
@@ -1461,12 +1477,11 @@ module.exports = class Replicator {
|
|
|
1461
1477
|
this._ranges = []
|
|
1462
1478
|
|
|
1463
1479
|
this._hadPeers = false
|
|
1480
|
+
this._active = 0
|
|
1464
1481
|
this._ifAvailable = 0
|
|
1465
1482
|
this._updatesPending = 0
|
|
1466
1483
|
this._applyingReorg = null
|
|
1467
1484
|
this._manifestPeer = null
|
|
1468
|
-
this._hasSession = false
|
|
1469
|
-
this._peerSessions = 0
|
|
1470
1485
|
this._notDownloadingLinger = notDownloadingLinger
|
|
1471
1486
|
this._downloadingTimer = null
|
|
1472
1487
|
|
|
@@ -1510,7 +1525,7 @@ module.exports = class Replicator {
|
|
|
1510
1525
|
if (downloading) { // restart channel if needed...
|
|
1511
1526
|
for (const protomux of this._attached) {
|
|
1512
1527
|
if (!protomux.stream.handshakeHash) continue
|
|
1513
|
-
if (protomux.opened({ protocol: 'hypercore/alpha', id: this.discoveryKey })) continue
|
|
1528
|
+
if (protomux.opened({ protocol: 'hypercore/alpha', id: this.core.discoveryKey })) continue
|
|
1514
1529
|
this._makePeer(protomux, true)
|
|
1515
1530
|
}
|
|
1516
1531
|
} else {
|
|
@@ -1557,7 +1572,9 @@ module.exports = class Replicator {
|
|
|
1557
1572
|
for (const peer of this.peers) peer.signalUpgrade()
|
|
1558
1573
|
if (this._blocks.isEmpty() === false) this._resolveBlocksLocally()
|
|
1559
1574
|
if (this._upgrade !== null) this._resolveUpgradeRequest(null)
|
|
1560
|
-
if (this._ranges.length !== 0 || this._seeks.length !== 0)
|
|
1575
|
+
if (!this._blocks.isEmpty() || this._ranges.length !== 0 || this._seeks.length !== 0) {
|
|
1576
|
+
this._updateNonPrimary(true)
|
|
1577
|
+
}
|
|
1561
1578
|
}
|
|
1562
1579
|
|
|
1563
1580
|
// Called externally when a conflict has been detected and verified
|
|
@@ -1689,13 +1706,13 @@ module.exports = class Replicator {
|
|
|
1689
1706
|
|
|
1690
1707
|
if (peer.remoteSynced === false) return
|
|
1691
1708
|
|
|
1692
|
-
if (this.core.
|
|
1709
|
+
if (this.core.state.length === 0 && peer.remoteLength > 0) return
|
|
1693
1710
|
|
|
1694
1711
|
if (peer.remoteLength <= this._upgrade.length || peer.remoteFork !== this._upgrade.fork) continue
|
|
1695
1712
|
|
|
1696
1713
|
if (peer.syncsProcessing > 0) return
|
|
1697
1714
|
|
|
1698
|
-
if (peer.lengthAcked !== this.core.
|
|
1715
|
+
if (peer.lengthAcked !== this.core.state.length && peer.remoteFork === this.core.state.fork) return
|
|
1699
1716
|
if (peer.remoteCanUpgrade === true) return
|
|
1700
1717
|
}
|
|
1701
1718
|
|
|
@@ -1725,7 +1742,7 @@ module.exports = class Replicator {
|
|
|
1725
1742
|
if (this._upgrade !== null) return this._upgrade
|
|
1726
1743
|
|
|
1727
1744
|
// TODO: needs a reorg: true/false flag to indicate if the user requested a reorg
|
|
1728
|
-
this._upgrade = new UpgradeRequest(this, this.core.
|
|
1745
|
+
this._upgrade = new UpgradeRequest(this, this.core.state.fork, this.core.state.length)
|
|
1729
1746
|
|
|
1730
1747
|
return this._upgrade
|
|
1731
1748
|
}
|
|
@@ -1763,19 +1780,19 @@ module.exports = class Replicator {
|
|
|
1763
1780
|
_shouldUpgrade (peer) {
|
|
1764
1781
|
if (this._upgrade !== null && this._upgrade.inflight.length > 0) return false
|
|
1765
1782
|
return peer.remoteCanUpgrade === true &&
|
|
1766
|
-
peer.remoteLength > this.core.
|
|
1767
|
-
peer.lengthAcked === this.core.
|
|
1783
|
+
peer.remoteLength > this.core.state.length &&
|
|
1784
|
+
peer.lengthAcked === this.core.state.length
|
|
1768
1785
|
}
|
|
1769
1786
|
|
|
1770
1787
|
_autoUpgrade (peer) {
|
|
1771
|
-
return this._upgrade !== null && peer.remoteFork === this.core.
|
|
1788
|
+
return this._upgrade !== null && peer.remoteFork === this.core.state.fork && this._shouldUpgrade(peer)
|
|
1772
1789
|
}
|
|
1773
1790
|
|
|
1774
1791
|
_addPeer (peer) {
|
|
1775
1792
|
this._hadPeers = true
|
|
1776
1793
|
this.peers.push(peer)
|
|
1777
1794
|
this.updatePeer(peer)
|
|
1778
|
-
this.
|
|
1795
|
+
this._onpeerupdate(true, peer)
|
|
1779
1796
|
}
|
|
1780
1797
|
|
|
1781
1798
|
_requestDone (id, roundtrip) {
|
|
@@ -1795,9 +1812,7 @@ module.exports = class Replicator {
|
|
|
1795
1812
|
this._clearRequest(peer, req)
|
|
1796
1813
|
}
|
|
1797
1814
|
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
this.onpeerupdate(false, peer)
|
|
1815
|
+
this._onpeerupdate(false, peer)
|
|
1801
1816
|
this.updateAll()
|
|
1802
1817
|
}
|
|
1803
1818
|
|
|
@@ -1817,22 +1832,19 @@ module.exports = class Replicator {
|
|
|
1817
1832
|
async _resolveBlocksLocally () {
|
|
1818
1833
|
// TODO: check if fork compat etc. Requires that we pass down truncation info
|
|
1819
1834
|
|
|
1820
|
-
|
|
1835
|
+
const clear = []
|
|
1836
|
+
const blocks = []
|
|
1821
1837
|
|
|
1838
|
+
const reader = this.core.storage.read()
|
|
1822
1839
|
for (const b of this._blocks) {
|
|
1823
1840
|
if (this.core.bitfield.get(b.index) === false) continue
|
|
1824
|
-
|
|
1825
|
-
try {
|
|
1826
|
-
b.resolve(await this.core.blocks.get(b.index))
|
|
1827
|
-
} catch (err) {
|
|
1828
|
-
b.reject(err)
|
|
1829
|
-
}
|
|
1830
|
-
|
|
1831
|
-
if (clear === null) clear = []
|
|
1832
|
-
clear.push(b)
|
|
1841
|
+
blocks.push(this._resolveLocalBlock(b, reader, clear))
|
|
1833
1842
|
}
|
|
1843
|
+
reader.tryFlush()
|
|
1834
1844
|
|
|
1835
|
-
|
|
1845
|
+
await Promise.all(blocks)
|
|
1846
|
+
|
|
1847
|
+
if (!clear.length) return
|
|
1836
1848
|
|
|
1837
1849
|
// Currently the block tracker does not support deletes during iteration, so we make
|
|
1838
1850
|
// sure to clear them afterwards.
|
|
@@ -1842,6 +1854,17 @@ module.exports = class Replicator {
|
|
|
1842
1854
|
}
|
|
1843
1855
|
}
|
|
1844
1856
|
|
|
1857
|
+
async _resolveLocalBlock (b, reader, resolved) {
|
|
1858
|
+
try {
|
|
1859
|
+
b.resolve(await this.core.blocks.get(reader, b.index))
|
|
1860
|
+
} catch (err) {
|
|
1861
|
+
b.reject(err)
|
|
1862
|
+
return
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
resolved.push(b)
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1845
1868
|
_resolveBlockRequest (tracker, index, value, req) {
|
|
1846
1869
|
const b = tracker.remove(index)
|
|
1847
1870
|
if (b === null) return false
|
|
@@ -1865,7 +1888,7 @@ module.exports = class Replicator {
|
|
|
1865
1888
|
_resolveUpgradeRequest (req) {
|
|
1866
1889
|
if (req !== null) removeInflight(this._upgrade.inflight, req)
|
|
1867
1890
|
|
|
1868
|
-
if (this.core.
|
|
1891
|
+
if (this.core.state.length === this._upgrade.length && this.core.state.fork === this._upgrade.fork) return false
|
|
1869
1892
|
|
|
1870
1893
|
const u = this._upgrade
|
|
1871
1894
|
this._upgrade = null
|
|
@@ -2035,6 +2058,25 @@ module.exports = class Replicator {
|
|
|
2035
2058
|
}
|
|
2036
2059
|
}
|
|
2037
2060
|
|
|
2061
|
+
_markProcessing (index) {
|
|
2062
|
+
const b = this._blocks.get(index)
|
|
2063
|
+
if (b) {
|
|
2064
|
+
b.processing = true
|
|
2065
|
+
return
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
const h = this._hashes.get(index)
|
|
2069
|
+
if (h) h.processing = true
|
|
2070
|
+
}
|
|
2071
|
+
|
|
2072
|
+
_markProcessed (index) {
|
|
2073
|
+
const b = this._blocks.get(index)
|
|
2074
|
+
if (b) return b.processed()
|
|
2075
|
+
|
|
2076
|
+
const h = this._hashes.get(index)
|
|
2077
|
+
if (h) h.processed()
|
|
2078
|
+
}
|
|
2079
|
+
|
|
2038
2080
|
_markInflight (index) {
|
|
2039
2081
|
if (this.core.skipBitfield !== null) this.core.skipBitfield.set(index, true)
|
|
2040
2082
|
for (const peer of this.peers) peer._markInflight(index)
|
|
@@ -2048,6 +2090,7 @@ module.exports = class Replicator {
|
|
|
2048
2090
|
_ondata (peer, req, data) {
|
|
2049
2091
|
if (data.block !== null) {
|
|
2050
2092
|
this._resolveBlockRequest(this._blocks, data.block.index, data.block.value, req)
|
|
2093
|
+
this._ondownload(data.block.index, data.block.value.byteLength, peer)
|
|
2051
2094
|
}
|
|
2052
2095
|
|
|
2053
2096
|
if (data.hash !== null && (data.hash.index & 1) === 0) {
|
|
@@ -2075,9 +2118,9 @@ module.exports = class Replicator {
|
|
|
2075
2118
|
}
|
|
2076
2119
|
|
|
2077
2120
|
_onwant (peer, start, length) {
|
|
2078
|
-
const contig = Math.min(this.core.
|
|
2121
|
+
const contig = Math.min(this.core.state.length, this.core.header.hints.contiguousLength)
|
|
2079
2122
|
|
|
2080
|
-
if (start + length < contig || (this.core.
|
|
2123
|
+
if (start + length < contig || (this.core.state.length === contig)) {
|
|
2081
2124
|
peer.wireRange.send({
|
|
2082
2125
|
drop: false,
|
|
2083
2126
|
start: 0,
|
|
@@ -2087,7 +2130,7 @@ module.exports = class Replicator {
|
|
|
2087
2130
|
return
|
|
2088
2131
|
}
|
|
2089
2132
|
|
|
2090
|
-
length = Math.min(length, this.core.
|
|
2133
|
+
length = Math.min(length, this.core.state.length - start)
|
|
2091
2134
|
|
|
2092
2135
|
peer.protomux.cork()
|
|
2093
2136
|
|
|
@@ -2173,7 +2216,7 @@ module.exports = class Replicator {
|
|
|
2173
2216
|
}
|
|
2174
2217
|
|
|
2175
2218
|
_updateFork (peer) {
|
|
2176
|
-
if (this._applyingReorg !== null || this.allowFork === false || peer.remoteFork <= this.core.
|
|
2219
|
+
if (this._applyingReorg !== null || this.allowFork === false || peer.remoteFork <= this.core.state.fork) {
|
|
2177
2220
|
return false
|
|
2178
2221
|
}
|
|
2179
2222
|
|
|
@@ -2304,67 +2347,62 @@ module.exports = class Replicator {
|
|
|
2304
2347
|
this._maybeResolveIfAvailableRanges()
|
|
2305
2348
|
}
|
|
2306
2349
|
|
|
2307
|
-
|
|
2308
|
-
if (this.
|
|
2309
|
-
this._hasSession = false
|
|
2310
|
-
this.core.active--
|
|
2311
|
-
}
|
|
2312
|
-
|
|
2313
|
-
// we were the last active ref, so lets shut things down
|
|
2314
|
-
if (this.core.active === 0 && this.core.sessions.length === 0) {
|
|
2315
|
-
this.destroy()
|
|
2316
|
-
this.core.close().catch(safetyCatch)
|
|
2317
|
-
return
|
|
2318
|
-
}
|
|
2319
|
-
|
|
2320
|
-
// in case one session is still alive but its been marked for auto close also kill it
|
|
2321
|
-
if (this.core.sessions.length === 1 && this.core.active === 1 && this.core.sessions[0].autoClose) {
|
|
2322
|
-
this.core.sessions[0].close().catch(safetyCatch)
|
|
2323
|
-
}
|
|
2350
|
+
onpeerdestroy () {
|
|
2351
|
+
if (--this._active === 0) this.core.checkIfIdle()
|
|
2324
2352
|
}
|
|
2325
2353
|
|
|
2326
2354
|
attached (protomux) {
|
|
2327
2355
|
return this._attached.has(protomux)
|
|
2328
2356
|
}
|
|
2329
2357
|
|
|
2330
|
-
|
|
2331
|
-
if (this._hasSession) return
|
|
2332
|
-
this._hasSession = true
|
|
2333
|
-
this.core.active++
|
|
2334
|
-
}
|
|
2335
|
-
|
|
2336
|
-
attachTo (protomux, useSession) {
|
|
2358
|
+
attachTo (protomux) {
|
|
2337
2359
|
if (this.core.closed) return
|
|
2338
|
-
if (useSession) this.ensureSession()
|
|
2339
2360
|
|
|
2340
|
-
const makePeer = this._makePeer.bind(this, protomux
|
|
2361
|
+
const makePeer = this._makePeer.bind(this, protomux)
|
|
2341
2362
|
|
|
2342
2363
|
this._attached.add(protomux)
|
|
2343
|
-
protomux.pair({ protocol: 'hypercore/alpha', id: this.discoveryKey }, makePeer)
|
|
2364
|
+
protomux.pair({ protocol: 'hypercore/alpha', id: this.core.discoveryKey }, makePeer)
|
|
2344
2365
|
protomux.stream.setMaxListeners(0)
|
|
2345
2366
|
protomux.stream.on('close', this._onstreamclose)
|
|
2346
2367
|
|
|
2347
|
-
if (useSession) this._peerSessions++
|
|
2348
2368
|
this._ifAvailable++
|
|
2369
|
+
this._active++
|
|
2349
2370
|
|
|
2350
2371
|
protomux.stream.opened.then((opened) => {
|
|
2351
|
-
if (useSession) this._peerSessions--
|
|
2352
2372
|
this._ifAvailable--
|
|
2373
|
+
this._active--
|
|
2353
2374
|
|
|
2354
2375
|
if (opened && !this.destroyed) makePeer()
|
|
2355
|
-
else if (useSession) this._closeSessionMaybe()
|
|
2356
2376
|
this._checkUpgradeIfAvailable()
|
|
2377
|
+
|
|
2378
|
+
this.core.checkIfIdle()
|
|
2357
2379
|
})
|
|
2358
2380
|
}
|
|
2359
2381
|
|
|
2360
2382
|
detachFrom (protomux) {
|
|
2361
2383
|
if (this._attached.delete(protomux)) {
|
|
2362
2384
|
protomux.stream.removeListener('close', this._onstreamclose)
|
|
2363
|
-
protomux.unpair({ protocol: 'hypercore/alpha', id: this.discoveryKey })
|
|
2385
|
+
protomux.unpair({ protocol: 'hypercore/alpha', id: this.core.discoveryKey })
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
idle () {
|
|
2390
|
+
return this.peers.length === 0 && this._active === 0
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2393
|
+
close () {
|
|
2394
|
+
const waiting = []
|
|
2395
|
+
|
|
2396
|
+
for (const peer of this.peers) {
|
|
2397
|
+
waiting.push(peer.channel.fullyClosed())
|
|
2364
2398
|
}
|
|
2399
|
+
|
|
2400
|
+
this.destroy()
|
|
2401
|
+
return Promise.all(waiting)
|
|
2365
2402
|
}
|
|
2366
2403
|
|
|
2367
2404
|
destroy () {
|
|
2405
|
+
if (this.destroyed) return
|
|
2368
2406
|
this.destroyed = true
|
|
2369
2407
|
|
|
2370
2408
|
if (this._downloadingTimer) {
|
|
@@ -2372,31 +2410,26 @@ module.exports = class Replicator {
|
|
|
2372
2410
|
this._downloadingTimer = null
|
|
2373
2411
|
}
|
|
2374
2412
|
|
|
2375
|
-
const waiting = []
|
|
2376
|
-
|
|
2377
2413
|
while (this.peers.length) {
|
|
2378
2414
|
const peer = this.peers[this.peers.length - 1]
|
|
2379
2415
|
this.detachFrom(peer.protomux)
|
|
2380
2416
|
peer.channel.close() // peer is removed from array in onclose
|
|
2381
|
-
waiting.push(peer.channel.fullyClosed())
|
|
2382
2417
|
}
|
|
2383
2418
|
|
|
2384
2419
|
for (const protomux of this._attached) {
|
|
2385
2420
|
this.detachFrom(protomux)
|
|
2386
2421
|
}
|
|
2387
|
-
|
|
2388
|
-
return Promise.all(waiting)
|
|
2389
2422
|
}
|
|
2390
2423
|
|
|
2391
|
-
_makePeer (protomux
|
|
2424
|
+
_makePeer (protomux) {
|
|
2392
2425
|
const replicator = this
|
|
2393
|
-
if (protomux.opened({ protocol: 'hypercore/alpha', id: this.discoveryKey })) return onnochannel()
|
|
2426
|
+
if (protomux.opened({ protocol: 'hypercore/alpha', id: this.core.discoveryKey })) return onnochannel()
|
|
2394
2427
|
|
|
2395
2428
|
const channel = protomux.createChannel({
|
|
2396
2429
|
userData: null,
|
|
2397
2430
|
protocol: 'hypercore/alpha',
|
|
2398
2431
|
aliases: ['hypercore'],
|
|
2399
|
-
id: this.discoveryKey,
|
|
2432
|
+
id: this.core.discoveryKey,
|
|
2400
2433
|
handshake: m.wire.handshake,
|
|
2401
2434
|
messages: [
|
|
2402
2435
|
{ encoding: m.wire.sync, onmessage: onwiresync },
|
|
@@ -2412,32 +2445,67 @@ module.exports = class Replicator {
|
|
|
2412
2445
|
],
|
|
2413
2446
|
onopen: onwireopen,
|
|
2414
2447
|
onclose: onwireclose,
|
|
2415
|
-
ondrain: onwiredrain
|
|
2448
|
+
ondrain: onwiredrain,
|
|
2449
|
+
ondestroy: onwiredestroy
|
|
2416
2450
|
})
|
|
2417
2451
|
|
|
2418
2452
|
if (channel === null) return onnochannel()
|
|
2419
2453
|
|
|
2420
|
-
const peer = new Peer(replicator, protomux, channel,
|
|
2454
|
+
const peer = new Peer(replicator, protomux, channel, this.inflightRange)
|
|
2421
2455
|
const stream = protomux.stream
|
|
2422
2456
|
|
|
2423
|
-
if (useSession) {
|
|
2424
|
-
// session may have been unref'd underneath us
|
|
2425
|
-
replicator.ensureSession()
|
|
2426
|
-
replicator._peerSessions++
|
|
2427
|
-
}
|
|
2428
|
-
|
|
2429
2457
|
peer.channel.open({
|
|
2430
2458
|
seeks: true,
|
|
2431
|
-
capability: caps.replicate(stream.isInitiator, this.key, stream.handshakeHash)
|
|
2459
|
+
capability: caps.replicate(stream.isInitiator, this.core.key, stream.handshakeHash)
|
|
2432
2460
|
})
|
|
2433
2461
|
|
|
2434
2462
|
return true
|
|
2435
2463
|
|
|
2436
2464
|
function onnochannel () {
|
|
2437
|
-
if (useSession) replicator._closeSessionMaybe()
|
|
2438
2465
|
return false
|
|
2439
2466
|
}
|
|
2440
2467
|
}
|
|
2468
|
+
|
|
2469
|
+
_onpeerupdate (added, peer) {
|
|
2470
|
+
const name = added ? 'peer-add' : 'peer-remove'
|
|
2471
|
+
const sessions = this.core.monitors
|
|
2472
|
+
|
|
2473
|
+
for (let i = sessions.length - 1; i >= 0; i--) {
|
|
2474
|
+
sessions[i].emit(name, peer)
|
|
2475
|
+
|
|
2476
|
+
if (added) {
|
|
2477
|
+
for (const ext of sessions[i].extensions.values()) {
|
|
2478
|
+
peer.extensions.set(ext.name, ext)
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
|
|
2484
|
+
_ondownload (index, byteLength, from) {
|
|
2485
|
+
const sessions = this.core.monitors
|
|
2486
|
+
|
|
2487
|
+
for (let i = sessions.length - 1; i >= 0; i--) {
|
|
2488
|
+
const s = sessions[i]
|
|
2489
|
+
s.emit('download', index, byteLength - s.padding, from)
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
|
|
2493
|
+
_onupload (index, byteLength, from) {
|
|
2494
|
+
const sessions = this.core.monitors
|
|
2495
|
+
|
|
2496
|
+
for (let i = sessions.length - 1; i >= 0; i--) {
|
|
2497
|
+
const s = sessions[i]
|
|
2498
|
+
s.emit('upload', index, byteLength - s.padding, from)
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2501
|
+
|
|
2502
|
+
_oninvalid (err, req, res, from) {
|
|
2503
|
+
const sessions = this.core.monitors
|
|
2504
|
+
|
|
2505
|
+
for (let i = 0; i < sessions.length; i++) {
|
|
2506
|
+
sessions[i].emit('verification-error', err, req, res, from)
|
|
2507
|
+
}
|
|
2508
|
+
}
|
|
2441
2509
|
}
|
|
2442
2510
|
|
|
2443
2511
|
function matchingRequest (req, data) {
|
|
@@ -2462,8 +2530,6 @@ function removeInflight (inf, req) {
|
|
|
2462
2530
|
return true
|
|
2463
2531
|
}
|
|
2464
2532
|
|
|
2465
|
-
function noop () {}
|
|
2466
|
-
|
|
2467
2533
|
function toLength (start, end) {
|
|
2468
2534
|
return end === -1 ? -1 : (end < start ? 0 : end - start)
|
|
2469
2535
|
}
|
|
@@ -2512,6 +2578,10 @@ function onwireclose (isRemote, c) {
|
|
|
2512
2578
|
return c.userData.onclose(isRemote)
|
|
2513
2579
|
}
|
|
2514
2580
|
|
|
2581
|
+
function onwiredestroy (c) {
|
|
2582
|
+
c.userData.replicator.onpeerdestroy()
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2515
2585
|
function onwiredrain (c) {
|
|
2516
2586
|
return c.userData.ondrain()
|
|
2517
2587
|
}
|