hypercore 11.6.3 → 11.8.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
@@ -213,7 +213,7 @@ class Hypercore extends EventEmitter {
213
213
  throw SESSION_CLOSED('Cannot make sessions on a closing core')
214
214
  }
215
215
  if (opts.checkout !== undefined && !opts.name && !opts.atom) {
216
- throw new Error('Checkouts are only supported on atoms or named sessions')
216
+ throw ASSERTION('Checkouts are only supported on atoms or named sessions')
217
217
  }
218
218
 
219
219
  const wait = opts.wait === false ? false : this.wait
@@ -249,7 +249,7 @@ class Hypercore extends EventEmitter {
249
249
  }
250
250
 
251
251
  if (!isEncryptionProvider(encryption)) {
252
- throw new Error('Provider does not satisfy HypercoreEncryption interface')
252
+ throw ASSERTION('Provider does not satisfy HypercoreEncryption interface')
253
253
  }
254
254
 
255
255
  this.encryption = encryption
@@ -0,0 +1,126 @@
1
+ // this helper is for fully remote proofs, is like in a push notification where no other context exists
2
+
3
+ const { MerkleTree } = require('./merkle-tree.js')
4
+ const messages = require('./messages.js')
5
+ const b4a = require('b4a')
6
+ const c = require('compact-encoding')
7
+ const crypto = require('hypercore-crypto')
8
+ const flat = require('flat-tree')
9
+
10
+ class SlimSession {
11
+ constructor (storage, auth, head, roots) {
12
+ this.fork = head ? head.fork : 0
13
+ this.roots = roots
14
+ this.length = head ? head.length : 0
15
+ this.signature = head ? head.signature : null
16
+ this.ancestors = this.length
17
+ this.byteLength = 0
18
+ this.prologue = auth.manifest.prologue
19
+ this.storage = storage
20
+
21
+ for (let i = 0; i < roots.length; i++) this.byteLength += roots[i].size
22
+ }
23
+ }
24
+
25
+ module.exports = { verify, proof }
26
+
27
+ async function verify (storage, buffer, { referrer = null } = {}) {
28
+ const state = { buffer, start: 0, end: buffer.byteLength }
29
+
30
+ const discoveryKey = c.fixed32.decode(state)
31
+ const proof = messages.wire.data.decode(state)
32
+
33
+ const result = {
34
+ key: null,
35
+ discoveryKey,
36
+ newer: true,
37
+ length: 0,
38
+ proof,
39
+ block: null
40
+ }
41
+
42
+ const core = await storage.resume(discoveryKey)
43
+ if (core === null) return null
44
+
45
+ let rx = core.read()
46
+ const authPromise = rx.getAuth()
47
+ const headPromise = rx.getHead()
48
+ const referrerPromise = rx.getUserData('referrer')
49
+
50
+ rx.tryFlush()
51
+
52
+ const [auth, head, ref] = await Promise.all([authPromise, headPromise, referrerPromise])
53
+
54
+ if (auth === null) return null
55
+
56
+ if (referrer && (!ref || !b4a.equals(ref, referrer))) return null
57
+
58
+ rx = core.read()
59
+
60
+ const rootPromises = []
61
+
62
+ for (const index of flat.fullRoots(head ? 2 * head.length : 0)) {
63
+ rootPromises.push(rx.getTreeNode(index))
64
+ }
65
+
66
+ rx.tryFlush()
67
+
68
+ const roots = await Promise.all(rootPromises)
69
+ const length = head ? head.length : 0
70
+
71
+ if (!auth.manifest || !auth.manifest.signers.length) return null
72
+
73
+ const batch = await MerkleTree.verifyFullyRemote(new SlimSession(core, auth, head, roots), proof)
74
+ const publicKey = auth.manifest.signers[0].publicKey
75
+
76
+ let signable = null
77
+ let signature = null
78
+
79
+ if (auth.manifest.version === 0) {
80
+ signable = batch.signable(auth.manifest.signers[0].namespace)
81
+ signature = batch.signature
82
+ } else {
83
+ if (batch.signature[0] !== 1) return null
84
+ if (batch.signature[1] !== 0) return null
85
+
86
+ signable = batch.signable(auth.key)
87
+ signature = batch.signature.subarray(2)
88
+ }
89
+
90
+ if (!crypto.verify(signable, signature, publicKey)) {
91
+ return null
92
+ }
93
+
94
+ result.key = auth.key
95
+ result.discoveryKey = discoveryKey
96
+ result.newer = batch.length > length
97
+ result.length = batch.length
98
+ result.block = proof.block
99
+
100
+ return result
101
+ }
102
+
103
+ async function proof (sender, { index, block = null } = {}) {
104
+ const treeProof = await sender.proof({
105
+ block: block ? { index, nodes: 0 } : null,
106
+ upgrade: { start: 0, length: sender.length }
107
+ })
108
+
109
+ const proof = await treeProof.settle()
110
+
111
+ if (block) proof.block.value = block
112
+ proof.manifest = sender.core.header.manifest
113
+
114
+ const state = { buffer: null, start: 0, end: 0 }
115
+ const data = { request: 0, ...proof }
116
+
117
+ c.fixed32.preencode(state, sender.discoveryKey)
118
+ messages.wire.data.preencode(state, data)
119
+
120
+ state.buffer = b4a.allocUnsafe(state.end)
121
+
122
+ c.fixed32.encode(state, sender.discoveryKey)
123
+ messages.wire.data.encode(state, data)
124
+
125
+ return state.buffer
126
+ }
@@ -543,7 +543,12 @@ module.exports = class SessionState {
543
543
 
544
544
  tx.setHead(tree)
545
545
 
546
- if (this.isDefault()) await storeBitfieldRange(this.storage, tx, batch.ancestors, batch.length, true)
546
+ if (this.isDefault()) {
547
+ await storeBitfieldRange(this.storage, tx, batch.ancestors, batch.length, true)
548
+ if (this.length === this.core.header.hints.contiguousLength) {
549
+ tx.setHints({ contiguousLength: this.length + values.length })
550
+ }
551
+ }
547
552
 
548
553
  for (let i = 0; i < values.length; i++) {
549
554
  tx.putBlock(this.length + i, values[i])
package/lib/streams.js CHANGED
@@ -8,7 +8,7 @@ class ReadStream extends Readable {
8
8
  this.start = opts.start || 0
9
9
  this.end = typeof opts.end === 'number' ? opts.end : -1
10
10
  this.snapshot = !opts.live && opts.snapshot !== false
11
- this.live = !!opts.live
11
+ this.live = this.end === -1 ? !!opts.live : false
12
12
  }
13
13
 
14
14
  _open (cb) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypercore",
3
- "version": "11.6.3",
3
+ "version": "11.8.0",
4
4
  "description": "Hypercore is a secure, distributed append-only log",
5
5
  "main": "index.js",
6
6
  "scripts": {