hypercore 11.34.0 → 11.35.0

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 CHANGED
@@ -23,7 +23,8 @@ const Download = require('./lib/download')
23
23
  const DefaultEncryption = require('./lib/default-encryption')
24
24
  const caps = require('./lib/caps')
25
25
  const Replicator = require('./lib/replicator')
26
- const { manifestHash, createManifest } = require('./lib/verifier')
26
+ const Verifier = require('./lib/verifier')
27
+ const { manifestHash, createManifest, encodeManifest } = Verifier
27
28
  const { ReadStream, WriteStream, ByteStream } = require('./lib/streams')
28
29
  const { MerkleTree } = require('./lib/merkle-tree')
29
30
  const { proof, verify } = require('./lib/fully-remote-proof')
@@ -35,7 +36,8 @@ const {
35
36
  SESSION_NOT_WRITABLE,
36
37
  SNAPSHOT_NOT_AVAILABLE,
37
38
  DECODING_ERROR,
38
- REQUEST_CANCELLED
39
+ REQUEST_CANCELLED,
40
+ INVALID_CHECKSUM
39
41
  } = require('hypercore-errors')
40
42
 
41
43
  // Hypercore actually does not have any notion of max/min block sizes
@@ -130,11 +132,29 @@ class Hypercore extends EventEmitter {
130
132
 
131
133
  static key(manifest, { compat, version, namespace } = {}) {
132
134
  if (b4a.isBuffer(manifest)) {
133
- manifest = { version, signers: [{ publicKey: manifest, namespace }] }
135
+ manifest =
136
+ manifest.byteLength === 32
137
+ ? { version, signers: [{ publicKey: manifest, namespace }] }
138
+ : this.parseManifest(manifest)
134
139
  }
135
140
  return compat ? manifest.signers[0].publicKey : manifestHash(createManifest(manifest))
136
141
  }
137
142
 
143
+ static parseManifest(manifest, key) {
144
+ const parsed = createManifest(manifest)
145
+ if (parsed === null) return null
146
+
147
+ if (parsed.quorum > parsed.signers.length) {
148
+ throw BAD_ARGUMENT('Quorum should not be higher than the number of signers')
149
+ }
150
+
151
+ if (key && !Verifier.isValidManifest(key, parsed)) {
152
+ throw INVALID_CHECKSUM('Manifest does not hash to provided key')
153
+ }
154
+
155
+ return parsed
156
+ }
157
+
138
158
  static discoveryKey(key) {
139
159
  return crypto.discoveryKey(key)
140
160
  }
@@ -453,7 +473,7 @@ class Hypercore extends EventEmitter {
453
473
  }
454
474
 
455
475
  if (opts.manifest && !this.core.header.manifest) {
456
- await this.core.setManifest(createManifest(opts.manifest))
476
+ await this.core.setManifest(opts.manifest)
457
477
  }
458
478
 
459
479
  this.core.replicator.updateActivity(this._active ? 1 : 0)
@@ -606,6 +626,11 @@ class Hypercore extends EventEmitter {
606
626
  return this.core === null ? null : this.core.manifest
607
627
  }
608
628
 
629
+ getManifest({ raw = false } = {}) {
630
+ if (this.manifest === null) return null
631
+ return raw ? encodeManifest(this.manifest) : this.manifest
632
+ }
633
+
609
634
  get length() {
610
635
  if (this._snapshot) return this._snapshot.length
611
636
  return this.opened === false ? 0 : this.state.length
package/lib/core.js CHANGED
@@ -259,15 +259,14 @@ module.exports = class Core {
259
259
  }
260
260
 
261
261
  if (opts.manifest) {
262
+ const manifest = Verifier.createManifest(opts.manifest)
263
+
262
264
  // if we provide a manifest and no key, verify that the stored key is the same
263
- if (
264
- !opts.key &&
265
- !Verifier.isValidManifest(header.key, Verifier.createManifest(opts.manifest))
266
- ) {
265
+ if (!opts.key && !Verifier.isValidManifest(header.key, manifest)) {
267
266
  throw STORAGE_CONFLICT('Manifest does not hash to provided key', this.discoveryKey)
268
267
  }
269
268
 
270
- if (!header.manifest) header.manifest = opts.manifest
269
+ if (!header.manifest) header.manifest = manifest
271
270
  }
272
271
 
273
272
  if (opts.key && !b4a.equals(header.key, opts.key)) {
@@ -393,12 +392,14 @@ module.exports = class Core {
393
392
 
394
393
  try {
395
394
  if (manifest && this.header.manifest === null) {
395
+ manifest = Verifier.createManifest(manifest)
396
+
396
397
  if (!Verifier.isValidManifest(this.header.key, manifest)) {
397
398
  throw INVALID_CHECKSUM('Manifest hash does not match', this.discoveryKey)
398
399
  }
399
400
 
400
401
  const tx = this.state.createWriteBatch()
401
- this._setManifest(tx, Verifier.createManifest(manifest), null)
402
+ this._setManifest(tx, manifest, null)
402
403
  await this.state.flush()
403
404
  }
404
405
  } finally {
package/lib/replicator.js CHANGED
@@ -1749,6 +1749,17 @@ class Peer {
1749
1749
  return false
1750
1750
  }
1751
1751
 
1752
+ _addLastRangeBatch(r, start, end) {
1753
+ const { WANT_BATCH } = w
1754
+
1755
+ const next = this.core.bitfield.findLast(false, end - 1)
1756
+ if (next === -1 || next < start) return false
1757
+
1758
+ const b = (next - (next & (WANT_BATCH - 1))) / WANT_BATCH
1759
+
1760
+ return r.addBatch(b)
1761
+ }
1762
+
1752
1763
  _populateRangeBatches(r) {
1753
1764
  const { WANT_BATCH } = w
1754
1765
  for (let i = r.batches.length - 1; i >= 0; i--) {
@@ -1764,10 +1775,13 @@ class Peer {
1764
1775
  r.removeBatch(b)
1765
1776
  }
1766
1777
 
1767
- while (r.batches.length < 3) {
1768
- const end = r.end === -1 ? this.core.state.length : r.end
1769
- if (end <= r.start) return
1778
+ const end = r.end === -1 ? this.core.state.length : r.end
1779
+ if (end <= r.start) return
1770
1780
 
1781
+ // always keep the last batch in the range selected
1782
+ if (r.batches.length < 3) this._addLastRangeBatch(r, r.start, end)
1783
+
1784
+ while (r.batches.length < 3) {
1771
1785
  const len = end - r.start
1772
1786
  const off = r.start + (r.linear ? 0 : Math.floor(Math.random() * len))
1773
1787
 
package/lib/verifier.js CHANGED
@@ -214,6 +214,8 @@ module.exports = class Verifier {
214
214
  static createManifest(inp) {
215
215
  if (!inp) return null
216
216
 
217
+ if (b4a.isBuffer(inp)) return Verifier.decodeManifest(inp)
218
+
217
219
  if (inp.quorum && inp.quorum < 0) throw BAD_ARGUMENT('Quorum cannot be negative')
218
220
  if (inp.quorum && inp.signers && inp.quorum > inp.signers.length) {
219
221
  throw BAD_ARGUMENT('Quorum should not be higher than the number of signers')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypercore",
3
- "version": "11.34.0",
3
+ "version": "11.35.0",
4
4
  "description": "Hypercore is a secure, distributed append-only log",
5
5
  "main": "index.js",
6
6
  "scripts": {