hypercore 11.0.1 → 11.0.2
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 +8 -6
- package/lib/copy-prologue.js +1 -1
- package/lib/core.js +6 -4
- package/lib/multisig.js +4 -4
- package/lib/session-state.js +52 -18
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -207,7 +207,7 @@ class Hypercore extends EventEmitter {
|
|
|
207
207
|
}
|
|
208
208
|
|
|
209
209
|
const wait = opts.wait === false ? false : this.wait
|
|
210
|
-
const writable = opts.writable ===
|
|
210
|
+
const writable = opts.writable === undefined ? !this._readonly : opts.writable === true
|
|
211
211
|
const onwait = opts.onwait === undefined ? this.onwait : opts.onwait
|
|
212
212
|
const timeout = opts.timeout === undefined ? this.timeout : opts.timeout
|
|
213
213
|
const weak = opts.weak === undefined ? this.weak : opts.weak
|
|
@@ -245,7 +245,6 @@ class Hypercore extends EventEmitter {
|
|
|
245
245
|
|
|
246
246
|
_setupSession (parent) {
|
|
247
247
|
if (!this.keyPair) this.keyPair = parent.keyPair
|
|
248
|
-
this.writable = this._isWritable()
|
|
249
248
|
|
|
250
249
|
const s = parent.state
|
|
251
250
|
|
|
@@ -341,13 +340,13 @@ class Hypercore extends EventEmitter {
|
|
|
341
340
|
}
|
|
342
341
|
|
|
343
342
|
const parent = opts.parent || this.core
|
|
343
|
+
const checkout = opts.checkout === undefined ? -1 : opts.checkout
|
|
344
344
|
|
|
345
345
|
if (opts.atom) {
|
|
346
|
-
this.state = await parent.state.createSession(null,
|
|
346
|
+
this.state = await parent.state.createSession(null, checkout, false, opts.atom)
|
|
347
347
|
} else if (opts.name) {
|
|
348
348
|
// todo: need to make named sessions safe before ready
|
|
349
349
|
// atm we always copy the state in passCapabilities
|
|
350
|
-
const checkout = opts.checkout === undefined ? -1 : opts.checkout
|
|
351
350
|
const state = this.state
|
|
352
351
|
|
|
353
352
|
this.state = await parent.state.createSession(opts.name, checkout, !!opts.overwrite, null)
|
|
@@ -360,6 +359,8 @@ class Hypercore extends EventEmitter {
|
|
|
360
359
|
this.state = this.core.state.ref()
|
|
361
360
|
}
|
|
362
361
|
|
|
362
|
+
this.writable = this._isWritable()
|
|
363
|
+
|
|
363
364
|
if (this.snapshotted && this.core) this._updateSnapshot()
|
|
364
365
|
|
|
365
366
|
this.state.addSession(this)
|
|
@@ -404,8 +405,9 @@ class Hypercore extends EventEmitter {
|
|
|
404
405
|
}
|
|
405
406
|
|
|
406
407
|
_isWritable () {
|
|
407
|
-
if (this.
|
|
408
|
-
|
|
408
|
+
if (this._readonly) return false
|
|
409
|
+
if (this.state && !this.state.isDefault()) return true
|
|
410
|
+
return !!(this.keyPair && this.keyPair.secretKey)
|
|
409
411
|
}
|
|
410
412
|
|
|
411
413
|
close ({ error } = {}) {
|
package/lib/copy-prologue.js
CHANGED
package/lib/core.js
CHANGED
|
@@ -8,7 +8,7 @@ const BlockStore = require('./block-store')
|
|
|
8
8
|
const BitInterlude = require('./bit-interlude')
|
|
9
9
|
const Bitfield = require('./bitfield')
|
|
10
10
|
const RemoteBitfield = require('./remote-bitfield')
|
|
11
|
-
const { BAD_ARGUMENT, STORAGE_EMPTY, STORAGE_CONFLICT,
|
|
11
|
+
const { BAD_ARGUMENT, STORAGE_EMPTY, STORAGE_CONFLICT, INVALID_SIGNATURE, INVALID_CHECKSUM } = require('hypercore-errors')
|
|
12
12
|
const Verifier = require('./verifier')
|
|
13
13
|
const audit = require('./audit')
|
|
14
14
|
const copyPrologue = require('./copy-prologue')
|
|
@@ -374,21 +374,23 @@ module.exports = class Core {
|
|
|
374
374
|
|
|
375
375
|
async _validateCommit (state, treeLength) {
|
|
376
376
|
if (this.state.length > state.length) {
|
|
377
|
-
|
|
377
|
+
return false // TODO: partial commit in the future if possible
|
|
378
378
|
}
|
|
379
379
|
|
|
380
380
|
if (this.state.length > treeLength) {
|
|
381
381
|
for (const root of this.state.roots) {
|
|
382
382
|
const batchRoot = await state.tree.get(root.index)
|
|
383
383
|
if (batchRoot.size !== root.size || !b4a.equals(batchRoot.hash, root.hash)) {
|
|
384
|
-
|
|
384
|
+
return false
|
|
385
385
|
}
|
|
386
386
|
}
|
|
387
387
|
}
|
|
388
388
|
|
|
389
389
|
if (this.verifier === null) {
|
|
390
|
-
|
|
390
|
+
return false // easier to assert than upsert
|
|
391
391
|
}
|
|
392
|
+
|
|
393
|
+
return true
|
|
392
394
|
}
|
|
393
395
|
|
|
394
396
|
_verifyBatchUpgrade (batch, manifest) {
|
package/lib/multisig.js
CHANGED
|
@@ -21,7 +21,7 @@ function inflate (data) {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
async function partialSignature (core, signer, from, to = core.state.length, signature = core.state.signature) {
|
|
24
|
-
if (from > core.
|
|
24
|
+
if (from > core.state.length) return null
|
|
25
25
|
const nodes = to <= from ? null : await upgradeNodes(core, from, to)
|
|
26
26
|
|
|
27
27
|
if (signature.byteLength !== 64) signature = c.decode(multiSignature, signature).proofs[0].signature
|
|
@@ -35,10 +35,10 @@ async function partialSignature (core, signer, from, to = core.state.length, sig
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
async function upgradeNodes (core, from, to) {
|
|
38
|
-
const
|
|
38
|
+
const rx = core.state.storage.read()
|
|
39
39
|
const treeBatch = core.state.createTreeBatch()
|
|
40
|
-
const p = await core.tree.proof(
|
|
41
|
-
|
|
40
|
+
const p = await core.state.tree.proof(rx, treeBatch, { upgrade: { start: from, length: to - from } })
|
|
41
|
+
rx.tryFlush()
|
|
42
42
|
return (await p.settle()).upgrade.nodes
|
|
43
43
|
}
|
|
44
44
|
|
package/lib/session-state.js
CHANGED
|
@@ -35,6 +35,7 @@ module.exports = class SessionState {
|
|
|
35
35
|
const deps = this.storage.dependencies
|
|
36
36
|
this.dependencyLength = deps.length ? deps[deps.length - 1].length : Infinity
|
|
37
37
|
|
|
38
|
+
if (treeInfo.length < this.dependencyLength) this.dependencyLength = treeInfo.length
|
|
38
39
|
if (treeInfo.roots.length) this.setRoots(treeInfo.roots)
|
|
39
40
|
|
|
40
41
|
this.snapshotCompatLength = this.isSnapshot() ? this.length : -1
|
|
@@ -109,7 +110,8 @@ module.exports = class SessionState {
|
|
|
109
110
|
fork: this.fork,
|
|
110
111
|
roots: this.roots.slice(),
|
|
111
112
|
length: this.length,
|
|
112
|
-
prologue: this.prologue
|
|
113
|
+
prologue: this.prologue,
|
|
114
|
+
signature: this.signature
|
|
113
115
|
}
|
|
114
116
|
}
|
|
115
117
|
|
|
@@ -144,11 +146,11 @@ module.exports = class SessionState {
|
|
|
144
146
|
return s
|
|
145
147
|
}
|
|
146
148
|
|
|
147
|
-
updateDependency (
|
|
149
|
+
updateDependency (tx, length) {
|
|
148
150
|
const dependency = updateDependency(this, length)
|
|
149
151
|
if (dependency) {
|
|
150
152
|
this.dependencyLength = dependency.length
|
|
151
|
-
|
|
153
|
+
tx.setDependency(dependency)
|
|
152
154
|
}
|
|
153
155
|
|
|
154
156
|
return dependency
|
|
@@ -202,6 +204,8 @@ module.exports = class SessionState {
|
|
|
202
204
|
}
|
|
203
205
|
|
|
204
206
|
async _oncommit (src, bitfield) {
|
|
207
|
+
const currLength = this.length
|
|
208
|
+
|
|
205
209
|
this.fork = src.fork
|
|
206
210
|
this.length = src.length
|
|
207
211
|
this.roots = src.roots.slice()
|
|
@@ -229,11 +233,16 @@ module.exports = class SessionState {
|
|
|
229
233
|
this._moveToCore(src.core)
|
|
230
234
|
}
|
|
231
235
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
+
const truncated = (bitfield && bitfield.truncated !== -1)
|
|
237
|
+
? bitfield.truncated
|
|
238
|
+
: src.dependencyLength
|
|
239
|
+
|
|
240
|
+
if (truncated < currLength) {
|
|
241
|
+
this.ontruncate(tree, truncated, currLength, true)
|
|
242
|
+
if (!bitfield || bitfield.length === 0) return
|
|
236
243
|
}
|
|
244
|
+
|
|
245
|
+
this.onappend(tree, bitfield, true)
|
|
237
246
|
}
|
|
238
247
|
|
|
239
248
|
flushed () {
|
|
@@ -511,22 +520,40 @@ module.exports = class SessionState {
|
|
|
511
520
|
}
|
|
512
521
|
|
|
513
522
|
_updateBitfield (bitfield, flushed) {
|
|
523
|
+
if (!bitfield) return
|
|
524
|
+
|
|
514
525
|
const p = this._pendingBitfield
|
|
526
|
+
const b = bitfield
|
|
515
527
|
|
|
516
|
-
if (
|
|
517
|
-
if (
|
|
528
|
+
if (b.drop) {
|
|
529
|
+
if (p === null) {
|
|
530
|
+
this._pendingBitfield = { truncated: b.start, start: b.start, length: 0, drop: false }
|
|
531
|
+
return
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
if (p.drop) {
|
|
535
|
+
if (p.truncated !== b.start + b.length) throw INVALID_OPERATION('Atomic truncations must be contiguous')
|
|
536
|
+
p.truncated = b.start
|
|
537
|
+
return
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
if (b.start < p.start) throw INVALID_OPERATION('Atomic truncations must be contiguous')
|
|
541
|
+
p.length = b.start - p.start
|
|
542
|
+
|
|
543
|
+
if (p.length === 0) this._pendingBitfield = null
|
|
518
544
|
return
|
|
519
545
|
}
|
|
520
546
|
|
|
521
|
-
if (p
|
|
522
|
-
|
|
523
|
-
|
|
547
|
+
if (p === null) {
|
|
548
|
+
this._pendingBitfield = { truncated: -1, start: b.start, length: b.length, drop: false }
|
|
549
|
+
return
|
|
550
|
+
}
|
|
524
551
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
} else {
|
|
528
|
-
p.length = bitfield.start + bitfield.length - p.start
|
|
552
|
+
if (b.start !== p.start + p.length) {
|
|
553
|
+
throw INVALID_OPERATION('Atomic operations must be contiguous')
|
|
529
554
|
}
|
|
555
|
+
|
|
556
|
+
p.length += b.length
|
|
530
557
|
}
|
|
531
558
|
|
|
532
559
|
async _overwrite (source, fork, length, treeLength, signature, isDependent, shallow) {
|
|
@@ -670,7 +697,7 @@ module.exports = class SessionState {
|
|
|
670
697
|
await state.mutex.lock()
|
|
671
698
|
srcLocked = true
|
|
672
699
|
|
|
673
|
-
await this.core._validateCommit(state, treeLength)
|
|
700
|
+
if (!(await this.core._validateCommit(state, treeLength))) return null
|
|
674
701
|
|
|
675
702
|
if (this.length < length && !signature) {
|
|
676
703
|
if (!keyPair) keyPair = this.core.header.keyPair
|
|
@@ -729,6 +756,8 @@ module.exports = class SessionState {
|
|
|
729
756
|
head.fork = this.fork
|
|
730
757
|
head.rootHash = rootHash
|
|
731
758
|
|
|
759
|
+
if (length === this.length) head.signature = this.signature
|
|
760
|
+
|
|
732
761
|
return head
|
|
733
762
|
}
|
|
734
763
|
|
|
@@ -739,6 +768,10 @@ module.exports = class SessionState {
|
|
|
739
768
|
this.core = core
|
|
740
769
|
this.index = this.core.sessionStates.push(this) - 1
|
|
741
770
|
|
|
771
|
+
// storage was updated
|
|
772
|
+
const deps = this.storage.dependencies
|
|
773
|
+
this.dependencyLength = deps[deps.length - 1].length
|
|
774
|
+
|
|
742
775
|
for (let i = this.sessions.length - 1; i >= 0; i--) this.sessions[i].transferSession(this.core)
|
|
743
776
|
}
|
|
744
777
|
|
|
@@ -831,7 +864,8 @@ module.exports = class SessionState {
|
|
|
831
864
|
fork: this.fork,
|
|
832
865
|
roots: length === this.length ? this.roots.slice() : await tree.getRoots(length),
|
|
833
866
|
length,
|
|
834
|
-
prologue: this.prologue
|
|
867
|
+
prologue: this.prologue,
|
|
868
|
+
signature: length === this.length ? this.signature : null
|
|
835
869
|
}
|
|
836
870
|
|
|
837
871
|
const state = new SessionState(
|