Skip to content
This repository was archived by the owner on Jul 21, 2023. It is now read-only.

Commit 42eab95

Browse files
dirkmcvasco-santos
authored andcommitted
refactor: convert from callbacks to async (#13)
BREAKING CHANGE: All places in the API that used callbacks are now replaced with async/await
1 parent bd5b994 commit 42eab95

File tree

6 files changed

+68
-89
lines changed

6 files changed

+68
-89
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ stages:
88

99
node_js:
1010
- '10'
11+
- '12'
1112

1213
os:
1314
- linux
@@ -21,7 +22,6 @@ jobs:
2122
include:
2223
- stage: check
2324
script:
24-
- npx aegir commitlint --travis
2525
- npx aegir dep-check
2626
- npm run lint
2727

package.json

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,8 @@
2727
"node": ">=6.0.0",
2828
"npm": ">=3.0.0"
2929
},
30-
"pre-commit": [
31-
"lint",
32-
"test"
30+
"pre-push": [
31+
"lint"
3332
],
3433
"author": "Friedel Ziegelmayer <dignifiedquire@gmail.com>",
3534
"license": "MIT",
@@ -38,19 +37,17 @@
3837
},
3938
"homepage": "https://github.com/libp2p/js-libp2p-record",
4039
"devDependencies": {
41-
"aegir": "^18.2.2",
40+
"aegir": "^20.0.0",
4241
"chai": "^4.2.0",
4342
"dirty-chai": "^2.0.1",
44-
"libp2p-crypto": "~0.16.1",
45-
"peer-id": "~0.12.2",
46-
"pre-commit": "^1.2.2"
43+
"libp2p-crypto": "~0.17.0",
44+
"peer-id": "~0.13.2"
4745
},
4846
"dependencies": {
49-
"async": "^2.6.2",
5047
"buffer-split": "^1.0.0",
5148
"err-code": "^1.1.2",
52-
"multihashes": "~0.4.14",
53-
"multihashing-async": "~0.6.0",
49+
"multihashes": "~0.4.15",
50+
"multihashing-async": "~0.7.0",
5451
"protons": "^1.0.1"
5552
},
5653
"contributors": [

src/selection.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,23 @@ const bestRecord = (selectors, k, records) => {
1515
if (records.length === 0) {
1616
const errMsg = `No records given`
1717

18-
throw errcode(new Error(errMsg), 'ERR_NO_RECORDS_RECEIVED')
18+
throw errcode(errMsg, 'ERR_NO_RECORDS_RECEIVED')
1919
}
2020

2121
const parts = bsplit(k, Buffer.from('/'))
2222

2323
if (parts.length < 3) {
2424
const errMsg = `Record key does not have a selector function`
2525

26-
throw errcode(new Error(errMsg), 'ERR_NO_SELECTOR_FUNCTION_FOR_RECORD_KEY')
26+
throw errcode(errMsg, 'ERR_NO_SELECTOR_FUNCTION_FOR_RECORD_KEY')
2727
}
2828

2929
const selector = selectors[parts[1].toString()]
3030

3131
if (!selector) {
3232
const errMsg = `Unrecognized key prefix: ${parts[1]}`
3333

34-
throw errcode(new Error(errMsg), 'ERR_UNRECOGNIZED_KEY_PREFIX')
34+
throw errcode(errMsg, 'ERR_UNRECOGNIZED_KEY_PREFIX')
3535
}
3636

3737
return selector(k, records)

src/validator.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,30 @@ const errcode = require('err-code')
66
/**
77
* Checks a record and ensures it is still valid.
88
* It runs the needed validators.
9+
* If verification fails the returned Promise will reject with the error.
910
*
1011
* @param {Object} validators
1112
* @param {Record} record
12-
* @param {function(Error)} callback
13-
* @returns {undefined}
13+
* @returns {Promise}
1414
*/
15-
const verifyRecord = (validators, record, callback) => {
15+
const verifyRecord = (validators, record) => {
1616
const key = record.key
1717
const parts = bsplit(key, Buffer.from('/'))
1818

1919
if (parts.length < 3) {
2020
// No validator available
21-
return callback()
21+
return
2222
}
2323

2424
const validator = validators[parts[1].toString()]
2525

2626
if (!validator) {
2727
const errMsg = `Invalid record keytype`
2828

29-
return callback(errcode(new Error(errMsg), 'ERR_INVALID_RECORD_KEY_TYPE'))
29+
throw errcode(errMsg, 'ERR_INVALID_RECORD_KEY_TYPE')
3030
}
3131

32-
validator.func(key, record.value, callback)
32+
return validator.func(key, record.value)
3333
}
3434

3535
module.exports = {

src/validators/public-key.js

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,40 @@
11
'use strict'
22

3-
const setImmediate = require('async/setImmediate')
43
const multihashing = require('multihashing-async')
4+
const errcode = require('err-code')
55

66
/**
77
* Validator for publick key records.
88
* Verifies that the passed in record value is the PublicKey
99
* that matches the passed in key.
10+
* If validation fails the returned Promise will reject with the error.
1011
*
1112
* @param {Buffer} key - A valid key is of the form `'/pk/<keymultihash>'`
1213
* @param {Buffer} publicKey - The public key to validate against (protobuf encoded).
13-
* @param {function(Error)} callback
14-
* @returns {undefined}
14+
* @returns {Promise}
1515
*/
16-
const validatePublicKeyRecord = (key, publicKey, callback) => {
17-
const done = (err) => setImmediate(() => callback(err))
18-
16+
const validatePublicKeyRecord = async (key, publicKey) => {
1917
if (!Buffer.isBuffer(key)) {
20-
return done(new Error('"key" must be a Buffer'))
18+
throw errcode('"key" must be a Buffer', 'ERR_INVALID_RECORD_KEY_NOT_BUFFER')
2119
}
2220

23-
if (key.length < 3) {
24-
return done(new Error('invalid public key record'))
21+
if (key.length < 5) {
22+
throw errcode('invalid public key record', 'ERR_INVALID_RECORD_KEY_TOO_SHORT')
2523
}
2624

2725
const prefix = key.slice(0, 4).toString()
2826

2927
if (prefix !== '/pk/') {
30-
return done(new Error('key was not prefixed with /pk/'))
28+
throw errcode('key was not prefixed with /pk/', 'ERR_INVALID_RECORD_KEY_BAD_PREFIX')
3129
}
3230

3331
const keyhash = key.slice(4)
3432

35-
multihashing(publicKey, 'sha2-256', (err, publicKeyHash) => {
36-
if (err) {
37-
return done(err)
38-
}
39-
40-
if (!keyhash.equals(publicKeyHash)) {
41-
return done(new Error('public key does not match passed in key'))
42-
}
33+
const publicKeyHash = await multihashing(publicKey, 'sha2-256')
4334

44-
done()
45-
})
35+
if (!keyhash.equals(publicKeyHash)) {
36+
throw errcode('public key does not match passed in key', 'ERR_INVALID_RECORD_HASH_MISMATCH')
37+
}
4638
}
4739

4840
module.exports = {

test/validator.spec.js

Lines changed: 39 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
const chai = require('chai')
66
chai.use(require('dirty-chai'))
77
const expect = chai.expect
8-
const waterfall = require('async/waterfall')
9-
const each = require('async/each')
108
const crypto = require('libp2p-crypto')
119
const PeerId = require('peer-id')
1210

@@ -29,14 +27,16 @@ const generateCases = (hash) => {
2927
invalid: {
3028
publicKey: [
3129
// missing hashkey
32-
Buffer.from('/pk/'),
30+
[Buffer.from('/pk/'), 'ERR_INVALID_RECORD_KEY_TOO_SHORT'],
3331
// not the hash of a key
34-
Buffer.concat([
32+
[Buffer.concat([
3533
Buffer.from('/pk/'),
3634
Buffer.from('random')
37-
]),
35+
]), 'ERR_INVALID_RECORD_HASH_MISMATCH'],
3836
// missing prefix
39-
hash
37+
[hash, 'ERR_INVALID_RECORD_KEY_BAD_PREFIX'],
38+
// not a buffer
39+
['not a buffer', 'ERR_INVALID_RECORD_KEY_NOT_BUFFER']
4040
]
4141
}
4242
}
@@ -47,57 +47,47 @@ describe('validator', () => {
4747
let hash
4848
let cases
4949

50-
before((done) => {
51-
waterfall([
52-
(cb) => crypto.keys.generateKeyPair('rsa', 1024, cb),
53-
(pair, cb) => {
54-
key = pair
55-
pair.public.hash(cb)
56-
},
57-
(_hash, cb) => {
58-
hash = _hash
59-
cases = generateCases(hash)
60-
cb()
61-
}
62-
], done)
50+
before(async () => {
51+
key = await crypto.keys.generateKeyPair('rsa', 1024)
52+
hash = await key.public.hash()
53+
cases = generateCases(hash)
6354
})
6455

6556
describe('verifyRecord', () => {
66-
it('calls matching validator', (done) => {
57+
it('calls matching validator', () => {
6758
const k = Buffer.from('/hello/you')
6859
const rec = new Record(k, Buffer.from('world'), new PeerId(hash))
6960

7061
const validators = {
7162
hello: {
72-
func (key, value, cb) {
63+
func (key, value) {
7364
expect(key).to.eql(k)
7465
expect(value).to.eql(Buffer.from('world'))
75-
cb()
7666
},
7767
sign: false
7868
}
7969
}
80-
validator.verifyRecord(validators, rec, done)
70+
return validator.verifyRecord(validators, rec)
8171
})
8272

83-
it('calls not matching any validator', (done) => {
73+
it('calls not matching any validator', () => {
8474
const k = Buffer.from('/hallo/you')
8575
const rec = new Record(k, Buffer.from('world'), new PeerId(hash))
8676

8777
const validators = {
8878
hello: {
89-
func (key, value, cb) {
79+
func (key, value) {
9080
expect(key).to.eql(k)
9181
expect(value).to.eql(Buffer.from('world'))
92-
cb()
9382
},
9483
sign: false
9584
}
9685
}
97-
validator.verifyRecord(validators, rec, (err) => {
98-
expect(err).to.exist()
99-
done()
100-
})
86+
return expect(
87+
() => validator.verifyRecord(validators, rec)
88+
).to.throw(
89+
/Invalid record keytype/
90+
)
10191
})
10292
})
10393

@@ -107,40 +97,40 @@ describe('validator', () => {
10797
})
10898

10999
describe('public key', () => {
110-
it('exports func and sing', () => {
100+
it('exports func and sign', () => {
111101
const pk = validator.validators.pk
112102

113103
expect(pk).to.have.property('func')
114104
expect(pk).to.have.property('sign', false)
115105
})
116106

117-
it('does not error on valid record', (done) => {
118-
each(cases.valid.publicKey, (k, cb) => {
119-
validator.validators.pk.func(k, key.public.bytes, cb)
120-
}, done)
107+
it('does not error on valid record', () => {
108+
return Promise.all(cases.valid.publicKey.map((k) => {
109+
return validator.validators.pk.func(k, key.public.bytes)
110+
}))
121111
})
122112

123-
it('throws on invalid records', (done) => {
124-
each(cases.invalid.publicKey, (k, cb) => {
125-
validator.validators.pk.func(k, key.public.bytes, (err) => {
126-
expect(err).to.exist()
127-
cb()
128-
})
129-
}, done)
113+
it('throws on invalid records', () => {
114+
return Promise.all(cases.invalid.publicKey.map(async ([k, errCode]) => {
115+
try {
116+
await validator.validators.pk.func(k, key.public.bytes)
117+
} catch (err) {
118+
expect(err.code).to.eql(errCode)
119+
return
120+
}
121+
expect.fail('did not throw an error with code ' + errCode)
122+
}))
130123
})
131124
})
132125
})
133126

134127
describe('go interop', () => {
135-
it('record with key from from go', (done) => {
128+
it('record with key from from go', async () => {
136129
const pubKey = crypto.keys.unmarshalPublicKey(fixture.publicKey)
137130

138-
pubKey.hash((err, hash) => {
139-
expect(err).to.not.exist()
140-
const k = Buffer.concat([Buffer.from('/pk/'), hash])
141-
142-
validator.validators.pk.func(k, pubKey.bytes, done)
143-
})
131+
const hash = await pubKey.hash()
132+
const k = Buffer.concat([Buffer.from('/pk/'), hash])
133+
return validator.validators.pk.func(k, pubKey.bytes)
144134
})
145135
})
146136
})

0 commit comments

Comments
 (0)