hypercore 11.0.26 → 11.0.28

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.
@@ -134,19 +134,32 @@ module.exports = class SessionState {
134
134
  rx.tryFlush()
135
135
  const [head, auth] = await Promise.all([headPromise, authPromise])
136
136
 
137
+ const fork = head ? head.fork : 0
138
+ const length = head ? head.length : 0
139
+
137
140
  rx = storage.read()
138
141
  const rootPromises = []
139
- for (const r of flat.fullRoots(head.length * 2)) {
142
+ for (const r of flat.fullRoots(length * 2)) {
140
143
  rootPromises.push(rx.getTreeNode(r))
141
144
  }
142
145
 
143
146
  rx.tryFlush()
147
+
148
+ const roots = await Promise.all(rootPromises)
149
+
150
+ // dbl check if we are hitting an regression from earler
151
+ for (const root of roots) {
152
+ if (root === null) {
153
+ throw new Error('Bad snapshot from atomized session, id = ' + this.core.id + ' length = ' + length + ' fork = ' + fork)
154
+ }
155
+ }
156
+
144
157
  return {
145
- fork: head.fork,
146
- roots: await Promise.all(rootPromises),
147
- length: head.length,
158
+ fork,
159
+ roots,
160
+ length,
148
161
  prologue: auth.manifest && auth.manifest.prologue,
149
- signature: head.signature
162
+ signature: head && head.signature
150
163
  }
151
164
  }
152
165
 
@@ -184,6 +197,7 @@ module.exports = class SessionState {
184
197
 
185
198
  async snapshot () {
186
199
  const storage = this.storage.snapshot()
200
+ const treeInfo = await this.getFlushedTreeInfo(storage)
187
201
 
188
202
  const s = new SessionState(
189
203
  this.core,
@@ -191,7 +205,7 @@ module.exports = class SessionState {
191
205
  storage,
192
206
  this.blocks,
193
207
  this.tree.clone(storage),
194
- await this.getFlushedTreeInfo(storage),
208
+ treeInfo,
195
209
  this.name
196
210
  )
197
211
 
@@ -447,7 +461,7 @@ module.exports = class SessionState {
447
461
  async _truncate (storage, batch) {
448
462
  storage.deleteBlockRange(batch.ancestors, batch.treeLength)
449
463
 
450
- if (batch.commitable()) batch.commit(storage)
464
+ assert(batch.commitable(), 'Batch must be commitable')
451
465
 
452
466
  const tree = {
453
467
  fork: batch.fork,
@@ -456,7 +470,8 @@ module.exports = class SessionState {
456
470
  signature: batch.signature
457
471
  }
458
472
 
459
- if (tree) storage.setHead(tree)
473
+ storage.setHead(tree)
474
+ batch.commit(storage)
460
475
 
461
476
  const truncated = batch.length < this.flushedLength()
462
477
  const dependency = truncated ? updateDependency(this, batch.length, true) : null
@@ -667,6 +682,10 @@ module.exports = class SessionState {
667
682
  const roots = await Promise.all(rootPromises)
668
683
  const truncating = sharedLength < origLength
669
684
 
685
+ for (const node of roots) {
686
+ if (node === null) throw new INVALID_OPERATION('Invalid catchup length, tree nodes not available')
687
+ }
688
+
670
689
  const fork = truncating ? this.fork + 1 : this.fork
671
690
 
672
691
  // overwrite it atm, TODO: keep what we can connect to the tree
@@ -706,7 +725,7 @@ module.exports = class SessionState {
706
725
  }
707
726
  }
708
727
 
709
- async _overwrite (source, fork, length, treeLength, signature, isDependent, shallow) {
728
+ async _overwrite (source, fork, length, treeLength, signature) {
710
729
  const blockPromises = []
711
730
  const treePromises = []
712
731
  const rootPromises = []
@@ -717,16 +736,14 @@ module.exports = class SessionState {
717
736
  rootPromises.push(rx.getTreeNode(root))
718
737
  }
719
738
 
720
- if (shallow !== true) {
721
- for (const index of flat.patch(treeLength * 2, length * 2)) {
722
- treePromises.push(rx.getTreeNode(index))
723
- }
739
+ for (const index of flat.patch(treeLength * 2, length * 2)) {
740
+ treePromises.push(rx.getTreeNode(index))
741
+ }
724
742
 
725
- for (let i = treeLength; i < length; i++) {
726
- treePromises.push(rx.getTreeNode(i * 2))
727
- treePromises.push(rx.getTreeNode(i * 2 + 1))
728
- blockPromises.push(rx.getBlock(i))
729
- }
743
+ for (let i = treeLength; i < length; i++) {
744
+ treePromises.push(rx.getTreeNode(i * 2))
745
+ treePromises.push(rx.getTreeNode(i * 2 + 1))
746
+ blockPromises.push(rx.getBlock(i))
730
747
  }
731
748
 
732
749
  rx.tryFlush()
@@ -754,6 +771,9 @@ module.exports = class SessionState {
754
771
  tx.deleteBlockRange(treeLength, this.length)
755
772
  }
756
773
 
774
+ for (const root of roots) tx.putTreeNode(root)
775
+
776
+ // no nodes will be copied in shallow mode
757
777
  for (const node of nodes) {
758
778
  if (node !== null) tx.putTreeNode(node)
759
779
  }
@@ -803,8 +823,6 @@ module.exports = class SessionState {
803
823
 
804
824
  if (upgraded) tx.setHead(tree)
805
825
 
806
- const dependency = isDependent ? updateDependency(this, length, true) : null
807
-
808
826
  const flushed = await this.flush()
809
827
 
810
828
  this.fork = tree.fork
@@ -812,39 +830,10 @@ module.exports = class SessionState {
812
830
  this.length = length
813
831
  this.signature = signature
814
832
 
815
- if (dependency) this.storage.updateDependencyLength(dependency.length, true)
816
-
817
833
  return { tree, flushed }
818
834
  }
819
835
 
820
- async overwrite (state, { length = state.tree.length, treeLength = state.flushedLength(), shallow = false } = {}) {
821
- assert(!this.isDefault(), 'Cannot overwrite signed state') // TODO: make this check better
822
-
823
- await this.mutex.lock()
824
-
825
- try {
826
- const origLength = this.length
827
- const fork = treeLength < origLength ? this.fork + 1 : this.fork
828
-
829
- const { tree, flushed } = await this._overwrite(state, fork, length, treeLength, null, state === this.core.state, shallow)
830
-
831
- const bitfield = { start: treeLength, length: tree.length - treeLength, drop: false }
832
-
833
- if (treeLength < origLength) this.ontruncate(tree, treeLength, origLength, flushed)
834
- if (treeLength < tree.length) this.onappend(tree, bitfield, flushed)
835
-
836
- return {
837
- length: this.length,
838
- byteLength: this.byteLength
839
- }
840
- } finally {
841
- this._clearActiveBatch()
842
- this.updating = false
843
- this.mutex.unlock()
844
- }
845
- }
846
-
847
- async commit (state, { signature, keyPair, length = state.length, treeLength = state.flushedLength(), overwrite = false } = {}) {
836
+ async commit (state, { signature, keyPair, length = state.length, treeLength = -1, overwrite = false } = {}) {
848
837
  assert(this.isDefault() || (this.parent && this.parent.isDefault()), 'Can only commit into default state')
849
838
 
850
839
  let srcLocked = false
@@ -854,6 +843,8 @@ module.exports = class SessionState {
854
843
  await state.mutex.lock()
855
844
  srcLocked = true
856
845
 
846
+ if (treeLength === -1) treeLength = state.flushedLength()
847
+
857
848
  if (!(await this.core._validateCommit(state, treeLength))) return null
858
849
  if (this.length > length) return null
859
850
 
@@ -864,7 +855,7 @@ module.exports = class SessionState {
864
855
  signature = this.core.verifier.sign(batch, keyPair)
865
856
  }
866
857
 
867
- const { tree, flushed } = await this._overwrite(state, this.fork, length, treeLength, signature, false, false)
858
+ const { tree, flushed } = await this._overwrite(state, this.fork, length, treeLength, signature)
868
859
 
869
860
  // gc blocks from source
870
861
  if (treeLength < length) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypercore",
3
- "version": "11.0.26",
3
+ "version": "11.0.28",
4
4
  "description": "Hypercore is a secure, distributed append-only log",
5
5
  "main": "index.js",
6
6
  "scripts": {