hypercore 10.0.0-alpha.53 → 10.0.0-alpha.54

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.
Files changed (3) hide show
  1. package/index.js +18 -21
  2. package/lib/core.js +54 -27
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -312,8 +312,7 @@ module.exports = class Hypercore extends EventEmitter {
312
312
  crypto: this.crypto,
313
313
  legacy: opts.legacy,
314
314
  auth: opts.auth,
315
- onupdate: this._oncoreupdate.bind(this),
316
- oncontigupdate: this._oncorecontigupdate.bind(this)
315
+ onupdate: this._oncoreupdate.bind(this)
317
316
  })
318
317
 
319
318
  if (opts.userData) {
@@ -496,30 +495,38 @@ module.exports = class Hypercore extends EventEmitter {
496
495
 
497
496
  _oncoreupdate (status, bitfield, value, from) {
498
497
  if (status !== 0) {
499
- const truncated = (status & 0b10) !== 0
500
- const appended = (status & 0b01) !== 0
498
+ const truncatedNonSparse = (status & 0b1000) !== 0
499
+ const appendedNonSparse = (status & 0b0100) !== 0
500
+ const truncated = (status & 0b0010) !== 0
501
+ const appended = (status & 0b0001) !== 0
501
502
 
502
503
  if (truncated) {
503
504
  this.replicator.ontruncate(bitfield.start)
504
505
  }
505
506
 
507
+ if ((status & 0b0011) !== 0) {
508
+ this.replicator.onupgrade()
509
+ }
510
+
506
511
  for (let i = 0; i < this.sessions.length; i++) {
507
512
  const s = this.sessions[i]
508
513
 
509
514
  if (truncated) {
510
515
  if (s.cache) s.cache.clear()
511
- s.emit('truncate', bitfield.start, this.core.tree.fork)
516
+
512
517
  // If snapshotted, make sure to update our compat so we can fail gets
513
518
  if (s._snapshot && bitfield.start < s._snapshot.compatLength) s._snapshot.compatLength = bitfield.start
514
519
  }
515
520
 
516
- // For sparse sessions, immediately emit appends. Non-sparse sessions
517
- // are handled separately and only emit appends when their contiguous
518
- // length is updated.
519
- if (appended && s.sparse) s.emit('append')
520
- }
521
+ if (s.sparse ? truncated : truncatedNonSparse) {
522
+ s.emit('truncate', bitfield.start, this.core.tree.fork)
523
+ }
521
524
 
522
- this.replicator.onupgrade()
525
+ // For sparse sessions, immediately emit appends. If non-sparse, emit if contig length has updated
526
+ if (s.sparse ? appended : appendedNonSparse) {
527
+ s.emit('append')
528
+ }
529
+ }
523
530
  }
524
531
 
525
532
  if (bitfield) {
@@ -535,16 +542,6 @@ module.exports = class Hypercore extends EventEmitter {
535
542
  }
536
543
  }
537
544
 
538
- _oncorecontigupdate () {
539
- // For non-sparse sessions, emit appends only when the contiguous length is
540
- // updated.
541
- for (let i = 0; i < this.sessions.length; i++) {
542
- const s = this.sessions[i]
543
-
544
- if (!s.sparse) s.emit('append')
545
- }
546
- }
547
-
548
545
  _onpeerupdate (added, peer) {
549
546
  const name = added ? 'peer-add' : 'peer-remove'
550
547
 
package/lib/core.js CHANGED
@@ -9,9 +9,8 @@ const { BAD_ARGUMENT, STORAGE_EMPTY, STORAGE_CONFLICT, INVALID_SIGNATURE } = req
9
9
  const m = require('./messages')
10
10
 
11
11
  module.exports = class Core {
12
- constructor (header, crypto, oplog, tree, blocks, bitfield, auth, legacy, onupdate, oncontigupdate) {
12
+ constructor (header, crypto, oplog, tree, blocks, bitfield, auth, legacy, onupdate) {
13
13
  this.onupdate = onupdate
14
- this.oncontigupdate = oncontigupdate
15
14
  this.header = header
16
15
  this.crypto = crypto
17
16
  this.oplog = oplog
@@ -27,8 +26,6 @@ module.exports = class Core {
27
26
  this._verifiesFlushed = null
28
27
  this._mutex = new Mutex()
29
28
  this._legacy = legacy
30
-
31
- this._updateContiguousLength(header.contiguousLength)
32
29
  }
33
30
 
34
31
  static async open (storage, opts = {}) {
@@ -134,6 +131,11 @@ module.exports = class Core {
134
131
  await bitfield.clear()
135
132
  }
136
133
 
134
+ // compat from earlier version that do not store contig length
135
+ if (header.contiguousLength === 0) {
136
+ while (bitfield.get(header.contiguousLength)) header.contiguousLength++
137
+ }
138
+
137
139
  const auth = opts.auth || this.createAuth(crypto, header.signer)
138
140
 
139
141
  for (const e of entries) {
@@ -149,6 +151,7 @@ module.exports = class Core {
149
151
 
150
152
  if (e.bitfield) {
151
153
  bitfield.setRange(e.bitfield.start, e.bitfield.length, !e.bitfield.drop)
154
+ updateContig(header, e.bitfield, bitfield)
152
155
  }
153
156
 
154
157
  if (e.treeUpgrade) {
@@ -165,7 +168,7 @@ module.exports = class Core {
165
168
  }
166
169
  }
167
170
 
168
- return new this(header, crypto, oplog, tree, blocks, bitfield, auth, !!opts.legacy, opts.onupdate || noop, opts.oncontigupdate || noop)
171
+ return new this(header, crypto, oplog, tree, blocks, bitfield, auth, !!opts.legacy, opts.onupdate || noop)
169
172
  }
170
173
 
171
174
  _shouldFlush () {
@@ -196,17 +199,6 @@ module.exports = class Core {
196
199
  await this.blocks.put(index, value, byteOffset)
197
200
  }
198
201
 
199
- _updateContiguousLength (index, length = 0) {
200
- if (index === this.header.contiguousLength) {
201
- let i = this.header.contiguousLength + length
202
-
203
- while (this.bitfield.get(i)) i++
204
-
205
- this.header.contiguousLength = i
206
- this.oncontigupdate()
207
- }
208
- }
209
-
210
202
  async userData (key, value) {
211
203
  // TODO: each oplog append can set user data, so we should have a way
212
204
  // to just hitch a ride on one of the other ongoing appends?
@@ -286,12 +278,12 @@ module.exports = class Core {
286
278
  this.bitfield.setRange(batch.ancestors, batch.length - batch.ancestors, true)
287
279
  batch.commit()
288
280
 
289
- this.header.contiguousLength = batch.length
290
- this.oncontigupdate()
291
281
  this.header.tree.length = batch.length
292
282
  this.header.tree.rootHash = hash
293
283
  this.header.tree.signature = batch.signature
294
- this.onupdate(0b01, entry.bitfield, null, null)
284
+
285
+ const status = 0b0001 | updateContig(this.header, entry.bitfield, this.bitfield)
286
+ this.onupdate(status, entry.bitfield, null, null)
295
287
 
296
288
  if (this._shouldFlush()) await this._flushOplog()
297
289
 
@@ -329,9 +321,11 @@ module.exports = class Core {
329
321
 
330
322
  await this.oplog.append([entry], false)
331
323
 
324
+ let status = 0b0001
325
+
332
326
  if (bitfield) {
333
327
  this.bitfield.set(bitfield.start, true)
334
- this._updateContiguousLength(bitfield.start, bitfield.length)
328
+ status |= updateContig(this.header, bitfield, this.bitfield)
335
329
  }
336
330
 
337
331
  batch.commit()
@@ -340,7 +334,8 @@ module.exports = class Core {
340
334
  this.header.tree.length = batch.length
341
335
  this.header.tree.rootHash = batch.rootHash
342
336
  this.header.tree.signature = batch.signature
343
- this.onupdate(0b01, bitfield, value, from)
337
+
338
+ this.onupdate(status, bitfield, value, from)
344
339
 
345
340
  if (this._shouldFlush()) await this._flushOplog()
346
341
  } finally {
@@ -387,14 +382,16 @@ module.exports = class Core {
387
382
  continue
388
383
  }
389
384
 
385
+ let status = 0
386
+
390
387
  if (bitfield) {
391
388
  this.bitfield.set(bitfield.start, true)
392
- this._updateContiguousLength(bitfield.start, bitfield.length)
389
+ status = updateContig(this.header, bitfield, this.bitfield)
393
390
  }
394
391
 
395
392
  batch.commit()
396
393
 
397
- this.onupdate(0, bitfield, value, from)
394
+ this.onupdate(status, bitfield, value, from)
398
395
  }
399
396
 
400
397
  if (this._shouldFlush()) await this._flushOplog()
@@ -472,15 +469,15 @@ module.exports = class Core {
472
469
  addReorgHint(this.header.hints.reorgs, this.tree, batch)
473
470
  batch.commit()
474
471
 
475
- const appended = batch.length > batch.ancestors
472
+ const contigStatus = updateContig(this.header, entry.bitfield, this.bitfield)
473
+ const status = ((batch.length > batch.ancestors) ? 0b0011 : 0b0010) | contigStatus
476
474
 
477
- this.header.contiguousLength = Math.min(batch.ancestors, this.header.contiguousLength)
478
- this.oncontigupdate()
479
475
  this.header.tree.fork = batch.fork
480
476
  this.header.tree.length = batch.length
481
477
  this.header.tree.rootHash = batch.hash()
482
478
  this.header.tree.signature = batch.signature
483
- this.onupdate(appended ? 0b11 : 0b10, entry.bitfield, null, from)
479
+
480
+ this.onupdate(status, entry.bitfield, null, from)
484
481
 
485
482
  // TODO: there is a bug in the merkle tree atm where it cannot handle unflushed
486
483
  // truncates if we append or download anything after the truncation point later on
@@ -501,6 +498,36 @@ module.exports = class Core {
501
498
  }
502
499
  }
503
500
 
501
+ function updateContig (header, upd, bitfield) {
502
+ const end = upd.start + upd.length
503
+
504
+ let c = header.contiguousLength
505
+
506
+ if (upd.drop) {
507
+ // If we dropped a block in the current contig range, "downgrade" it
508
+ if (c <= end && c > upd.start) {
509
+ c = upd.start
510
+ }
511
+ } else {
512
+ if (c <= end && c >= upd.start) {
513
+ c = end
514
+ while (bitfield.get(c)) c++
515
+ }
516
+ }
517
+
518
+ if (c === header.contiguousLength) {
519
+ return 0b0000
520
+ }
521
+
522
+ if (c > header.contiguousLength) {
523
+ header.contiguousLength = c
524
+ return 0b0100
525
+ }
526
+
527
+ header.contiguousLength = c
528
+ return 0b1000
529
+ }
530
+
504
531
  function addReorgHint (list, tree, batch) {
505
532
  if (tree.length === 0 || tree.fork === batch.fork) return
506
533
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypercore",
3
- "version": "10.0.0-alpha.53",
3
+ "version": "10.0.0-alpha.54",
4
4
  "description": "Hypercore 10",
5
5
  "main": "index.js",
6
6
  "scripts": {