corestore 6.0.0-alpha.4 → 6.0.1-alpha.10

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
@@ -1,7 +1,9 @@
1
1
  const { EventEmitter } = require('events')
2
+ const safetyCatch = require('safety-catch')
2
3
  const crypto = require('hypercore-crypto')
3
4
  const sodium = require('sodium-universal')
4
5
  const Hypercore = require('hypercore')
6
+ const b4a = require('b4a')
5
7
 
6
8
  const KeyManager = require('./lib/keys')
7
9
 
@@ -22,9 +24,10 @@ module.exports = class Corestore extends EventEmitter {
22
24
 
23
25
  this._namespace = opts._namespace || DEFAULT_NAMESPACE
24
26
  this._replicationStreams = opts._streams || []
27
+ this._streamSessions = opts._streamSessions || new Map()
25
28
 
26
29
  this._opening = opts._opening ? opts._opening.then(() => this._open()) : this._open()
27
- this._opening.catch(noop)
30
+ this._opening.catch(safetyCatch)
28
31
  this.ready = () => this._opening
29
32
  }
30
33
 
@@ -37,11 +40,11 @@ module.exports = class Corestore extends EventEmitter {
37
40
  }
38
41
 
39
42
  async _generateKeys (opts) {
40
- if (opts.discoveryKey) {
43
+ if (opts._discoveryKey) {
41
44
  return {
42
45
  keyPair: null,
43
46
  sign: null,
44
- discoveryKey: opts.discoveryKey
47
+ discoveryKey: opts._discoveryKey
45
48
  }
46
49
  }
47
50
  if (!opts.name) {
@@ -65,15 +68,22 @@ module.exports = class Corestore extends EventEmitter {
65
68
  }
66
69
  }
67
70
 
68
- async _postload (core) {
69
- const name = await core.getUserData(USERDATA_NAME_KEY)
71
+ _getPrereadyUserData (core, key) {
72
+ for (const { key: savedKey, value } of core.core.header.userData) {
73
+ if (key === savedKey) return value
74
+ }
75
+ return null
76
+ }
77
+
78
+ async _preready (core) {
79
+ const name = this._getPrereadyUserData(core, USERDATA_NAME_KEY)
70
80
  if (!name) return
71
81
 
72
- const namespace = await core.getUserData(USERDATA_NAMESPACE_KEY)
73
- const { publicKey, sign } = await this.keys.createHypercoreKeyPair(name.toString(), namespace)
82
+ const namespace = this._getPrereadyUserData(core, USERDATA_NAMESPACE_KEY)
83
+ const { publicKey, sign } = await this.keys.createHypercoreKeyPair(b4a.toString(name), namespace)
74
84
  if (!publicKey.equals(core.key)) throw new Error('Stored core key does not match the provided name')
75
85
 
76
- // TODO: Should Hypercore expose a helper for this, or should postload return keypair/sign?
86
+ // TODO: Should Hypercore expose a helper for this, or should preready return keypair/sign?
77
87
  core.sign = sign
78
88
  core.key = publicKey
79
89
  core.writable = true
@@ -83,19 +93,21 @@ module.exports = class Corestore extends EventEmitter {
83
93
  await this.ready()
84
94
 
85
95
  const { discoveryKey, keyPair, sign } = await this._generateKeys(opts)
86
- const id = discoveryKey.toString('hex')
96
+ const id = b4a.toString(discoveryKey, 'hex')
87
97
 
88
98
  while (this.cores.has(id)) {
89
99
  const existing = this.cores.get(id)
90
- if (existing) {
91
- if (!existing.closing) return { from: existing, keyPair, sign }
100
+ if (existing.opened && !existing.closing) return { from: existing, keyPair, sign }
101
+ if (!existing.opened) {
102
+ await existing.ready().catch(safetyCatch)
103
+ } else if (existing.closing) {
92
104
  await existing.close()
93
105
  }
94
106
  }
95
107
 
96
108
  const userData = {}
97
109
  if (opts.name) {
98
- userData[USERDATA_NAME_KEY] = Buffer.from(opts.name)
110
+ userData[USERDATA_NAME_KEY] = b4a.from(opts.name)
99
111
  userData[USERDATA_NAMESPACE_KEY] = this._namespace
100
112
  }
101
113
 
@@ -103,22 +115,31 @@ module.exports = class Corestore extends EventEmitter {
103
115
 
104
116
  const storageRoot = [CORES_DIR, id.slice(0, 2), id.slice(2, 4), id].join('/')
105
117
  const core = new Hypercore(p => this.storage(storageRoot + '/' + p), {
118
+ _preready: this._preready.bind(this),
106
119
  autoClose: true,
107
120
  encryptionKey: opts.encryptionKey || null,
108
- keyPair: {
109
- publicKey: keyPair.publicKey,
110
- secretKey: null
111
- },
112
121
  userData,
113
122
  sign: null,
114
- postload: this._postload.bind(this),
115
- createIfMissing: !!opts.keyPair
123
+ createIfMissing: !opts._discoveryKey,
124
+ keyPair: keyPair && keyPair.publicKey
125
+ ? {
126
+ publicKey: keyPair.publicKey,
127
+ secretKey: null
128
+ }
129
+ : null
116
130
  })
117
131
 
118
132
  this.cores.set(id, core)
119
- for (const stream of this._replicationStreams) {
120
- core.replicate(stream)
121
- }
133
+ core.ready().then(() => {
134
+ for (const { stream } of this._replicationStreams) {
135
+ const sessions = this._streamSessions.get(stream)
136
+ const session = core.session()
137
+ sessions.push(session)
138
+ core.replicate(stream)
139
+ }
140
+ }, () => {
141
+ this.cores.delete(id)
142
+ })
122
143
  core.once('close', () => {
123
144
  this.cores.delete(id)
124
145
  })
@@ -136,47 +157,59 @@ module.exports = class Corestore extends EventEmitter {
136
157
  return core
137
158
  }
138
159
 
139
- replicate (opts = {}) {
140
- const stream = isStream(opts) ? opts : (opts.stream || Hypercore.createProtocolStream(opts))
160
+ replicate (isInitiator, opts) {
161
+ const isExternal = isStream(isInitiator) || !!(opts && opts.stream)
162
+ const stream = Hypercore.createProtocolStream(isInitiator, {
163
+ ...opts,
164
+ ondiscoverykey: discoveryKey => {
165
+ const core = this.get({ _discoveryKey: discoveryKey })
166
+ return core.ready().catch(safetyCatch)
167
+ }
168
+ })
169
+
170
+ const sessions = []
141
171
  for (const core of this.cores.values()) {
172
+ if (!core.opened) continue // If the core is not opened, it will be replicated in preload.
173
+ const session = core.session()
174
+ sessions.push(session)
142
175
  core.replicate(stream)
143
176
  }
144
- stream.on('discovery-key', discoveryKey => {
145
- const core = this.get({ discoveryKey })
146
- core.ready().then(() => {
147
- core.replicate(stream)
148
- }, () => {
149
- stream.close(discoveryKey)
150
- })
151
- })
152
- this._replicationStreams.push(stream)
177
+
178
+ const streamRecord = { stream, isExternal }
179
+ this._replicationStreams.push(streamRecord)
180
+ this._streamSessions.set(stream, sessions)
181
+
153
182
  stream.once('close', () => {
154
- this._replicationStreams.splice(this._replicationStreams.indexOf(stream), 1)
183
+ this._replicationStreams.splice(this._replicationStreams.indexOf(streamRecord), 1)
184
+ this._streamSessions.delete(stream)
185
+ Promise.all(sessions.map(s => s.close())).catch(safetyCatch)
155
186
  })
156
187
  return stream
157
188
  }
158
189
 
159
190
  namespace (name) {
160
- if (!Buffer.isBuffer(name)) name = Buffer.from(name)
191
+ if (!b4a.isBuffer(name)) name = b4a.from(name)
161
192
  return new Corestore(this.storage, {
162
193
  _namespace: generateNamespace(this._namespace, name),
163
194
  _opening: this._opening,
164
195
  _cores: this.cores,
165
196
  _streams: this._replicationStreams,
197
+ _streamSessions: this._streamSessions,
166
198
  keys: this._opening.then(() => this.keys)
167
199
  })
168
200
  }
169
201
 
170
202
  async _close () {
171
- if (this._closing) return this._closing
172
203
  await this._opening
204
+ if (!this._namespace.equals(DEFAULT_NAMESPACE)) return // namespaces should not release resources on close
173
205
  const closePromises = []
174
206
  for (const core of this.cores.values()) {
175
207
  closePromises.push(core.close())
176
208
  }
177
209
  await Promise.allSettled(closePromises)
178
- for (const stream of this._replicationStreams) {
179
- stream.destroy()
210
+ for (const { stream, isExternal } of this._replicationStreams) {
211
+ // Only close streams that were created by the Corestore
212
+ if (!isExternal) stream.destroy()
180
213
  }
181
214
  await this.keys.close()
182
215
  }
@@ -184,7 +217,7 @@ module.exports = class Corestore extends EventEmitter {
184
217
  close () {
185
218
  if (this._closing) return this._closing
186
219
  this._closing = this._close()
187
- this._closing.catch(noop)
220
+ this._closing.catch(safetyCatch)
188
221
  return this._closing
189
222
  }
190
223
 
@@ -194,7 +227,7 @@ module.exports = class Corestore extends EventEmitter {
194
227
  }
195
228
 
196
229
  function validateGetOptions (opts) {
197
- if (Buffer.isBuffer(opts)) return { key: opts, publicKey: opts }
230
+ if (b4a.isBuffer(opts)) return { key: opts, publicKey: opts }
198
231
  if (opts.key) {
199
232
  opts.publicKey = opts.key
200
233
  }
@@ -204,23 +237,20 @@ function validateGetOptions (opts) {
204
237
  }
205
238
  if (opts.name && typeof opts.name !== 'string') throw new Error('name option must be a String')
206
239
  if (opts.name && opts.secretKey) throw new Error('Cannot provide both a name and a secret key')
207
- if (opts.publicKey && !Buffer.isBuffer(opts.publicKey)) throw new Error('publicKey option must be a Buffer')
208
- if (opts.secretKey && !Buffer.isBuffer(opts.secretKey)) throw new Error('secretKey option must be a Buffer')
209
- if (opts.discoveryKey && !Buffer.isBuffer(opts.discoveryKey)) throw new Error('discoveryKey option must be a Buffer')
210
- if (!opts.name && !opts.publicKey) throw new Error('Must provide either a name or a publicKey')
240
+ if (opts.publicKey && !b4a.isBuffer(opts.publicKey)) throw new Error('publicKey option must be a Buffer or Uint8Array')
241
+ if (opts.secretKey && !b4a.isBuffer(opts.secretKey)) throw new Error('secretKey option must be a Buffer or Uint8Array')
242
+ if (!opts._discoveryKey && (!opts.name && !opts.publicKey)) throw new Error('Must provide either a name or a publicKey')
211
243
  return opts
212
244
  }
213
245
 
214
246
  function generateNamespace (first, second) {
215
- if (!Buffer.isBuffer(first)) first = Buffer.from(first)
216
- if (second && !Buffer.isBuffer(second)) second = Buffer.from(second)
217
- const out = Buffer.allocUnsafe(32)
218
- sodium.crypto_generichash(out, second ? Buffer.concat([first, second]) : first)
247
+ if (!b4a.isBuffer(first)) first = b4a.from(first)
248
+ if (second && !b4a.isBuffer(second)) second = b4a.from(second)
249
+ const out = b4a.allocUnsafe(32)
250
+ sodium.crypto_generichash(out, second ? b4a.concat([first, second]) : first)
219
251
  return out
220
252
  }
221
253
 
222
254
  function isStream (s) {
223
255
  return typeof s === 'object' && s && typeof s.pipe === 'function'
224
256
  }
225
-
226
- function noop () {}
package/lib/keys.js CHANGED
@@ -2,9 +2,10 @@
2
2
 
3
3
  const sodium = require('sodium-universal')
4
4
  const blake2b = require('blake2b-universal')
5
+ const b4a = require('b4a')
5
6
 
6
- const DEFAULT_TOKEN = Buffer.alloc(0)
7
- const NAMESPACE = Buffer.from('@hyperspace/key-manager')
7
+ const DEFAULT_TOKEN = b4a.alloc(0)
8
+ const NAMESPACE = b4a.from('@hyperspace/key-manager')
8
9
 
9
10
  module.exports = class KeyManager {
10
11
  constructor (storage, profile, opts = {}) {
@@ -14,7 +15,7 @@ module.exports = class KeyManager {
14
15
 
15
16
  _sign (keyPair, message) {
16
17
  if (!keyPair._secretKey) throw new Error('Invalid key pair')
17
- const signature = Buffer.allocUnsafe(sodium.crypto_sign_BYTES)
18
+ const signature = b4a.allocUnsafe(sodium.crypto_sign_BYTES)
18
19
  sodium.crypto_sign_detached(signature, message, keyPair._secretKey)
19
20
  return signature
20
21
  }
@@ -25,8 +26,8 @@ module.exports = class KeyManager {
25
26
 
26
27
  createHypercoreKeyPair (name, token) {
27
28
  const keyPair = {
28
- publicKey: Buffer.allocUnsafe(sodium.crypto_sign_PUBLICKEYBYTES),
29
- _secretKey: Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES),
29
+ publicKey: b4a.allocUnsafe(sodium.crypto_sign_PUBLICKEYBYTES),
30
+ _secretKey: b4a.alloc(sodium.crypto_sign_SECRETKEYBYTES),
30
31
  sign: (msg) => this._sign(keyPair, msg)
31
32
  }
32
33
 
@@ -37,8 +38,8 @@ module.exports = class KeyManager {
37
38
 
38
39
  createNetworkIdentity (name, token) {
39
40
  const keyPair = {
40
- publicKey: Buffer.alloc(32),
41
- secretKey: Buffer.alloc(64)
41
+ publicKey: b4a.alloc(32),
42
+ secretKey: b4a.alloc(64)
42
43
  }
43
44
 
44
45
  sodium.crypto_sign_seed_keypair(keyPair.publicKey, keyPair.secretKey, this.createSecret(name, token))
@@ -86,19 +87,19 @@ module.exports = class KeyManager {
86
87
  function deriveSeed (profile, token, name, output) {
87
88
  if (token && token.length < 32) throw new Error('Token must be a Buffer with length >= 32')
88
89
  if (!name || typeof name !== 'string') throw new Error('name must be a String')
89
- if (!output) output = Buffer.alloc(32)
90
+ if (!output) output = b4a.alloc(32)
90
91
 
91
92
  blake2b.batch(output, [
92
93
  NAMESPACE,
93
94
  token || DEFAULT_TOKEN,
94
- Buffer.from(Buffer.byteLength(name, 'ascii') + '\n' + name, 'ascii')
95
+ b4a.from(b4a.byteLength(name, 'ascii') + '\n' + name, 'ascii')
95
96
  ], profile)
96
97
 
97
98
  return output
98
99
  }
99
100
 
100
101
  function randomBytes (n) {
101
- const buf = Buffer.allocUnsafe(n)
102
+ const buf = b4a.allocUnsafe(n)
102
103
  sodium.randombytes_buf(buf)
103
104
  return buf
104
105
  }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "corestore",
3
- "version": "6.0.0-alpha.4",
3
+ "version": "6.0.1-alpha.10",
4
4
  "description": "A Hypercore factory that simplifies managing collections of cores.",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
- "test": "standard && tape test/*.js"
7
+ "test": "standard && brittle test/*.js"
8
8
  },
9
9
  "repository": {
10
10
  "type": "git",
@@ -20,17 +20,19 @@
20
20
  },
21
21
  "homepage": "https://github.com/hypercore-protocol/corestore#readme",
22
22
  "devDependencies": {
23
+ "brittle": "^1.6.0",
23
24
  "random-access-file": "^2.2.0",
24
25
  "random-access-memory": "^3.1.2",
25
26
  "standardx": "^7.0.0",
26
- "tape": "^5.3.1",
27
27
  "tmp-promise": "^3.0.2"
28
28
  },
29
29
  "dependencies": {
30
+ "b4a": "^1.3.1",
31
+ "hypercore": "next",
30
32
  "blake2b-universal": "^1.0.1",
31
33
  "derive-key": "^1.0.1",
32
- "hypercore": "next",
33
34
  "hypercore-crypto": "^2.3.0",
35
+ "safety-catch": "^1.0.1",
34
36
  "sodium-universal": "^3.0.4"
35
37
  }
36
38
  }
package/test/all.js CHANGED
@@ -1,10 +1,12 @@
1
- const test = require('tape')
1
+ const { test, configure } = require('brittle')
2
2
  const crypto = require('hypercore-crypto')
3
3
  const ram = require('random-access-memory')
4
4
  const tmp = require('tmp-promise')
5
5
 
6
6
  const Corestore = require('..')
7
7
 
8
+ configure({ serial: true })
9
+
8
10
  test('basic get with caching', async function (t) {
9
11
  const store = new Corestore(ram)
10
12
  const core1a = store.get({ name: 'core-1' })
@@ -13,15 +15,13 @@ test('basic get with caching', async function (t) {
13
15
 
14
16
  await Promise.all([core1a.ready(), core1b.ready(), core2.ready()])
15
17
 
16
- t.same(core1a.key, core1b.key)
17
- t.notSame(core1a.key, core2.key)
18
-
19
- t.true(core1a.writable)
20
- t.true(core1b.writable)
18
+ t.alike(core1a.key, core1b.key)
19
+ t.unlike(core1a.key, core2.key)
21
20
 
22
- t.same(store.cores.size, 2)
21
+ t.ok(core1a.writable)
22
+ t.ok(core1b.writable)
23
23
 
24
- t.end()
24
+ t.is(store.cores.size, 2)
25
25
  })
26
26
 
27
27
  test('basic get with custom keypair', async function (t) {
@@ -33,12 +33,10 @@ test('basic get with custom keypair', async function (t) {
33
33
  const core2 = store.get(kp2)
34
34
  await Promise.all([core1.ready(), core2.ready()])
35
35
 
36
- t.same(core1.key, kp1.publicKey)
37
- t.same(core2.key, kp2.publicKey)
38
- t.true(core1.writable)
39
- t.true(core2.writable)
40
-
41
- t.end()
36
+ t.alike(core1.key, kp1.publicKey)
37
+ t.alike(core2.key, kp2.publicKey)
38
+ t.ok(core1.writable)
39
+ t.ok(core2.writable)
42
40
  })
43
41
 
44
42
  test('basic namespaces', async function (t) {
@@ -52,12 +50,12 @@ test('basic namespaces', async function (t) {
52
50
  const core3 = ns3.get({ name: 'main' })
53
51
  await Promise.all([core1.ready(), core2.ready(), core3.ready()])
54
52
 
55
- t.false(core1.key.equals(core2.key))
56
- t.true(core1.key.equals(core3.key))
57
- t.true(core1.writable)
58
- t.true(core2.writable)
59
- t.true(core3.writable)
60
- t.same(store.cores.size, 2)
53
+ t.absent(core1.key.equals(core2.key))
54
+ t.ok(core1.key.equals(core3.key))
55
+ t.ok(core1.writable)
56
+ t.ok(core2.writable)
57
+ t.ok(core3.writable)
58
+ t.is(store.cores.size, 2)
61
59
 
62
60
  t.end()
63
61
  })
@@ -77,10 +75,48 @@ test('basic replication', async function (t) {
77
75
  const s = store1.replicate(true)
78
76
  s.pipe(store2.replicate(false)).pipe(s)
79
77
 
80
- t.same(await core3.get(0), Buffer.from('hello'))
81
- t.same(await core4.get(0), Buffer.from('world'))
78
+ t.alike(await core3.get(0), Buffer.from('hello'))
79
+ t.alike(await core4.get(0), Buffer.from('world'))
80
+ })
81
+
82
+ test('replicating cores created after replication begins', async function (t) {
83
+ const store1 = new Corestore(ram)
84
+ const store2 = new Corestore(ram)
85
+
86
+ const s = store1.replicate(true, { live: true })
87
+ s.pipe(store2.replicate(false, { live: true })).pipe(s)
82
88
 
83
- t.end()
89
+ const core1 = store1.get({ name: 'core-1' })
90
+ const core2 = store1.get({ name: 'core-2' })
91
+ await core1.append('hello')
92
+ await core2.append('world')
93
+
94
+ const core3 = store2.get({ key: core1.key })
95
+ const core4 = store2.get({ key: core2.key })
96
+
97
+ t.alike(await core3.get(0), Buffer.from('hello'))
98
+ t.alike(await core4.get(0), Buffer.from('world'))
99
+ })
100
+
101
+ test('replicating cores using discovery key hook', async function (t) {
102
+ const dir = await tmp.dir({ unsafeCleanup: true })
103
+ let store1 = new Corestore(dir.path)
104
+ const store2 = new Corestore(ram)
105
+
106
+ const core = store1.get({ name: 'main' })
107
+ await core.append('hello')
108
+ const key = core.key
109
+
110
+ await store1.close()
111
+ store1 = new Corestore(dir.path)
112
+
113
+ const s = store1.replicate(true, { live: true })
114
+ s.pipe(store2.replicate(false, { live: true })).pipe(s)
115
+
116
+ const core2 = store2.get(key)
117
+ t.alike(await core2.get(0), Buffer.from('hello'))
118
+
119
+ await dir.cleanup()
84
120
  })
85
121
 
86
122
  test('nested namespaces', async function (t) {
@@ -92,22 +128,19 @@ test('nested namespaces', async function (t) {
92
128
  const core2 = ns1b.get({ name: 'main' })
93
129
  await Promise.all([core1.ready(), core2.ready()])
94
130
 
95
- t.false(core1.key.equals(core2.key))
96
- t.true(core1.writable)
97
- t.true(core2.writable)
98
- t.same(store.cores.size, 2)
99
-
100
- t.end()
131
+ t.not(core1.key.equals(core2.key))
132
+ t.ok(core1.writable)
133
+ t.ok(core2.writable)
134
+ t.is(store.cores.size, 2)
101
135
  })
102
136
 
103
137
  test('core uncached when all sessions close', async function (t) {
104
138
  const store = new Corestore(ram)
105
139
  const core1 = store.get({ name: 'main' })
106
140
  await core1.ready()
107
- t.same(store.cores.size, 1)
141
+ t.is(store.cores.size, 1)
108
142
  await core1.close()
109
- t.same(store.cores.size, 0)
110
- t.end()
143
+ t.is(store.cores.size, 0)
111
144
  })
112
145
 
113
146
  test('writable core loaded from name userData', async function (t) {
@@ -118,23 +151,22 @@ test('writable core loaded from name userData', async function (t) {
118
151
  await core.ready()
119
152
  const key = core.key
120
153
 
121
- t.true(core.writable)
154
+ t.ok(core.writable)
122
155
  await core.append('hello')
123
- t.same(core.length, 1)
156
+ t.is(core.length, 1)
124
157
 
125
158
  await store.close()
126
159
  store = new Corestore(dir.path)
127
160
  core = store.get(key)
128
161
  await core.ready()
129
162
 
130
- t.true(core.writable)
163
+ t.ok(core.writable)
131
164
  await core.append('world')
132
- t.same(core.length, 2)
133
- t.same(await core.get(0), Buffer.from('hello'))
134
- t.same(await core.get(1), Buffer.from('world'))
165
+ t.is(core.length, 2)
166
+ t.alike(await core.get(0), Buffer.from('hello'))
167
+ t.alike(await core.get(1), Buffer.from('world'))
135
168
 
136
169
  await dir.cleanup()
137
- t.end()
138
170
  })
139
171
 
140
172
  test('storage locking', async function (t) {
@@ -152,5 +184,24 @@ test('storage locking', async function (t) {
152
184
  }
153
185
 
154
186
  await dir.cleanup()
155
- t.end()
187
+ })
188
+
189
+ test('closing a namespace does not close cores', async function (t) {
190
+ const store = new Corestore(ram)
191
+ const ns1 = store.namespace('ns1')
192
+ const core1 = ns1.get({ name: 'core-1' })
193
+ const core2 = ns1.get({ name: 'core-2' })
194
+ await Promise.all([core1.ready(), core2.ready()])
195
+
196
+ await ns1.close()
197
+
198
+ t.is(store.cores.size, 2)
199
+ t.not(core1.closed)
200
+ t.not(core1.closed)
201
+
202
+ await store.close()
203
+
204
+ t.is(store.cores.size, 0)
205
+ t.ok(core1.closed)
206
+ t.ok(core2.closed)
156
207
  })
package/test/keys.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const p = require('path')
2
2
  const fs = require('fs')
3
3
 
4
- const test = require('tape')
4
+ const test = require('brittle')
5
5
  const ram = require('random-access-memory')
6
6
  const raf = require('random-access-file')
7
7
 
@@ -13,11 +13,9 @@ test('can create hypercore keypairs', async t => {
13
13
  const kp1 = await keys.createHypercoreKeyPair('core1')
14
14
  const kp2 = await keys.createHypercoreKeyPair('core2')
15
15
 
16
- t.same(kp1.publicKey.length, 32)
17
- t.same(kp2.publicKey.length, 32)
18
- t.notSame(kp1.publicKey, kp2.publicKey)
19
-
20
- t.end()
16
+ t.is(kp1.publicKey.length, 32)
17
+ t.is(kp2.publicKey.length, 32)
18
+ t.unlike(kp1.publicKey, kp2.publicKey)
21
19
  })
22
20
 
23
21
  test('distinct tokens create distinct hypercore keypairs', async t => {
@@ -28,9 +26,7 @@ test('distinct tokens create distinct hypercore keypairs', async t => {
28
26
  const kp1 = await keys.createHypercoreKeyPair('core1', token1)
29
27
  const kp2 = await keys.createHypercoreKeyPair('core1', token2)
30
28
 
31
- t.notSame(kp1.publicKey, kp2.publicKey)
32
-
33
- t.end()
29
+ t.unlike(kp1.publicKey, kp2.publicKey)
34
30
  })
35
31
 
36
32
  test('short user-provided token will throw', async t => {
@@ -42,8 +38,6 @@ test('short user-provided token will throw', async t => {
42
38
  } catch {
43
39
  t.pass('threw correctly')
44
40
  }
45
-
46
- t.end()
47
41
  })
48
42
 
49
43
  test('persistent storage regenerates keys correctly', async t => {
@@ -55,10 +49,9 @@ test('persistent storage regenerates keys correctly', async t => {
55
49
  const keys2 = await KeyManager.fromStorage((name) => raf(testPath, { directory: testPath }))
56
50
  const kp2 = await keys2.createHypercoreKeyPair('core1')
57
51
 
58
- t.same(kp1.publicKey, kp2.publicKey)
52
+ t.alike(kp1.publicKey, kp2.publicKey)
59
53
 
60
54
  await fs.promises.rm(testPath, { recursive: true })
61
- t.end()
62
55
  })
63
56
 
64
57
  test('different master keys -> different keys', async t => {
@@ -68,7 +61,5 @@ test('different master keys -> different keys', async t => {
68
61
  const kp1 = await keys1.createHypercoreKeyPair('core1')
69
62
  const kp2 = await keys2.createHypercoreKeyPair('core1')
70
63
 
71
- t.notSame(kp1.publicKey, kp2.publicKey)
72
-
73
- t.end()
64
+ t.unlike(kp1.publicKey, kp2.publicKey)
74
65
  })