hypercore 10.0.0-alpha.3 → 10.0.0-alpha.32
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 +45 -3
- package/index.js +390 -156
- package/lib/bitfield.js +9 -5
- package/lib/block-encryption.js +68 -0
- package/lib/block-store.js +3 -1
- package/lib/caps.js +34 -0
- package/lib/core.js +32 -13
- package/lib/merkle-tree.js +184 -109
- package/lib/messages.js +245 -167
- package/lib/oplog.js +4 -3
- package/lib/replicator.js +1359 -593
- package/lib/streams.js +56 -0
- package/package.json +17 -8
- package/.github/workflows/test-node.yml +0 -24
- package/UPGRADE.md +0 -9
- package/examples/announce.js +0 -19
- package/examples/basic.js +0 -10
- package/examples/http.js +0 -123
- package/examples/lookup.js +0 -20
- package/lib/extensions.js +0 -76
- package/lib/protocol.js +0 -522
- package/lib/random-iterator.js +0 -46
- package/test/basic.js +0 -78
- package/test/bitfield.js +0 -71
- package/test/core.js +0 -290
- package/test/encodings.js +0 -18
- package/test/extension.js +0 -71
- package/test/helpers/index.js +0 -23
- package/test/merkle-tree.js +0 -518
- package/test/mutex.js +0 -137
- package/test/oplog.js +0 -399
- package/test/preload.js +0 -72
- package/test/replicate.js +0 -296
- package/test/sessions.js +0 -173
- package/test/user-data.js +0 -47
package/lib/merkle-tree.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
const flat = require('flat-tree')
|
|
2
2
|
const crypto = require('hypercore-crypto')
|
|
3
|
-
const
|
|
3
|
+
const c = require('compact-encoding')
|
|
4
|
+
const b4a = require('b4a')
|
|
5
|
+
const caps = require('./caps')
|
|
4
6
|
|
|
5
|
-
const BLANK_HASH =
|
|
6
|
-
const OLD_TREE =
|
|
7
|
+
const BLANK_HASH = b4a.alloc(32)
|
|
8
|
+
const OLD_TREE = b4a.from([5, 2, 87, 2, 0, 0, 40, 7, 66, 76, 65, 75, 69, 50, 98])
|
|
7
9
|
|
|
8
10
|
class NodeQueue {
|
|
9
11
|
constructor (nodes, extra = null) {
|
|
@@ -56,11 +58,11 @@ class MerkleTreeBatch {
|
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
signable (hash = this.hash()) {
|
|
59
|
-
return
|
|
61
|
+
return caps.treeSignable(hash, this.length, this.fork)
|
|
60
62
|
}
|
|
61
63
|
|
|
62
|
-
|
|
63
|
-
return
|
|
64
|
+
signableLegacy (hash = this.hash()) {
|
|
65
|
+
return caps.treeSignableLegacy(hash, this.length, this.fork)
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
append (buf) {
|
|
@@ -212,9 +214,9 @@ class ReorgBatch extends MerkleTreeBatch {
|
|
|
212
214
|
if (this.want === null) return true
|
|
213
215
|
|
|
214
216
|
const nodes = []
|
|
215
|
-
const root =
|
|
217
|
+
const root = verifyTree(proof, this.tree.crypto, nodes)
|
|
216
218
|
|
|
217
|
-
if (root === null || !root.hash
|
|
219
|
+
if (root === null || !b4a.equals(root.hash, this.diff.hash)) return false
|
|
218
220
|
|
|
219
221
|
this.nodes.push(...nodes)
|
|
220
222
|
return this._update(nodes)
|
|
@@ -232,7 +234,7 @@ class ReorgBatch extends MerkleTreeBatch {
|
|
|
232
234
|
if (!left) break
|
|
233
235
|
|
|
234
236
|
const existing = await this.tree.get(left.index, false)
|
|
235
|
-
if (!existing || !existing.hash
|
|
237
|
+
if (!existing || !b4a.equals(existing.hash, left.hash)) {
|
|
236
238
|
diff = left
|
|
237
239
|
} else {
|
|
238
240
|
diff = n.get(ite.sibling())
|
|
@@ -246,6 +248,8 @@ class ReorgBatch extends MerkleTreeBatch {
|
|
|
246
248
|
}
|
|
247
249
|
|
|
248
250
|
_updateDiffRoot (diff) {
|
|
251
|
+
if (this.want === null) return true
|
|
252
|
+
|
|
249
253
|
const spans = flat.spans(diff.index)
|
|
250
254
|
const start = spans[0] / 2
|
|
251
255
|
const end = Math.min(this.treeLength, spans[1] / 2 + 1)
|
|
@@ -272,11 +276,15 @@ class ReorgBatch extends MerkleTreeBatch {
|
|
|
272
276
|
}
|
|
273
277
|
|
|
274
278
|
class ByteSeeker {
|
|
275
|
-
constructor (tree, bytes) {
|
|
279
|
+
constructor (tree, bytes, padding = 0) {
|
|
276
280
|
this.tree = tree
|
|
277
281
|
this.bytes = bytes
|
|
278
|
-
this.
|
|
279
|
-
|
|
282
|
+
this.padding = padding
|
|
283
|
+
|
|
284
|
+
const size = tree.byteLength - (tree.length * padding)
|
|
285
|
+
|
|
286
|
+
this.start = bytes >= size ? tree.length : 0
|
|
287
|
+
this.end = bytes < size ? tree.length : 0
|
|
280
288
|
}
|
|
281
289
|
|
|
282
290
|
nodes () {
|
|
@@ -287,12 +295,12 @@ class ByteSeeker {
|
|
|
287
295
|
if (!bytes) return [0, 0]
|
|
288
296
|
|
|
289
297
|
for (const node of this.tree.roots) { // all async ticks happen once we find the root so safe
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
}
|
|
298
|
+
let size = node.size
|
|
299
|
+
if (this.padding > 0) size -= this.padding * flat.countLeaves(node.index)
|
|
293
300
|
|
|
294
|
-
if (bytes
|
|
295
|
-
|
|
301
|
+
if (bytes === size) return [flat.rightSpan(node.index) + 2, 0]
|
|
302
|
+
if (bytes > size) {
|
|
303
|
+
bytes -= size
|
|
296
304
|
continue
|
|
297
305
|
}
|
|
298
306
|
|
|
@@ -301,9 +309,12 @@ class ByteSeeker {
|
|
|
301
309
|
while ((ite.index & 1) !== 0) {
|
|
302
310
|
const l = await this.tree.get(ite.leftChild(), false)
|
|
303
311
|
if (l) {
|
|
304
|
-
|
|
305
|
-
if (
|
|
306
|
-
|
|
312
|
+
let size = l.size
|
|
313
|
+
if (this.padding > 0) size -= this.padding * ite.countLeaves()
|
|
314
|
+
|
|
315
|
+
if (size === bytes) return [ite.rightSpan() + 2, 0]
|
|
316
|
+
if (size > bytes) continue
|
|
317
|
+
bytes -= size
|
|
307
318
|
ite.sibling()
|
|
308
319
|
} else {
|
|
309
320
|
ite.parent()
|
|
@@ -347,7 +358,7 @@ module.exports = class MerkleTree {
|
|
|
347
358
|
}
|
|
348
359
|
|
|
349
360
|
addNode (node) {
|
|
350
|
-
if (node.size === 0 && node.hash
|
|
361
|
+
if (node.size === 0 && b4a.equals(node.hash, BLANK_HASH)) node = blankNode(node.index)
|
|
351
362
|
this.unflushed.set(node.index, node)
|
|
352
363
|
}
|
|
353
364
|
|
|
@@ -355,8 +366,8 @@ module.exports = class MerkleTree {
|
|
|
355
366
|
return new MerkleTreeBatch(this)
|
|
356
367
|
}
|
|
357
368
|
|
|
358
|
-
seek (bytes) {
|
|
359
|
-
return new ByteSeeker(this, bytes)
|
|
369
|
+
seek (bytes, padding) {
|
|
370
|
+
return new ByteSeeker(this, bytes, padding)
|
|
360
371
|
}
|
|
361
372
|
|
|
362
373
|
hash () {
|
|
@@ -364,11 +375,33 @@ module.exports = class MerkleTree {
|
|
|
364
375
|
}
|
|
365
376
|
|
|
366
377
|
signable (hash = this.hash()) {
|
|
367
|
-
return
|
|
378
|
+
return caps.treeSignable(hash, this.length, this.fork)
|
|
368
379
|
}
|
|
369
380
|
|
|
370
|
-
|
|
371
|
-
|
|
381
|
+
getRoots (length) {
|
|
382
|
+
const indexes = flat.fullRoots(2 * length)
|
|
383
|
+
const roots = new Array(indexes.length)
|
|
384
|
+
|
|
385
|
+
for (let i = 0; i < indexes.length; i++) {
|
|
386
|
+
roots[i] = this.get(indexes[i], true)
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return Promise.all(roots)
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
async upgradeable (length) {
|
|
393
|
+
const indexes = flat.fullRoots(2 * length)
|
|
394
|
+
const roots = new Array(indexes.length)
|
|
395
|
+
|
|
396
|
+
for (let i = 0; i < indexes.length; i++) {
|
|
397
|
+
roots[i] = this.get(indexes[i], false)
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
for (const node of await Promise.all(roots)) {
|
|
401
|
+
if (node === null) return false
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
return true
|
|
372
405
|
}
|
|
373
406
|
|
|
374
407
|
get (index, error = true) {
|
|
@@ -433,17 +466,23 @@ module.exports = class MerkleTree {
|
|
|
433
466
|
// TODO: write neighbors together etc etc
|
|
434
467
|
// TODO: bench loading a full disk page and copy to that instead
|
|
435
468
|
return new Promise((resolve, reject) => {
|
|
436
|
-
const slab =
|
|
469
|
+
const slab = b4a.allocUnsafe(40 * this.flushing.size)
|
|
437
470
|
|
|
438
471
|
let error = null
|
|
439
472
|
let missing = this.flushing.size + 1
|
|
440
473
|
let offset = 0
|
|
441
474
|
|
|
442
475
|
for (const node of this.flushing.values()) {
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
476
|
+
const state = {
|
|
477
|
+
start: 0,
|
|
478
|
+
end: 40,
|
|
479
|
+
buffer: slab.subarray(offset, offset += 40)
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
c.uint64.encode(state, node.size)
|
|
483
|
+
c.raw.encode(state, node.hash)
|
|
484
|
+
|
|
485
|
+
this.storage.write(node.index * 40, state.buffer, done)
|
|
447
486
|
}
|
|
448
487
|
|
|
449
488
|
done(null)
|
|
@@ -510,8 +549,8 @@ module.exports = class MerkleTree {
|
|
|
510
549
|
|
|
511
550
|
let unverified = null
|
|
512
551
|
|
|
513
|
-
if (proof.block || proof.seek) {
|
|
514
|
-
unverified =
|
|
552
|
+
if (proof.block || proof.hash || proof.seek) {
|
|
553
|
+
unverified = verifyTree(proof, this.crypto, batch.nodes)
|
|
515
554
|
}
|
|
516
555
|
|
|
517
556
|
if (!verifyUpgrade(proof, unverified, batch)) {
|
|
@@ -520,7 +559,7 @@ module.exports = class MerkleTree {
|
|
|
520
559
|
|
|
521
560
|
for (const root of batch.roots) {
|
|
522
561
|
const existing = await this.get(root.index, false)
|
|
523
|
-
if (existing && existing.hash
|
|
562
|
+
if (existing && b4a.equals(existing.hash, root.hash)) continue
|
|
524
563
|
batch._updateDiffRoot(root)
|
|
525
564
|
break
|
|
526
565
|
}
|
|
@@ -538,7 +577,7 @@ module.exports = class MerkleTree {
|
|
|
538
577
|
async verify (proof) {
|
|
539
578
|
const batch = new MerkleTreeBatch(this)
|
|
540
579
|
|
|
541
|
-
let unverified =
|
|
580
|
+
let unverified = verifyTree(proof, this.crypto, batch.nodes)
|
|
542
581
|
|
|
543
582
|
if (proof.upgrade) {
|
|
544
583
|
if (verifyUpgrade(proof, unverified, batch)) {
|
|
@@ -548,7 +587,7 @@ module.exports = class MerkleTree {
|
|
|
548
587
|
|
|
549
588
|
if (unverified) {
|
|
550
589
|
const verified = await this.get(unverified.index)
|
|
551
|
-
if (!verified.hash
|
|
590
|
+
if (!b4a.equals(verified.hash, unverified.hash)) {
|
|
552
591
|
throw new Error('Invalid checksum at node ' + unverified.index)
|
|
553
592
|
}
|
|
554
593
|
}
|
|
@@ -556,89 +595,102 @@ module.exports = class MerkleTree {
|
|
|
556
595
|
return batch
|
|
557
596
|
}
|
|
558
597
|
|
|
559
|
-
async proof ({ block, seek, upgrade }) {
|
|
598
|
+
async proof ({ block, hash, seek, upgrade }) {
|
|
560
599
|
// Important that this does not throw inbetween making the promise arrays
|
|
561
600
|
// and finalise being called, otherwise there will be lingering promises in the background
|
|
562
601
|
|
|
563
|
-
const signature = this.signature
|
|
564
602
|
const fork = this.fork
|
|
603
|
+
const signature = this.signature
|
|
565
604
|
const head = 2 * this.length
|
|
566
605
|
const from = upgrade ? upgrade.start * 2 : 0
|
|
567
606
|
const to = upgrade ? from + upgrade.length * 2 : head
|
|
607
|
+
const node = normalizeIndexed(block, hash)
|
|
568
608
|
|
|
569
609
|
if (from >= to || to > head) {
|
|
570
610
|
throw new Error('Invalid upgrade')
|
|
571
611
|
}
|
|
572
|
-
if (seek &&
|
|
573
|
-
throw new Error('Cannot both do a seek and block request when upgrading')
|
|
612
|
+
if (seek && upgrade && node !== null && node.index >= from) {
|
|
613
|
+
throw new Error('Cannot both do a seek and block/hash request when upgrading')
|
|
574
614
|
}
|
|
575
615
|
|
|
576
616
|
let subTree = head
|
|
577
617
|
|
|
578
618
|
const p = {
|
|
579
|
-
|
|
619
|
+
node: null,
|
|
580
620
|
seek: null,
|
|
581
621
|
upgrade: null,
|
|
582
622
|
additionalUpgrade: null
|
|
583
623
|
}
|
|
584
624
|
|
|
585
|
-
if (
|
|
586
|
-
subTree = nodesToRoot(
|
|
625
|
+
if (node !== null && (!upgrade || node.lastIndex < upgrade.start)) {
|
|
626
|
+
subTree = nodesToRoot(node.index, node.nodes, to)
|
|
587
627
|
const seekRoot = seek ? await seekUntrustedTree(this, subTree, seek.bytes) : head
|
|
588
|
-
blockAndSeekProof(this,
|
|
589
|
-
} else if ((
|
|
590
|
-
subTree = seek ? await seekFromHead(this, to, seek.bytes) :
|
|
628
|
+
blockAndSeekProof(this, node, seek, seekRoot, subTree, p)
|
|
629
|
+
} else if ((node || seek) && upgrade) {
|
|
630
|
+
subTree = seek ? await seekFromHead(this, to, seek.bytes) : node.index
|
|
591
631
|
}
|
|
592
632
|
|
|
593
633
|
if (upgrade) {
|
|
594
|
-
upgradeProof(this,
|
|
634
|
+
upgradeProof(this, node, seek, from, to, subTree, p)
|
|
595
635
|
if (head > to) additionalUpgradeProof(this, to, head, p)
|
|
596
636
|
}
|
|
597
637
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
if (block) {
|
|
602
|
-
const nodes = await Promise.all(p.block)
|
|
638
|
+
const [pNode, pSeek, pUpgrade, pAdditional] = await settleProof(p)
|
|
639
|
+
const result = { fork, block: null, hash: null, seek: null, upgrade: null }
|
|
603
640
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
641
|
+
if (block) {
|
|
642
|
+
result.block = {
|
|
643
|
+
index: block.index,
|
|
644
|
+
value: null, // populated upstream, alloc it here for simplicity
|
|
645
|
+
nodes: pNode
|
|
646
|
+
}
|
|
647
|
+
} else if (hash) {
|
|
648
|
+
result.hash = {
|
|
649
|
+
index: hash.index,
|
|
650
|
+
nodes: pNode
|
|
609
651
|
}
|
|
610
|
-
|
|
611
|
-
const nodes = await Promise.all(p.seek)
|
|
652
|
+
}
|
|
612
653
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
654
|
+
if (seek && pSeek !== null) {
|
|
655
|
+
result.seek = {
|
|
656
|
+
bytes: seek.bytes,
|
|
657
|
+
nodes: pSeek
|
|
617
658
|
}
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
signature
|
|
628
|
-
}
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
if (upgrade) {
|
|
662
|
+
result.upgrade = {
|
|
663
|
+
start: upgrade.start,
|
|
664
|
+
length: upgrade.length,
|
|
665
|
+
nodes: pUpgrade,
|
|
666
|
+
additionalNodes: pAdditional || [],
|
|
667
|
+
signature
|
|
629
668
|
}
|
|
669
|
+
}
|
|
630
670
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
671
|
+
return result
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// Successor to .nodes()
|
|
675
|
+
async missingNodes (index) {
|
|
676
|
+
const head = 2 * this.length
|
|
677
|
+
const ite = flat.iterator(index)
|
|
678
|
+
|
|
679
|
+
// See iterator.rightSpan()
|
|
680
|
+
const iteRightSpan = ite.index + ite.factor / 2 - 1
|
|
681
|
+
// If the index is not in the current tree, we do not know how many missing nodes there are...
|
|
682
|
+
if (iteRightSpan >= head) return 0
|
|
683
|
+
|
|
684
|
+
let cnt = 0
|
|
685
|
+
while (!ite.contains(head) && (await this.get(ite.index, false)) === null) {
|
|
686
|
+
cnt++
|
|
687
|
+
ite.parent()
|
|
639
688
|
}
|
|
689
|
+
|
|
690
|
+
return cnt
|
|
640
691
|
}
|
|
641
692
|
|
|
693
|
+
// Deprecated
|
|
642
694
|
async nodes (index) {
|
|
643
695
|
const head = 2 * this.length
|
|
644
696
|
const ite = flat.iterator(index)
|
|
@@ -693,7 +745,7 @@ module.exports = class MerkleTree {
|
|
|
693
745
|
await new Promise((resolve, reject) => {
|
|
694
746
|
storage.read(0, OLD_TREE.length, (err, buf) => {
|
|
695
747
|
if (err) return resolve()
|
|
696
|
-
if (
|
|
748
|
+
if (b4a.equals(buf, OLD_TREE)) return reject(new Error('Storage contains an incompatible merkle tree'))
|
|
697
749
|
resolve()
|
|
698
750
|
})
|
|
699
751
|
})
|
|
@@ -713,8 +765,14 @@ module.exports = class MerkleTree {
|
|
|
713
765
|
|
|
714
766
|
// All the methods needed for proof verification
|
|
715
767
|
|
|
716
|
-
function
|
|
717
|
-
|
|
768
|
+
function verifyTree ({ block, hash, seek }, crypto, nodes) {
|
|
769
|
+
const untrustedNode = block
|
|
770
|
+
? { index: 2 * block.index, value: block.value, nodes: block.nodes }
|
|
771
|
+
: hash
|
|
772
|
+
? { index: hash.index, value: null, nodes: hash.nodes }
|
|
773
|
+
: null
|
|
774
|
+
|
|
775
|
+
if (untrustedNode === null && (!seek || !seek.nodes.length)) return null
|
|
718
776
|
|
|
719
777
|
let root = null
|
|
720
778
|
|
|
@@ -734,12 +792,12 @@ function verifyBlock ({ block, seek }, crypto, nodes) {
|
|
|
734
792
|
}
|
|
735
793
|
}
|
|
736
794
|
|
|
737
|
-
if (
|
|
795
|
+
if (untrustedNode === null) return root
|
|
738
796
|
|
|
739
|
-
const ite = flat.iterator(
|
|
740
|
-
const blockHash =
|
|
797
|
+
const ite = flat.iterator(untrustedNode.index)
|
|
798
|
+
const blockHash = untrustedNode.value && blockNode(crypto, ite.index, untrustedNode.value)
|
|
741
799
|
|
|
742
|
-
const q = new NodeQueue(
|
|
800
|
+
const q = new NodeQueue(untrustedNode.nodes, root)
|
|
743
801
|
|
|
744
802
|
root = blockHash || q.shift(ite.index)
|
|
745
803
|
nodes.push(root)
|
|
@@ -888,13 +946,13 @@ function seekProof (tree, seekRoot, root, p) {
|
|
|
888
946
|
}
|
|
889
947
|
}
|
|
890
948
|
|
|
891
|
-
function blockAndSeekProof (tree,
|
|
892
|
-
if (!
|
|
949
|
+
function blockAndSeekProof (tree, node, seek, seekRoot, root, p) {
|
|
950
|
+
if (!node) return seekProof(tree, seekRoot, root, p)
|
|
893
951
|
|
|
894
|
-
const ite = flat.iterator(
|
|
952
|
+
const ite = flat.iterator(node.index)
|
|
895
953
|
|
|
896
|
-
p.
|
|
897
|
-
if (!
|
|
954
|
+
p.node = []
|
|
955
|
+
if (!node.value) p.node.push(tree.get(ite.index))
|
|
898
956
|
|
|
899
957
|
while (ite.index !== root) {
|
|
900
958
|
ite.sibling()
|
|
@@ -902,14 +960,14 @@ function blockAndSeekProof (tree, block, seek, seekRoot, root, p) {
|
|
|
902
960
|
if (seek && ite.contains(seekRoot) && ite.index !== seekRoot) {
|
|
903
961
|
seekProof(tree, seekRoot, ite.index, p)
|
|
904
962
|
} else {
|
|
905
|
-
p.
|
|
963
|
+
p.node.push(tree.get(ite.index))
|
|
906
964
|
}
|
|
907
965
|
|
|
908
966
|
ite.parent()
|
|
909
967
|
}
|
|
910
968
|
}
|
|
911
969
|
|
|
912
|
-
function upgradeProof (tree,
|
|
970
|
+
function upgradeProof (tree, node, seek, from, to, subTree, p) {
|
|
913
971
|
if (from === 0) p.upgrade = []
|
|
914
972
|
|
|
915
973
|
for (const ite = flat.iterator(0); ite.fullRoot(to); ite.nextTree()) {
|
|
@@ -928,8 +986,8 @@ function upgradeProof (tree, block, seek, from, to, subTree, p) {
|
|
|
928
986
|
while (ite.index !== root) {
|
|
929
987
|
ite.sibling()
|
|
930
988
|
if (ite.index > target) {
|
|
931
|
-
if (p.
|
|
932
|
-
blockAndSeekProof(tree,
|
|
989
|
+
if (p.node === null && p.seek === null && ite.contains(subTree)) {
|
|
990
|
+
blockAndSeekProof(tree, node, seek, subTree, ite.index, p)
|
|
933
991
|
} else {
|
|
934
992
|
p.upgrade.push(tree.get(ite.index))
|
|
935
993
|
}
|
|
@@ -946,8 +1004,8 @@ function upgradeProof (tree, block, seek, from, to, subTree, p) {
|
|
|
946
1004
|
|
|
947
1005
|
// if the subtree included is a child of this tree, include that one
|
|
948
1006
|
// instead of a dup node
|
|
949
|
-
if (p.
|
|
950
|
-
blockAndSeekProof(tree,
|
|
1007
|
+
if (p.node === null && p.seek === null && ite.contains(subTree)) {
|
|
1008
|
+
blockAndSeekProof(tree, node, seek, subTree, ite.index, p)
|
|
951
1009
|
continue
|
|
952
1010
|
}
|
|
953
1011
|
|
|
@@ -1038,10 +1096,10 @@ function getStoredNode (storage, index, error) {
|
|
|
1038
1096
|
return
|
|
1039
1097
|
}
|
|
1040
1098
|
|
|
1041
|
-
const hash = data.
|
|
1042
|
-
const size =
|
|
1099
|
+
const hash = data.subarray(8)
|
|
1100
|
+
const size = c.decode(c.uint64, data)
|
|
1043
1101
|
|
|
1044
|
-
if (size === 0 &&
|
|
1102
|
+
if (size === 0 && b4a.compare(hash, BLANK_HASH) === 0) {
|
|
1045
1103
|
if (error) reject(new Error('Could not load node: ' + index))
|
|
1046
1104
|
else resolve(null)
|
|
1047
1105
|
return
|
|
@@ -1087,10 +1145,27 @@ function log2 (n) {
|
|
|
1087
1145
|
return res
|
|
1088
1146
|
}
|
|
1089
1147
|
|
|
1090
|
-
function
|
|
1091
|
-
|
|
1092
|
-
hash.
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1148
|
+
function normalizeIndexed (block, hash) {
|
|
1149
|
+
if (block) return { value: true, index: block.index * 2, nodes: block.nodes, lastIndex: block.index }
|
|
1150
|
+
if (hash) return { value: false, index: hash.index, nodes: hash.nodes, lastIndex: flat.rightSpan(hash.index) / 2 }
|
|
1151
|
+
return null
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
async function settleProof (p) {
|
|
1155
|
+
const result = [
|
|
1156
|
+
p.node && Promise.all(p.node),
|
|
1157
|
+
p.seek && Promise.all(p.seek),
|
|
1158
|
+
p.upgrade && Promise.all(p.upgrade),
|
|
1159
|
+
p.additionalUpgrade && Promise.all(p.additionalUpgrade)
|
|
1160
|
+
]
|
|
1161
|
+
|
|
1162
|
+
try {
|
|
1163
|
+
return await Promise.all(result)
|
|
1164
|
+
} catch (err) {
|
|
1165
|
+
if (p.node) await Promise.allSettled(p.node)
|
|
1166
|
+
if (p.seek) await Promise.allSettled(p.seek)
|
|
1167
|
+
if (p.upgrade) await Promise.allSettled(p.upgrade)
|
|
1168
|
+
if (p.additionalUpgrade) await Promise.allSettled(p.additionalUpgrade)
|
|
1169
|
+
throw err
|
|
1170
|
+
}
|
|
1096
1171
|
}
|