hypercore 10.0.0-alpha.23 → 10.0.0-alpha.24

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/README.md CHANGED
@@ -212,6 +212,12 @@ Buffer containing the public key identifying this core.
212
212
 
213
213
  Populated after `ready` has been emitted. Will be `null` before the event.
214
214
 
215
+ #### `core.keyPair`
216
+
217
+ Object containing buffers of the core's public and secret key
218
+
219
+ Populated after `ready` has been emitted. Will be `null` before the event.
220
+
215
221
  #### `core.discoveryKey`
216
222
 
217
223
  Buffer containing a key derived from the core's public key.
@@ -274,6 +280,6 @@ socket.pipe(localCore.replicate(true)).pipe(socket)
274
280
 
275
281
  Emitted when the core has been appended to (i.e. has a new length / byteLength), either locally or remotely.
276
282
 
277
- #### `core.on('truncate')`
283
+ #### `core.on('truncate', ancestors, forkId)`
278
284
 
279
285
  Emitted when the core has been truncated, either locally or remotely.
package/index.js CHANGED
@@ -58,6 +58,7 @@ module.exports = class Hypercore extends EventEmitter {
58
58
  this.encodeBatch = null
59
59
 
60
60
  this.key = key || null
61
+ this.keyPair = null
61
62
  this.discoveryKey = null
62
63
  this.readable = true
63
64
  this.writable = false
@@ -245,11 +246,13 @@ module.exports = class Hypercore extends EventEmitter {
245
246
  }
246
247
 
247
248
  this.replicator = new Replicator(this.core, {
248
- onupdate: this._onpeerupdate.bind(this)
249
+ onupdate: this._onpeerupdate.bind(this),
250
+ onupload: this._onupload.bind(this)
249
251
  })
250
252
 
251
253
  this.discoveryKey = this.crypto.discoveryKey(this.core.header.signer.publicKey)
252
254
  this.key = this.core.header.signer.publicKey
255
+ this.keyPair = this.core.header.signer
253
256
 
254
257
  if (!this.encryption && opts.encryptionKey) {
255
258
  this.encryption = new BlockEncryption(opts.encryptionKey, this.key)
@@ -330,12 +333,20 @@ module.exports = class Hypercore extends EventEmitter {
330
333
  return this.opening
331
334
  }
332
335
 
336
+ _onupload (index, value, from) {
337
+ const byteLength = value.byteLength - this.padding
338
+
339
+ for (let i = 0; i < this.sessions.length; i++) {
340
+ this.sessions[i].emit('upload', index, byteLength, from)
341
+ }
342
+ }
343
+
333
344
  _oncoreupdate (status, bitfield, value, from) {
334
345
  if (status !== 0) {
335
346
  for (let i = 0; i < this.sessions.length; i++) {
336
347
  if ((status & 0b10) !== 0) {
337
348
  if (this.cache) this.cache.clear()
338
- this.sessions[i].emit('truncate', this.core.tree.fork)
349
+ this.sessions[i].emit('truncate', bitfield.start, this.core.tree.fork)
339
350
  }
340
351
  if ((status & 0b01) !== 0) {
341
352
  this.sessions[i].emit('append')
package/lib/messages.js CHANGED
@@ -256,16 +256,25 @@ exports.info = {
256
256
  preencode (state, i) {
257
257
  c.uint.preencode(state, i.length)
258
258
  c.uint.preencode(state, i.fork)
259
+ c.uint.preencode(state, 1) // flags
259
260
  },
260
261
  encode (state, i) {
261
262
  c.uint.encode(state, i.length)
262
263
  c.uint.encode(state, i.fork)
264
+ c.uint.encode(state, (i.uploading ? 1 : 0) | (i.downloading ? 2 : 0))
263
265
  },
264
266
  decode (state) {
265
- return {
267
+ const i = {
266
268
  length: c.uint.decode(state),
267
- fork: c.uint.decode(state)
269
+ fork: c.uint.decode(state),
270
+ uploading: true,
271
+ downloading: true
268
272
  }
273
+ if (state.end <= state.start) return i // backwards compat with prev alphas
274
+ const flags = c.uint.decode(state)
275
+ i.uploading = (flags & 1) !== 0
276
+ i.downloading = (flags & 2) !== 0
277
+ return i
269
278
  }
270
279
  }
271
280
 
package/lib/protocol.js CHANGED
@@ -136,11 +136,34 @@ class Peer {
136
136
  this.resend = false
137
137
  this.state = state
138
138
  this.extensions = new Map()
139
+ this.uploading = true
140
+ this.downloading = true
139
141
  this.destroyed = false
140
142
 
141
143
  this._destroyer = this._safeDestroy.bind(this)
142
144
  }
143
145
 
146
+ setUploading (uploading) {
147
+ if (uploading === this.uploading) return
148
+ this.uploading = uploading
149
+ this._sendInfo()
150
+ }
151
+
152
+ setDownloading (downloading) {
153
+ if (downloading === this.downloading) return
154
+ this.downloading = downloading
155
+ this._sendInfo()
156
+ }
157
+
158
+ _sendInfo () {
159
+ this.info({
160
+ length: this.handlers.core.tree.length,
161
+ fork: this.handlers.core.tree.fork,
162
+ uploading: this.uploading,
163
+ downloading: this.downloading
164
+ })
165
+ }
166
+
144
167
  onmessage (type, state) {
145
168
  const handlers = this.handlers
146
169
 
package/lib/replicator.js CHANGED
@@ -14,6 +14,8 @@ class RemoteState {
14
14
  this.bitfield = new RemoteBitfield()
15
15
  this.length = 0
16
16
  this.fork = 0
17
+ this.uploading = true
18
+ this.downloading = true
17
19
  }
18
20
  }
19
21
 
@@ -241,6 +243,7 @@ class RequestPool {
241
243
 
242
244
  update (peer) {
243
245
  if (peer.state.inflight >= peer.state.maxInflight) return false
246
+ if (peer.downloading === false || peer.state.uploading === false) return false
244
247
  if (this.paused) return false
245
248
 
246
249
  if (peer.state.fork > this.core.tree.fork) {
@@ -624,13 +627,14 @@ class RequestPool {
624
627
  }
625
628
 
626
629
  module.exports = class Replicator {
627
- constructor (core, { onupdate }) {
630
+ constructor (core, { onupdate, onupload }) {
628
631
  this.core = core
629
632
  this.peers = []
630
633
  this.requests = new RequestPool(this, core)
631
634
  this.updating = null
632
635
  this.pendingPeers = new Set()
633
636
  this.onupdate = onupdate
637
+ this.onupload = onupload
634
638
  }
635
639
 
636
640
  static createProtocol (noiseStream, opts) {
@@ -659,8 +663,14 @@ module.exports = class Replicator {
659
663
  }
660
664
 
661
665
  broadcastInfo () {
662
- const msg = { length: this.core.tree.length, fork: this.core.tree.fork }
663
- for (const peer of this.peers) peer.info(msg)
666
+ for (const peer of this.peers) {
667
+ peer.info({
668
+ length: this.core.tree.length,
669
+ fork: this.core.tree.fork,
670
+ uploading: peer.uploading,
671
+ downloading: peer.downloading
672
+ })
673
+ }
664
674
  this.updateAll()
665
675
  }
666
676
 
@@ -738,7 +748,12 @@ module.exports = class Replicator {
738
748
  this.peers.push(peer)
739
749
  this.onupdate(true, peer)
740
750
 
741
- peer.info({ length: this.core.tree.length, fork: this.core.tree.fork })
751
+ peer.info({
752
+ length: this.core.tree.length,
753
+ fork: this.core.tree.fork,
754
+ uploading: peer.uploading,
755
+ downloading: peer.downloading
756
+ })
742
757
 
743
758
  // YOLO send over all the pages for now
744
759
  const p = pages(this.core)
@@ -753,12 +768,14 @@ module.exports = class Replicator {
753
768
  // This is a no-op because there isn't any state to dealloc currently
754
769
  }
755
770
 
756
- oninfo ({ length, fork }, peer) {
771
+ oninfo ({ length, fork, uploading, downloading }, peer) {
757
772
  const len = peer.state.length
758
773
  const forked = peer.state.fork !== fork
759
774
 
760
775
  peer.state.length = length
761
776
  peer.state.fork = fork
777
+ peer.state.downloading = downloading
778
+ peer.state.uploading = uploading
762
779
 
763
780
  if (forked) {
764
781
  for (let i = peer.state.length; i < len; i++) {
@@ -814,11 +831,13 @@ module.exports = class Replicator {
814
831
  async onrequest (req, peer) {
815
832
  const fork = req.fork || peer.state.fork
816
833
  if (fork !== this.core.tree.fork) return
834
+ if (!peer.uploading) return
817
835
 
818
836
  const proof = await this.core.tree.proof(req)
819
837
 
820
838
  if (req.block && req.block.value) {
821
839
  proof.block.value = await this.core.blocks.get(req.block.index)
840
+ this.onupload(req.block.index, proof.block.value, peer)
822
841
  }
823
842
 
824
843
  peer.data(proof)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypercore",
3
- "version": "10.0.0-alpha.23",
3
+ "version": "10.0.0-alpha.24",
4
4
  "description": "Hypercore 10",
5
5
  "main": "index.js",
6
6
  "scripts": {