hypercore 10.0.0-alpha.18 → 10.0.0-alpha.21
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 +1 -0
- package/lib/merkle-tree.js +2 -0
- package/lib/protocol.js +60 -2
- package/package.json +2 -2
package/index.js
CHANGED
|
@@ -108,6 +108,7 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
108
108
|
|
|
109
109
|
if (!noiseStream.userData) {
|
|
110
110
|
const protocol = Replicator.createProtocol(noiseStream)
|
|
111
|
+
if (opts.keepAlive !== false) protocol.setKeepAlive(true)
|
|
111
112
|
noiseStream.userData = protocol
|
|
112
113
|
noiseStream.on('error', noop) // All noise errors already propagate through outerStream
|
|
113
114
|
}
|
package/lib/merkle-tree.js
CHANGED
|
@@ -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)
|
package/lib/protocol.js
CHANGED
|
@@ -2,9 +2,19 @@ const { uint, from: fromEncoding } = require('compact-encoding')
|
|
|
2
2
|
const b4a = require('b4a')
|
|
3
3
|
const safetyCatch = require('safety-catch')
|
|
4
4
|
const codecs = require('codecs')
|
|
5
|
+
const sodium = require('sodium-universal')
|
|
5
6
|
|
|
6
7
|
const messages = require('./messages')
|
|
7
8
|
|
|
9
|
+
const slab = b4a.alloc(96)
|
|
10
|
+
const NS = slab.subarray(0, 32)
|
|
11
|
+
const NS_HYPERCORE_INITIATOR = slab.subarray(32, 64)
|
|
12
|
+
const NS_HYPERCORE_RESPONDER = slab.subarray(64, 96)
|
|
13
|
+
|
|
14
|
+
sodium.crypto_generichash(NS, b4a.from('hypercore'))
|
|
15
|
+
sodium.crypto_generichash(NS_HYPERCORE_INITIATOR, b4a.from([0]), NS)
|
|
16
|
+
sodium.crypto_generichash(NS_HYPERCORE_RESPONDER, b4a.from([1]), NS)
|
|
17
|
+
|
|
8
18
|
class Extension {
|
|
9
19
|
constructor (protocol, type, name, handlers) {
|
|
10
20
|
this.protocol = protocol
|
|
@@ -256,11 +266,17 @@ module.exports = class Protocol {
|
|
|
256
266
|
this._localExtensions = 128
|
|
257
267
|
this._remoteExtensions = []
|
|
258
268
|
this._extensions = new Map()
|
|
269
|
+
this._keepAliveInterval = null
|
|
270
|
+
this._pendingCaps = []
|
|
259
271
|
|
|
260
272
|
this._destroyer = this._safeDestroy.bind(this)
|
|
261
273
|
this.noiseStream.on('data', this.onmessage.bind(this))
|
|
262
274
|
this.noiseStream.on('end', this.noiseStream.end) // no half open
|
|
275
|
+
this.noiseStream.on('finish', () => {
|
|
276
|
+
this.setKeepAlive(false)
|
|
277
|
+
})
|
|
263
278
|
this.noiseStream.on('close', () => {
|
|
279
|
+
this.setKeepAlive(false)
|
|
264
280
|
// TODO: If the stream was destroyed with an error, we probably want to forward it here
|
|
265
281
|
for (const peer of this._peers.values()) {
|
|
266
282
|
peer.destroy(null)
|
|
@@ -270,6 +286,18 @@ module.exports = class Protocol {
|
|
|
270
286
|
this._sendHandshake()
|
|
271
287
|
}
|
|
272
288
|
|
|
289
|
+
setKeepAlive (enable) {
|
|
290
|
+
if (enable) {
|
|
291
|
+
if (this._keepAliveInterval) return
|
|
292
|
+
this._keepAliveInterval = setInterval(this.ping.bind(this), 5000)
|
|
293
|
+
if (this._keepAliveInterval.unref) this._keepAliveInterval.unref()
|
|
294
|
+
} else {
|
|
295
|
+
if (!this._keepAliveInterval) return
|
|
296
|
+
clearInterval(this._keepAliveInterval)
|
|
297
|
+
this._keepAliveInterval = null
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
273
301
|
_sendHandshake () {
|
|
274
302
|
const m = { protocolVersion: this.protocolVersion, userAgent: this.userAgent }
|
|
275
303
|
const state = { start: 0, end: 0, buffer: null }
|
|
@@ -332,6 +360,11 @@ module.exports = class Protocol {
|
|
|
332
360
|
|
|
333
361
|
if (batch.length === 0) return
|
|
334
362
|
|
|
363
|
+
while (this._pendingCaps.length > 0) {
|
|
364
|
+
const [key, cap] = this._pendingCaps.pop()
|
|
365
|
+
hypercoreCapability(this.noiseStream.isInitiator, this.noiseStream.handshakeHash, key, cap)
|
|
366
|
+
}
|
|
367
|
+
|
|
335
368
|
const state = { start: 0, end: 0, buffer: null }
|
|
336
369
|
const lens = new Array(batch.length)
|
|
337
370
|
|
|
@@ -372,14 +405,24 @@ module.exports = class Protocol {
|
|
|
372
405
|
}
|
|
373
406
|
|
|
374
407
|
_announceCore (alias, key, discoveryKey) {
|
|
408
|
+
const cap = b4a.alloc(32)
|
|
409
|
+
|
|
410
|
+
if (!this.noiseStream.handshakeHash) {
|
|
411
|
+
this._pendingCaps.push([key, cap]) // encode it later...
|
|
412
|
+
} else {
|
|
413
|
+
hypercoreCapability(this.noiseStream.isInitiator, this.noiseStream.handshakeHash, key, cap)
|
|
414
|
+
}
|
|
415
|
+
|
|
375
416
|
this.send(2, messages.core, -1, {
|
|
376
417
|
alias: alias,
|
|
377
418
|
discoveryKey: discoveryKey,
|
|
378
|
-
capability:
|
|
419
|
+
capability: cap
|
|
379
420
|
})
|
|
380
421
|
}
|
|
381
422
|
|
|
382
423
|
_decode (buffer) {
|
|
424
|
+
if (buffer.byteLength === 0) return
|
|
425
|
+
|
|
383
426
|
const state = { start: 0, end: buffer.length, buffer }
|
|
384
427
|
|
|
385
428
|
if (this._firstMessage === true) {
|
|
@@ -453,7 +496,11 @@ module.exports = class Protocol {
|
|
|
453
496
|
if (m.alias === this._remoteAliases.length) this._remoteAliases.push(null)
|
|
454
497
|
|
|
455
498
|
if (peer) {
|
|
456
|
-
|
|
499
|
+
const expectedCap = hypercoreCapability(!this.noiseStream.isInitiator, this.noiseStream.handshakeHash, peer.key)
|
|
500
|
+
if (!b4a.equals(expectedCap, m.capability)) {
|
|
501
|
+
this.destroy(new Error('Remote sent an invalid capability'))
|
|
502
|
+
return
|
|
503
|
+
}
|
|
457
504
|
|
|
458
505
|
if (m.alias >= this._remoteAliases.length) {
|
|
459
506
|
this.destroy(new Error('Remote alias out of bounds'))
|
|
@@ -508,6 +555,11 @@ module.exports = class Protocol {
|
|
|
508
555
|
return this.noiseStream.write(state.buffer)
|
|
509
556
|
}
|
|
510
557
|
|
|
558
|
+
ping () {
|
|
559
|
+
const empty = this.noiseStream.alloc(0)
|
|
560
|
+
this.noiseStream.write(empty)
|
|
561
|
+
}
|
|
562
|
+
|
|
511
563
|
destroy (err) {
|
|
512
564
|
return this.noiseStream.destroy(err)
|
|
513
565
|
}
|
|
@@ -523,3 +575,9 @@ function noop () {}
|
|
|
523
575
|
function isPromise (p) {
|
|
524
576
|
return !!p && typeof p.then === 'function'
|
|
525
577
|
}
|
|
578
|
+
|
|
579
|
+
function hypercoreCapability (initiator, handshakeHash, key, cap = b4a.alloc(32)) {
|
|
580
|
+
const ns = initiator ? NS_HYPERCORE_INITIATOR : NS_HYPERCORE_RESPONDER
|
|
581
|
+
sodium.crypto_generichash_batch(cap, [handshakeHash, key], ns)
|
|
582
|
+
return cap
|
|
583
|
+
}
|
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.21",
|
|
4
4
|
"description": "Hypercore 10",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -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",
|