hypercore 10.0.0-alpha.15 → 10.0.0-alpha.19
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 +1 -1
- package/index.js +31 -24
- package/lib/core.js +3 -2
- package/lib/merkle-tree.js +19 -6
- package/lib/protocol.js +1 -1
- package/lib/streams.js +18 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -87,7 +87,7 @@ Options include
|
|
|
87
87
|
|
|
88
88
|
``` js
|
|
89
89
|
{
|
|
90
|
-
wait: true, // wait for
|
|
90
|
+
wait: true, // wait for block to be downloaded
|
|
91
91
|
onwait: () => {}, // hook that is called if the get is waiting for download
|
|
92
92
|
timeout: 0, // wait at max some milliseconds (0 means no timeout)
|
|
93
93
|
valueEncoding: 'json' | 'utf-8' | 'binary' // defaults to the core's valueEncoding
|
package/index.js
CHANGED
|
@@ -14,7 +14,7 @@ const Replicator = require('./lib/replicator')
|
|
|
14
14
|
const Extensions = require('./lib/extensions')
|
|
15
15
|
const Core = require('./lib/core')
|
|
16
16
|
const BlockEncryption = require('./lib/block-encryption')
|
|
17
|
-
const { ReadStream } = require('./lib/streams')
|
|
17
|
+
const { ReadStream, WriteStream } = require('./lib/streams')
|
|
18
18
|
|
|
19
19
|
const promises = Symbol.for('hypercore.promises')
|
|
20
20
|
const inspect = Symbol.for('nodejs.util.inspect.custom')
|
|
@@ -92,9 +92,27 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
92
92
|
indent + ')'
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
static createProtocolStream (isInitiator, opts) {
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
static createProtocolStream (isInitiator, opts = {}) {
|
|
96
|
+
let outerStream = isStream(isInitiator)
|
|
97
|
+
? isInitiator
|
|
98
|
+
: opts.stream
|
|
99
|
+
let noiseStream = null
|
|
100
|
+
|
|
101
|
+
if (outerStream) {
|
|
102
|
+
noiseStream = outerStream.noiseStream
|
|
103
|
+
} else {
|
|
104
|
+
noiseStream = new NoiseSecretStream(isInitiator, null, opts)
|
|
105
|
+
outerStream = noiseStream.rawStream
|
|
106
|
+
}
|
|
107
|
+
if (!noiseStream) throw new Error('Invalid stream')
|
|
108
|
+
|
|
109
|
+
if (!noiseStream.userData) {
|
|
110
|
+
const protocol = Replicator.createProtocol(noiseStream)
|
|
111
|
+
noiseStream.userData = protocol
|
|
112
|
+
noiseStream.on('error', noop) // All noise errors already propagate through outerStream
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return outerStream
|
|
98
116
|
}
|
|
99
117
|
|
|
100
118
|
static defaultStorage (storage, opts = {}) {
|
|
@@ -268,33 +286,17 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
268
286
|
}
|
|
269
287
|
|
|
270
288
|
replicate (isInitiator, opts = {}) {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
: opts.stream
|
|
274
|
-
let noiseStream = null
|
|
275
|
-
|
|
276
|
-
if (outerStream) {
|
|
277
|
-
noiseStream = outerStream.noiseStream
|
|
278
|
-
} else {
|
|
279
|
-
outerStream = Hypercore.createProtocolStream(isInitiator, opts)
|
|
280
|
-
noiseStream = outerStream.noiseStream
|
|
281
|
-
}
|
|
282
|
-
if (!noiseStream) throw new Error('Invalid stream passed to replicate')
|
|
283
|
-
|
|
284
|
-
if (!noiseStream.userData) {
|
|
285
|
-
const protocol = Replicator.createProtocol(noiseStream)
|
|
286
|
-
noiseStream.userData = protocol
|
|
287
|
-
noiseStream.on('error', noop) // All noise errors already propagate through outerStream
|
|
288
|
-
}
|
|
289
|
-
|
|
289
|
+
const protocolStream = Hypercore.createProtocolStream(isInitiator, opts)
|
|
290
|
+
const noiseStream = protocolStream.noiseStream
|
|
290
291
|
const protocol = noiseStream.userData
|
|
292
|
+
|
|
291
293
|
if (this.opened) {
|
|
292
294
|
this.replicator.joinProtocol(protocol, this.key, this.discoveryKey)
|
|
293
295
|
} else {
|
|
294
296
|
this.opening.then(() => this.replicator.joinProtocol(protocol, this.key, this.discoveryKey), protocol.destroy.bind(protocol))
|
|
295
297
|
}
|
|
296
298
|
|
|
297
|
-
return
|
|
299
|
+
return protocolStream
|
|
298
300
|
}
|
|
299
301
|
|
|
300
302
|
get length () {
|
|
@@ -416,6 +418,7 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
416
418
|
if (this.core.bitfield.get(index)) {
|
|
417
419
|
block = await this.core.blocks.get(index)
|
|
418
420
|
} else {
|
|
421
|
+
if (opts && opts.wait === false) return null
|
|
419
422
|
if (opts && opts.onwait) opts.onwait(index)
|
|
420
423
|
block = await this.replicator.requestBlock(index)
|
|
421
424
|
}
|
|
@@ -428,6 +431,10 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
428
431
|
return new ReadStream(this, opts)
|
|
429
432
|
}
|
|
430
433
|
|
|
434
|
+
createWriteStream (opts) {
|
|
435
|
+
return new WriteStream(this, opts)
|
|
436
|
+
}
|
|
437
|
+
|
|
431
438
|
download (range) {
|
|
432
439
|
const linear = !!(range && range.linear)
|
|
433
440
|
|
package/lib/core.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const hypercoreCrypto = require('hypercore-crypto')
|
|
2
|
+
const b4a = require('b4a')
|
|
2
3
|
const Oplog = require('./oplog')
|
|
3
4
|
const Mutex = require('./mutex')
|
|
4
5
|
const MerkleTree = require('./merkle-tree')
|
|
@@ -90,7 +91,7 @@ module.exports = class Core {
|
|
|
90
91
|
await oplog.flush(header)
|
|
91
92
|
}
|
|
92
93
|
|
|
93
|
-
if (opts.keyPair && !header.signer.publicKey
|
|
94
|
+
if (opts.keyPair && !b4a.equals(header.signer.publicKey, opts.keyPair.publicKey)) {
|
|
94
95
|
throw new Error('Another hypercore is stored here')
|
|
95
96
|
}
|
|
96
97
|
|
|
@@ -176,7 +177,7 @@ module.exports = class Core {
|
|
|
176
177
|
|
|
177
178
|
for (const u of this.header.userData) {
|
|
178
179
|
if (u.key !== key) continue
|
|
179
|
-
if (value &&
|
|
180
|
+
if (value && b4a.equals(u.value, value)) return
|
|
180
181
|
empty = false
|
|
181
182
|
break
|
|
182
183
|
}
|
package/lib/merkle-tree.js
CHANGED
|
@@ -215,7 +215,7 @@ class ReorgBatch extends MerkleTreeBatch {
|
|
|
215
215
|
const nodes = []
|
|
216
216
|
const root = verifyBlock(proof, this.tree.crypto, nodes)
|
|
217
217
|
|
|
218
|
-
if (root === null || !root.hash
|
|
218
|
+
if (root === null || !b4a.equals(root.hash, this.diff.hash)) return false
|
|
219
219
|
|
|
220
220
|
this.nodes.push(...nodes)
|
|
221
221
|
return this._update(nodes)
|
|
@@ -233,7 +233,7 @@ class ReorgBatch extends MerkleTreeBatch {
|
|
|
233
233
|
if (!left) break
|
|
234
234
|
|
|
235
235
|
const existing = await this.tree.get(left.index, false)
|
|
236
|
-
if (!existing || !existing.hash
|
|
236
|
+
if (!existing || !b4a.equals(existing.hash, left.hash)) {
|
|
237
237
|
diff = left
|
|
238
238
|
} else {
|
|
239
239
|
diff = n.get(ite.sibling())
|
|
@@ -247,6 +247,8 @@ class ReorgBatch extends MerkleTreeBatch {
|
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
_updateDiffRoot (diff) {
|
|
250
|
+
if (this.want === null) return true
|
|
251
|
+
|
|
250
252
|
const spans = flat.spans(diff.index)
|
|
251
253
|
const start = spans[0] / 2
|
|
252
254
|
const end = Math.min(this.treeLength, spans[1] / 2 + 1)
|
|
@@ -355,7 +357,7 @@ module.exports = class MerkleTree {
|
|
|
355
357
|
}
|
|
356
358
|
|
|
357
359
|
addNode (node) {
|
|
358
|
-
if (node.size === 0 && node.hash
|
|
360
|
+
if (node.size === 0 && b4a.equals(node.hash, BLANK_HASH)) node = blankNode(node.index)
|
|
359
361
|
this.unflushed.set(node.index, node)
|
|
360
362
|
}
|
|
361
363
|
|
|
@@ -379,6 +381,17 @@ module.exports = class MerkleTree {
|
|
|
379
381
|
return this.signature !== null && this.crypto.verify(this.signable(), this.signature, key)
|
|
380
382
|
}
|
|
381
383
|
|
|
384
|
+
getRoots (length) {
|
|
385
|
+
const indexes = flat.fullRoots(2 * length)
|
|
386
|
+
const roots = new Array(indexes.length)
|
|
387
|
+
|
|
388
|
+
for (let i = 0; i < indexes.length; i++) {
|
|
389
|
+
roots[i] = this.get(indexes[i], true)
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
return Promise.all(roots)
|
|
393
|
+
}
|
|
394
|
+
|
|
382
395
|
get (index, error = true) {
|
|
383
396
|
let node = this.unflushed.get(index)
|
|
384
397
|
|
|
@@ -534,7 +547,7 @@ module.exports = class MerkleTree {
|
|
|
534
547
|
|
|
535
548
|
for (const root of batch.roots) {
|
|
536
549
|
const existing = await this.get(root.index, false)
|
|
537
|
-
if (existing && existing.hash
|
|
550
|
+
if (existing && b4a.equals(existing.hash, root.hash)) continue
|
|
538
551
|
batch._updateDiffRoot(root)
|
|
539
552
|
break
|
|
540
553
|
}
|
|
@@ -562,7 +575,7 @@ module.exports = class MerkleTree {
|
|
|
562
575
|
|
|
563
576
|
if (unverified) {
|
|
564
577
|
const verified = await this.get(unverified.index)
|
|
565
|
-
if (!verified.hash
|
|
578
|
+
if (!b4a.equals(verified.hash, unverified.hash)) {
|
|
566
579
|
throw new Error('Invalid checksum at node ' + unverified.index)
|
|
567
580
|
}
|
|
568
581
|
}
|
|
@@ -707,7 +720,7 @@ module.exports = class MerkleTree {
|
|
|
707
720
|
await new Promise((resolve, reject) => {
|
|
708
721
|
storage.read(0, OLD_TREE.length, (err, buf) => {
|
|
709
722
|
if (err) return resolve()
|
|
710
|
-
if (
|
|
723
|
+
if (b4a.equals(buf, OLD_TREE)) return reject(new Error('Storage contains an incompatible merkle tree'))
|
|
711
724
|
resolve()
|
|
712
725
|
})
|
|
713
726
|
})
|
package/lib/protocol.js
CHANGED
package/lib/streams.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { Readable } = require('streamx')
|
|
1
|
+
const { Writable, Readable } = require('streamx')
|
|
2
2
|
|
|
3
3
|
class ReadStream extends Readable {
|
|
4
4
|
constructor (core, opts = {}) {
|
|
@@ -37,3 +37,20 @@ class ReadStream extends Readable {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
exports.ReadStream = ReadStream
|
|
40
|
+
|
|
41
|
+
class WriteStream extends Writable {
|
|
42
|
+
constructor (core) {
|
|
43
|
+
super()
|
|
44
|
+
this.core = core
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
_writev (batch, cb) {
|
|
48
|
+
this._writevP(batch).then(cb, cb)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async _writevP (batch) {
|
|
52
|
+
await this.core.append(batch)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
exports.WriteStream = WriteStream
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hypercore",
|
|
3
|
-
"version": "10.0.0-alpha.
|
|
3
|
+
"version": "10.0.0-alpha.19",
|
|
4
4
|
"description": "Hypercore 10",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@hyperswarm/secret-stream": "^5.0.0",
|
|
36
36
|
"b4a": "^1.1.0",
|
|
37
37
|
"big-sparse-array": "^1.0.2",
|
|
38
|
-
"codecs": "^
|
|
38
|
+
"codecs": "^3.0.0",
|
|
39
39
|
"compact-encoding": "^2.5.0",
|
|
40
40
|
"crc32-universal": "^1.0.1",
|
|
41
41
|
"events": "^3.3.0",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"xache": "^1.0.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"brittle": "^
|
|
52
|
+
"brittle": "^2.0.0",
|
|
53
53
|
"hyperswarm": "next",
|
|
54
54
|
"random-access-memory": "^3.1.2",
|
|
55
55
|
"standard": "^16.0.3",
|