diff --git a/.travis.yml b/.travis.yml index 60a0ff6..2db2e47 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,10 +4,10 @@ language: node_js matrix: include: - - node_js: 6 - env: CXX=g++-4.8 - node_js: 8 env: CXX=g++-4.8 + - node_js: 10 + env: CXX=g++-4.8 script: - npm run lint diff --git a/README.md b/README.md index 1782083..1eb932b 100644 --- a/README.md +++ b/README.md @@ -71,12 +71,8 @@ Though it can also be used as a standalone module: const IpldZcash = require('ipld-zcash') // `zcashBlock` is some binary Zcash block -IpldZcash.util.deserialize(zcashBlock, (err, dagNode) => { - if (err) { - throw err - } - console.log(dagNode) -}) +const dagNode = await IpldZcash.util.deserialize(zcashBlock) +console.log(dagNode) ``` ## Contribute diff --git a/appveyor.yml b/appveyor.yml index 046bf91..8ab0d6c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,8 +3,8 @@ version: "{build}" environment: matrix: - - nodejs_version: "6" - nodejs_version: "8" + - nodejs_version: "10" matrix: fast_finish: true diff --git a/package.json b/package.json index 050423b..70a0d7d 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,6 @@ }, "homepage": "https://github.com/ipld/js-ipld-zcash#readme", "dependencies": { - "async": "^2.6.1", "cids": "~0.5.2", "multihashes": "~0.4.12", "multihashing-async": "~0.5.1", diff --git a/src/resolver.js b/src/resolver.js index aa82a08..6f472cb 100644 --- a/src/resolver.js +++ b/src/resolver.js @@ -3,11 +3,9 @@ const util = require('./util') /** - * @callback ResolveCallback - * @param {?Error} error - Error if path can't be resolved - * @param {Object} result - Result of the path it it was resolved successfully - * @param {*} result.value - Value the path resolves to - * @param {string} result.remainderPath - If the path resolves half-way to a + * @typedef {Object} ResolveObject + * @property {*} value - Value the path resolves to + * @property {string} remainderPath - If the path resolves half-way to a * link, then the `remainderPath` is the part after the link that can be used * for further resolving. */ @@ -19,61 +17,44 @@ const util = require('./util') * * @param {Buffer} binaryBlob - Binary representation of a Zcash block * @param {string} [path='/'] - Path that should be resolved - * @param {ResolveCallback} callback - Callback that handles the return value - * @returns {void} + * @returns {Promise} */ -const resolve = (binaryBlob, path, callback) => { - if (typeof path === 'function') { - callback = path - path = undefined - } +const resolve = async (binaryBlob, path) => { + const dagNode = await util.deserialize(binaryBlob) - util.deserialize(binaryBlob, (err, dagNode) => { - if (err) { - return callback(err) + // Return the deserialized block if no path is given + if (!path) { + return { + value: dagNode, + remainderPath: '' } + } - // Return the deserialized block if no path is given - if (!path) { - return callback(null, { - value: dagNode, - remainderPath: '' - }) - } + const pathArray = path.split('/') + const value = resolveField(dagNode, pathArray[0]) + if (value === null) { + throw new Error('No such path') + } - const pathArray = path.split('/') - const value = resolveField(dagNode, pathArray[0]) - if (value === null) { - return callback(new Error('No such path'), null) + let remainderPath = pathArray.slice(1).join('/') + // It is a link, hence it may have a remainder + if (value['/'] !== undefined) { + return { + value: value, + remainderPath: remainderPath } - - let remainderPath = pathArray.slice(1).join('/') - // It is a link, hence it may have a remainder - if (value['/'] !== undefined) { - return callback(null, { - value: value, - remainderPath: remainderPath - }) + } else { + if (remainderPath.length > 0) { + throw new Error('No such path') } else { - if (remainderPath.length > 0) { - return callback(new Error('No such path'), null) - } else { - return callback(null, { - value: value, - remainderPath: '' - }) + return { + value: value, + remainderPath: '' } } - }) + } } -/** - * @callback TreeCallback - * @param {?Error} error - Error if paths can't be retreived - * @param {string[] | Object.[]} result - The result depends on - * `options.values`, whether it returns only the paths, or the paths with - * the corresponding values - */ /** * Return all available paths of a block. * @@ -81,34 +62,27 @@ const resolve = (binaryBlob, path, callback) => { * @param {Object} [options] - Possible options * @param {boolean} [options.values=false] - Retun only the paths by default. * If it is `true` also return the values - * @param {TreeCallback} callback - Callback that handles the return value - * @returns {void} + * @returns {Promise[]>} -The result depends on + * `options.values`, whether it returns only the paths, or the paths with + * the corresponding values */ -const tree = (binaryBlob, options, callback) => { - if (typeof options === 'function') { - callback = options - options = undefined - } - options = options || {} +const tree = async (binaryBlob, options = {}) => { + const dagNode = await util.deserialize(binaryBlob) - util.deserialize(binaryBlob, (err, dagNode) => { - if (err) { - return callback(err) - } + const paths = ['version', 'timestamp', 'difficulty', 'nonce', + 'solution', 'reserved', 'parent', 'tx'] - const paths = ['version', 'timestamp', 'difficulty', 'nonce', - 'solution', 'reserved', 'parent', 'tx'] + if (options.values === true) { + const pathValues = {} - if (options.values === true) { - const pathValues = {} - for (let path of paths) { - pathValues[path] = resolveField(dagNode, path) - } - return callback(null, pathValues) - } else { - return callback(null, paths) + for (let path of paths) { + pathValues[path] = resolveField(dagNode, path) } - }) + + return pathValues + } else { + return paths + } } // Return top-level fields. Returns `null` if field doesn't exist diff --git a/src/util.js b/src/util.js index dc2a219..bf5a44f 100644 --- a/src/util.js +++ b/src/util.js @@ -4,66 +4,33 @@ const ZcashBitcoreBlockHeader = require('zcash-bitcore-lib').BlockHeader const CID = require('cids') const multihashes = require('multihashes') const multihashing = require('multihashing-async') -const waterfall = require('async/waterfall') const ZCASH_BLOCK_HEADER_SIZE = 1487 -/** - * @callback SerializeCallback - * @param {?Error} error - Error if serialization failed - * @param {?Buffer} binaryBlob - Binary Zcash block if serialization was - * successful - */ /** * Serialize internal representation into a binary Zcash block. * * @param {ZcashBlock} dagNode - Internal representation of a Zcash block - * @param {SerializeCallback} callback - Callback that handles the - * return value - * @returns {void} + * @returns {Promise} */ -const serialize = (dagNode, callback) => { - let err = null - let binaryBlob - try { - binaryBlob = dagNode.toBuffer() - } catch (serializeError) { - err = serializeError - } finally { - callback(err, binaryBlob) - } +const serialize = async (dagNode) => { + return dagNode.toBuffer() } -/** - * @callback DeserializeCallback - * @param {?Error} error - Error if deserialization failed - * @param {?ZcashBlock} dagNode - Internal representation of a Zcash block - * if deserialization was successful - */ /** * Deserialize Zcash block into the internal representation, * * @param {Buffer} binaryBlob - Binary representation of a Zcash block - * @param {DeserializeCallback} callback - Callback that handles the - * return value - * @returns {void} + * @returns {Promise} */ -const deserialize = (binaryBlob, callback) => { +const deserialize = async (binaryBlob) => { if (binaryBlob.length !== ZCASH_BLOCK_HEADER_SIZE) { - const err = new Error( - `Zcash block header needs to be ${ZCASH_BLOCK_HEADER_SIZE} bytes`) - return callback(err) + throw new Error(`Zcash block header needs to be ${ZCASH_BLOCK_HEADER_SIZE} bytes`) } - const dagNode = ZcashBitcoreBlockHeader.fromBuffer(binaryBlob) - callback(null, dagNode) + return ZcashBitcoreBlockHeader.fromBuffer(binaryBlob) } -/** - * @callback CidCallback - * @param {?Error} error - Error if getting the CID failed - * @param {?CID} cid - CID if call was successful - */ /** * Get the CID of the DAG-Node. * @@ -71,28 +38,19 @@ const deserialize = (binaryBlob, callback) => { * @param {Object} [options] - Options to create the CID * @param {number} [options.version=1] - CID version number * @param {string} [options.hashAlg='dbl-sha2-256'] - Hashing algorithm - * @param {CidCallback} callback - Callback that handles the return value - * @returns {void} + * @returns {Promise} */ -const cid = (dagNode, options, callback) => { - if (typeof options === 'function') { - callback = options - options = {} - } - options = options || {} +const cid = async (dagNode, options = {}) => { // avoid deadly embrace between resolver and util const hashAlg = options.hashAlg || require('./resolver').defaultHashAlg const version = typeof options.version === 'undefined' ? 1 : options.version - waterfall([ - (cb) => { - try { - multihashing(dagNode.toBuffer(), hashAlg, cb) - } catch (err) { - cb(err) - } - }, - (mh, cb) => cb(null, new CID(version, 'zcash-block', mh)) - ], callback) + + return new Promise((resolve, reject) => { + multihashing(dagNode.toBuffer(), hashAlg, (err, mh) => { + if (err) return reject(err) + resolve(new CID(version, 'zcash-block', mh)) + }) + }) } // Convert a Zcash hash (as Buffer) to a CID diff --git a/test/resolver.spec.js b/test/resolver.spec.js index b3c6617..073f47c 100644 --- a/test/resolver.spec.js +++ b/test/resolver.spec.js @@ -15,148 +15,121 @@ const fixtureBlockHeader = helpers.headerFromHexBlock(fixtureBlockHex) const invalidBlock = Buffer.from('abcdef', 'hex') describe('IPLD format resolver API resolve()', () => { - it('should return the deserialized node if no path is given', (done) => { - IpldZcash.resolver.resolve(fixtureBlockHeader, (err, value) => { - expect(err).to.not.exist() - expect(value.remainderPath).is.empty() - expect(value.value).is.not.empty() - done() - }) + it('should return the deserialized node if no path is given', async () => { + const value = await IpldZcash.resolver.resolve(fixtureBlockHeader) + expect(value.remainderPath).is.empty() + expect(value.value).is.not.empty() }) - it('should return the deserialized node if path is empty', (done) => { - IpldZcash.resolver.resolve(fixtureBlockHeader, '', (err, value) => { - expect(err).to.not.exist() - expect(value.remainderPath).is.empty() - expect(value.value).is.not.empty() - done() - }) + it('should return the deserialized node if path is empty', async () => { + const value = await IpldZcash.resolver.resolve(fixtureBlockHeader, '') + expect(value.remainderPath).is.empty() + expect(value.value).is.not.empty() }) - it('should return the version', (done) => { - verifyPath(fixtureBlockHeader, 'version', 4, done) + it('should return the version', async () => { + return verifyPath(fixtureBlockHeader, 'version', 4) }) - it('should return the timestamp', (done) => { - verifyPath(fixtureBlockHeader, 'timestamp', 1481233847, done) + it('should return the timestamp', async () => { + return verifyPath(fixtureBlockHeader, 'timestamp', 1481233847) }) - it('should return the difficulty', (done) => { - verifyPath(fixtureBlockHeader, 'difficulty', 477875354, done) + it('should return the difficulty', async () => { + return verifyPath(fixtureBlockHeader, 'difficulty', 477875354) }) - it('should return the nonce', (done) => { - verifyPath( + it('should return the nonce', async () => { + return verifyPath( fixtureBlockHeader, 'nonce', - Buffer.from('8200000000000000d548af969ea8dceedb6bfad4000000000000000000000000', 'hex'), - done) + Buffer.from('8200000000000000d548af969ea8dceedb6bfad4000000000000000000000000', 'hex')) }) - it('should return the solution', (done) => { - verifyPath( + it('should return the solution', async () => { + return verifyPath( fixtureBlockHeader, 'solution', - Buffer.from('005836fdbc8a7a7d9cbec4f059ba17f62d0e775b19035c8e18f123d3a99f270118325eaac526ae7a68d60c9c8c5acdc3e71e987020cb55ad92e0c37af0ab200d3a19e366389bdfe53cd79f70dbc4a67ea6fdc3700f25e0b1d49cee31a54ba8cf826b34c2561c97a0c239e2872c74a33c41690a44e0de741283d60dbfb738152a90d84b1b8f4dce36c3323d35275e8c43f464e9401b757a85392335fdba2432eda2b225b9549faee001d0ebadf24c106f353a02788c386a2f6bce7d83422e8d3ba8ff5cdd85429484a67c76ce31bfacf968621f0b72d9334dfee6b430d2a811f7954548b419fb9428b6d9a09e1317774ebb628d4dd8f334fbe4fb80200f226af20f1cd089849c6207c9d87869baba2e473b0f6b07e68ada56955322d31879c5653a1a84df97a5180e0655fa8da912d5b09396dc601db16143ac00525a9f16b087b64e4fb6567822f1ed84ba723ffde6ca00f29446a54ce34ad03030e6dd55a992817ede9038436793fa72b7133fcded9443d2340b7dcfb45b02230121c5d0d2958cff63a5633db92b61ed9524f74d230a5429c76a02e12f096e611cc978893683429f89cf03a52533039ae3b7c092589aa9f60cb67b19d5849533c254986a614909ee5765097935f7b162842c09d315526f5f3d77c817eff16204fbe6c949b44e1ac1052482774279e76377431123a189d6716ddff6157c6708985f8f01277d67871e915adcc83119440c8cf6e121911b6d748a4c4b15537273379965ecb0bd89862936cfd7a45d9138b93e564596de4ae5099a371f8cf95f692dffe46523ad5bb0482891df72eac651b9c42f191841e3ad68b0459619367f0341523a03a61ecda6694a7dbcaf1f6d9d11c8c6f132fda2beca91f84cd01d78e2854b5aac4ad7219bff38f94e131e065a48961e6e5468690d0122c832f3ee5570fbed1547d91bc202151d3757d432f1edc793c5f37cf6bd34a9af42970ccb01ae1696ba75067c743b58b9ca4e81e1d7a69203c3b62609150effaab450dd4a0b20d68a31be560808c097f046924acd6e9fc18e3f5d28e698d658a96b06821737a511616bdcb4237c5d3dedd56e53d758bb2d695f52ee58cb49bff3563d38c30411c22e7393b61797d79755a4ea5f9b1232283e4b802100199633b03277e398f70f3e0ef8e7a4b7bf396aba1d55f53a2e03ef089c6720dc456715b08bb94f754d211037c15e0b2078d6226a7a31f4e8f19d885adae07244132dcf0605873a19d4dbef5a03f425975e796956827d6d66072675d10ac87a02db325559bdc9643a32a0beb93723fc3fdbb218b5c2c9d3c2ca9dec65392e1a0fbe0732e66547335f69ab4b81064a4d3fb9830d0e3c547e2a6a554f22928e8762e8941f6f5f5cc509319fb85a2cbf0e433be5a225f94c693bb0691a8ecdba58f71104e12f7cc056a10ae17856e059fb126ea1a5fa43a40f4367901212a3decbea31e0756c37587ff4fdd0271825aa48e0105f8af667977a823fe051dfaa1fb4014f50d6222fed9ccd8787c77563d83e3e52435cf19806c662596988442b39f2611fc80a8ee561bc3f944320b3f7ebaae1fc592e7a823c0967ceedf898b6f805224a3353f92121fb22fb16dbdc41cc066c1f5efaa42945ad4b6326fe73e4b3b34371c64871a99d97bec407ec53b9b01a332ada7a81f8f5f576aedd96b7ec0f51f9977c2ca8c40fbd66779a4743db1622619d23940c59f72b055674bd9ab331a20db20bbcdef4d8184929b1b6bcfc5f155ff0d263e37145f5c98cde541dda165943dec7a56deb81b8f1bd279acfcc8e16e9a968263f8d5c8793e7311a4fe2d114c9d601bf315df05317c0ad89c34e363af79ca4f0c6618f0da51cb8930f2d525779a64f3b657ff0e8b1106ce4f63f775b4cf6', 'hex'), - done) + Buffer.from('005836fdbc8a7a7d9cbec4f059ba17f62d0e775b19035c8e18f123d3a99f270118325eaac526ae7a68d60c9c8c5acdc3e71e987020cb55ad92e0c37af0ab200d3a19e366389bdfe53cd79f70dbc4a67ea6fdc3700f25e0b1d49cee31a54ba8cf826b34c2561c97a0c239e2872c74a33c41690a44e0de741283d60dbfb738152a90d84b1b8f4dce36c3323d35275e8c43f464e9401b757a85392335fdba2432eda2b225b9549faee001d0ebadf24c106f353a02788c386a2f6bce7d83422e8d3ba8ff5cdd85429484a67c76ce31bfacf968621f0b72d9334dfee6b430d2a811f7954548b419fb9428b6d9a09e1317774ebb628d4dd8f334fbe4fb80200f226af20f1cd089849c6207c9d87869baba2e473b0f6b07e68ada56955322d31879c5653a1a84df97a5180e0655fa8da912d5b09396dc601db16143ac00525a9f16b087b64e4fb6567822f1ed84ba723ffde6ca00f29446a54ce34ad03030e6dd55a992817ede9038436793fa72b7133fcded9443d2340b7dcfb45b02230121c5d0d2958cff63a5633db92b61ed9524f74d230a5429c76a02e12f096e611cc978893683429f89cf03a52533039ae3b7c092589aa9f60cb67b19d5849533c254986a614909ee5765097935f7b162842c09d315526f5f3d77c817eff16204fbe6c949b44e1ac1052482774279e76377431123a189d6716ddff6157c6708985f8f01277d67871e915adcc83119440c8cf6e121911b6d748a4c4b15537273379965ecb0bd89862936cfd7a45d9138b93e564596de4ae5099a371f8cf95f692dffe46523ad5bb0482891df72eac651b9c42f191841e3ad68b0459619367f0341523a03a61ecda6694a7dbcaf1f6d9d11c8c6f132fda2beca91f84cd01d78e2854b5aac4ad7219bff38f94e131e065a48961e6e5468690d0122c832f3ee5570fbed1547d91bc202151d3757d432f1edc793c5f37cf6bd34a9af42970ccb01ae1696ba75067c743b58b9ca4e81e1d7a69203c3b62609150effaab450dd4a0b20d68a31be560808c097f046924acd6e9fc18e3f5d28e698d658a96b06821737a511616bdcb4237c5d3dedd56e53d758bb2d695f52ee58cb49bff3563d38c30411c22e7393b61797d79755a4ea5f9b1232283e4b802100199633b03277e398f70f3e0ef8e7a4b7bf396aba1d55f53a2e03ef089c6720dc456715b08bb94f754d211037c15e0b2078d6226a7a31f4e8f19d885adae07244132dcf0605873a19d4dbef5a03f425975e796956827d6d66072675d10ac87a02db325559bdc9643a32a0beb93723fc3fdbb218b5c2c9d3c2ca9dec65392e1a0fbe0732e66547335f69ab4b81064a4d3fb9830d0e3c547e2a6a554f22928e8762e8941f6f5f5cc509319fb85a2cbf0e433be5a225f94c693bb0691a8ecdba58f71104e12f7cc056a10ae17856e059fb126ea1a5fa43a40f4367901212a3decbea31e0756c37587ff4fdd0271825aa48e0105f8af667977a823fe051dfaa1fb4014f50d6222fed9ccd8787c77563d83e3e52435cf19806c662596988442b39f2611fc80a8ee561bc3f944320b3f7ebaae1fc592e7a823c0967ceedf898b6f805224a3353f92121fb22fb16dbdc41cc066c1f5efaa42945ad4b6326fe73e4b3b34371c64871a99d97bec407ec53b9b01a332ada7a81f8f5f576aedd96b7ec0f51f9977c2ca8c40fbd66779a4743db1622619d23940c59f72b055674bd9ab331a20db20bbcdef4d8184929b1b6bcfc5f155ff0d263e37145f5c98cde541dda165943dec7a56deb81b8f1bd279acfcc8e16e9a968263f8d5c8793e7311a4fe2d114c9d601bf315df05317c0ad89c34e363af79ca4f0c6618f0da51cb8930f2d525779a64f3b657ff0e8b1106ce4f63f775b4cf6', 'hex')) }) - it('should return the reserved', (done) => { - verifyPath( + + it('should return the reserved', async () => { + return verifyPath( fixtureBlockHeader, 'reserved', - Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex'), - done) + Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex')) }) - it('should error on non-existent path', (done) => { - verifyError(fixtureBlockHeader, 'something/random', done) + it('should error on non-existent path', async () => { + return verifyError(fixtureBlockHeader, 'something/random') }) - it('should error on path starting with a slash', (done) => { - verifyError(fixtureBlockHeader, '/version', done) + it('should error on path starting with a slash', async () => { + return verifyError(fixtureBlockHeader, '/version') }) - it('should error on partially matching path that isn\'t a link', (done) => { - verifyError(fixtureBlockHeader, 'version/but/additional/things', done) + it('should error on partially matching path that isn\'t a link', async () => { + return verifyError(fixtureBlockHeader, 'version/but/additional/things') }) - it('should return a link when parent is requested', (done) => { - IpldZcash.resolver.resolve(fixtureBlockHeader, 'parent', (err, value) => { - expect(err).to.not.exist() - expect(value.remainderPath).is.empty() - expect(value.value).to.deep.equal({ - '/': new CID('z4QJh987XTweMqSLmNakYhbReGF55QBJY1P3WqgSYKsfWuwCvHM')}) - done() + it('should return a link when parent is requested', async () => { + const value = await IpldZcash.resolver.resolve(fixtureBlockHeader, 'parent') + expect(value.remainderPath).is.empty() + expect(value.value).to.deep.equal({ + '/': new CID('z4QJh987XTweMqSLmNakYhbReGF55QBJY1P3WqgSYKsfWuwCvHM') }) }) - it('should return a link and remaining path when parent is requested', - (done) => { - IpldZcash.resolver.resolve(fixtureBlockHeader, 'parent/timestamp', - (err, value) => { - expect(err).to.not.exist() - expect(value.remainderPath).to.equal('timestamp') - expect(value.value).to.deep.equal({ - '/': - new CID('z4QJh987XTweMqSLmNakYhbReGF55QBJY1P3WqgSYKsfWuwCvHM')}) - done() - }) + it('should return a link and remaining path when parent is requested', async () => { + const value = await IpldZcash.resolver.resolve(fixtureBlockHeader, 'parent/timestamp') + expect(value.remainderPath).to.equal('timestamp') + expect(value.value).to.deep.equal({ + '/': + new CID('z4QJh987XTweMqSLmNakYhbReGF55QBJY1P3WqgSYKsfWuwCvHM') }) - - it('should return a link when transactions are requested', (done) => { - IpldZcash.resolver.resolve(fixtureBlockHeader, 'tx/some/remainder', - (err, value) => { - expect(err).to.not.exist() - expect(value.remainderPath).to.equal('some/remainder') - expect(value.value).to.deep.equal({ - '/': new CID('z4QJh987RUUrqpBCCdGuhVMh6Gr21KxokFeHppiNiydiydNEut9')}) - done() - }) - }) - - it('should return an error if block is invalid', (done) => { - verifyError(invalidBlock, 'version', done) }) -}) -describe('IPLD format resolver API tree()', () => { - it('should return only paths by default', (done) => { - IpldZcash.resolver.tree(fixtureBlockHeader, (err, value) => { - expect(err).to.not.exist() - expect(value).to.deep.equal(['version', 'timestamp', 'difficulty', - 'nonce', 'solution', 'reserved', 'parent', 'tx']) - done() + it('should return a link when transactions are requested', async () => { + const value = await IpldZcash.resolver.resolve(fixtureBlockHeader, 'tx/some/remainder') + expect(value.remainderPath).to.equal('some/remainder') + expect(value.value).to.deep.equal({ + '/': new CID('z4QJh987RUUrqpBCCdGuhVMh6Gr21KxokFeHppiNiydiydNEut9') }) }) - it('should be able to return paths and values', (done) => { - IpldZcash.resolver.tree(fixtureBlockHeader, {values: true}, (err, value) => { - expect(err).to.not.exist() - expect(value).to.deep.equal({ - version: 4, - timestamp: 1481233847, - difficulty: 477875354, - nonce: Buffer.from( - '8200000000000000d548af969ea8dceedb6bfad4000000000000000000000000', - 'hex'), - reserved: Buffer.from( - '0000000000000000000000000000000000000000000000000000000000000000', - 'hex'), - solution: Buffer.from('005836fdbc8a7a7d9cbec4f059ba17f62d0e775b19035c8e18f123d3a99f270118325eaac526ae7a68d60c9c8c5acdc3e71e987020cb55ad92e0c37af0ab200d3a19e366389bdfe53cd79f70dbc4a67ea6fdc3700f25e0b1d49cee31a54ba8cf826b34c2561c97a0c239e2872c74a33c41690a44e0de741283d60dbfb738152a90d84b1b8f4dce36c3323d35275e8c43f464e9401b757a85392335fdba2432eda2b225b9549faee001d0ebadf24c106f353a02788c386a2f6bce7d83422e8d3ba8ff5cdd85429484a67c76ce31bfacf968621f0b72d9334dfee6b430d2a811f7954548b419fb9428b6d9a09e1317774ebb628d4dd8f334fbe4fb80200f226af20f1cd089849c6207c9d87869baba2e473b0f6b07e68ada56955322d31879c5653a1a84df97a5180e0655fa8da912d5b09396dc601db16143ac00525a9f16b087b64e4fb6567822f1ed84ba723ffde6ca00f29446a54ce34ad03030e6dd55a992817ede9038436793fa72b7133fcded9443d2340b7dcfb45b02230121c5d0d2958cff63a5633db92b61ed9524f74d230a5429c76a02e12f096e611cc978893683429f89cf03a52533039ae3b7c092589aa9f60cb67b19d5849533c254986a614909ee5765097935f7b162842c09d315526f5f3d77c817eff16204fbe6c949b44e1ac1052482774279e76377431123a189d6716ddff6157c6708985f8f01277d67871e915adcc83119440c8cf6e121911b6d748a4c4b15537273379965ecb0bd89862936cfd7a45d9138b93e564596de4ae5099a371f8cf95f692dffe46523ad5bb0482891df72eac651b9c42f191841e3ad68b0459619367f0341523a03a61ecda6694a7dbcaf1f6d9d11c8c6f132fda2beca91f84cd01d78e2854b5aac4ad7219bff38f94e131e065a48961e6e5468690d0122c832f3ee5570fbed1547d91bc202151d3757d432f1edc793c5f37cf6bd34a9af42970ccb01ae1696ba75067c743b58b9ca4e81e1d7a69203c3b62609150effaab450dd4a0b20d68a31be560808c097f046924acd6e9fc18e3f5d28e698d658a96b06821737a511616bdcb4237c5d3dedd56e53d758bb2d695f52ee58cb49bff3563d38c30411c22e7393b61797d79755a4ea5f9b1232283e4b802100199633b03277e398f70f3e0ef8e7a4b7bf396aba1d55f53a2e03ef089c6720dc456715b08bb94f754d211037c15e0b2078d6226a7a31f4e8f19d885adae07244132dcf0605873a19d4dbef5a03f425975e796956827d6d66072675d10ac87a02db325559bdc9643a32a0beb93723fc3fdbb218b5c2c9d3c2ca9dec65392e1a0fbe0732e66547335f69ab4b81064a4d3fb9830d0e3c547e2a6a554f22928e8762e8941f6f5f5cc509319fb85a2cbf0e433be5a225f94c693bb0691a8ecdba58f71104e12f7cc056a10ae17856e059fb126ea1a5fa43a40f4367901212a3decbea31e0756c37587ff4fdd0271825aa48e0105f8af667977a823fe051dfaa1fb4014f50d6222fed9ccd8787c77563d83e3e52435cf19806c662596988442b39f2611fc80a8ee561bc3f944320b3f7ebaae1fc592e7a823c0967ceedf898b6f805224a3353f92121fb22fb16dbdc41cc066c1f5efaa42945ad4b6326fe73e4b3b34371c64871a99d97bec407ec53b9b01a332ada7a81f8f5f576aedd96b7ec0f51f9977c2ca8c40fbd66779a4743db1622619d23940c59f72b055674bd9ab331a20db20bbcdef4d8184929b1b6bcfc5f155ff0d263e37145f5c98cde541dda165943dec7a56deb81b8f1bd279acfcc8e16e9a968263f8d5c8793e7311a4fe2d114c9d601bf315df05317c0ad89c34e363af79ca4f0c6618f0da51cb8930f2d525779a64f3b657ff0e8b1106ce4f63f775b4cf6', 'hex'), - parent: { - '/': new CID('z4QJh987XTweMqSLmNakYhbReGF55QBJY1P3WqgSYKsfWuwCvHM')}, - tx: { - '/': new CID('z4QJh987RUUrqpBCCdGuhVMh6Gr21KxokFeHppiNiydiydNEut9')}}) - done() - }) + it('should return an error if block is invalid', async () => { + return verifyError(invalidBlock, 'version') }) +}) - it('should return an error if block is invalid', (done) => { - IpldZcash.resolver.tree(invalidBlock, (err, value) => { - expect(value).to.not.exist() - expect(err).to.be.an('error') - done() - }) +describe('IPLD format resolver API tree()', () => { + it('should return only paths by default', async () => { + const value = await IpldZcash.resolver.tree(fixtureBlockHeader) + expect(value).to.deep.equal(['version', 'timestamp', 'difficulty', + 'nonce', 'solution', 'reserved', 'parent', 'tx']) + }) + + it('should be able to return paths and values', async () => { + const value = await IpldZcash.resolver.tree(fixtureBlockHeader, {values: true}) + expect(value).to.deep.equal({ + version: 4, + timestamp: 1481233847, + difficulty: 477875354, + nonce: Buffer.from( + '8200000000000000d548af969ea8dceedb6bfad4000000000000000000000000', + 'hex'), + reserved: Buffer.from( + '0000000000000000000000000000000000000000000000000000000000000000', + 'hex'), + solution: Buffer.from('005836fdbc8a7a7d9cbec4f059ba17f62d0e775b19035c8e18f123d3a99f270118325eaac526ae7a68d60c9c8c5acdc3e71e987020cb55ad92e0c37af0ab200d3a19e366389bdfe53cd79f70dbc4a67ea6fdc3700f25e0b1d49cee31a54ba8cf826b34c2561c97a0c239e2872c74a33c41690a44e0de741283d60dbfb738152a90d84b1b8f4dce36c3323d35275e8c43f464e9401b757a85392335fdba2432eda2b225b9549faee001d0ebadf24c106f353a02788c386a2f6bce7d83422e8d3ba8ff5cdd85429484a67c76ce31bfacf968621f0b72d9334dfee6b430d2a811f7954548b419fb9428b6d9a09e1317774ebb628d4dd8f334fbe4fb80200f226af20f1cd089849c6207c9d87869baba2e473b0f6b07e68ada56955322d31879c5653a1a84df97a5180e0655fa8da912d5b09396dc601db16143ac00525a9f16b087b64e4fb6567822f1ed84ba723ffde6ca00f29446a54ce34ad03030e6dd55a992817ede9038436793fa72b7133fcded9443d2340b7dcfb45b02230121c5d0d2958cff63a5633db92b61ed9524f74d230a5429c76a02e12f096e611cc978893683429f89cf03a52533039ae3b7c092589aa9f60cb67b19d5849533c254986a614909ee5765097935f7b162842c09d315526f5f3d77c817eff16204fbe6c949b44e1ac1052482774279e76377431123a189d6716ddff6157c6708985f8f01277d67871e915adcc83119440c8cf6e121911b6d748a4c4b15537273379965ecb0bd89862936cfd7a45d9138b93e564596de4ae5099a371f8cf95f692dffe46523ad5bb0482891df72eac651b9c42f191841e3ad68b0459619367f0341523a03a61ecda6694a7dbcaf1f6d9d11c8c6f132fda2beca91f84cd01d78e2854b5aac4ad7219bff38f94e131e065a48961e6e5468690d0122c832f3ee5570fbed1547d91bc202151d3757d432f1edc793c5f37cf6bd34a9af42970ccb01ae1696ba75067c743b58b9ca4e81e1d7a69203c3b62609150effaab450dd4a0b20d68a31be560808c097f046924acd6e9fc18e3f5d28e698d658a96b06821737a511616bdcb4237c5d3dedd56e53d758bb2d695f52ee58cb49bff3563d38c30411c22e7393b61797d79755a4ea5f9b1232283e4b802100199633b03277e398f70f3e0ef8e7a4b7bf396aba1d55f53a2e03ef089c6720dc456715b08bb94f754d211037c15e0b2078d6226a7a31f4e8f19d885adae07244132dcf0605873a19d4dbef5a03f425975e796956827d6d66072675d10ac87a02db325559bdc9643a32a0beb93723fc3fdbb218b5c2c9d3c2ca9dec65392e1a0fbe0732e66547335f69ab4b81064a4d3fb9830d0e3c547e2a6a554f22928e8762e8941f6f5f5cc509319fb85a2cbf0e433be5a225f94c693bb0691a8ecdba58f71104e12f7cc056a10ae17856e059fb126ea1a5fa43a40f4367901212a3decbea31e0756c37587ff4fdd0271825aa48e0105f8af667977a823fe051dfaa1fb4014f50d6222fed9ccd8787c77563d83e3e52435cf19806c662596988442b39f2611fc80a8ee561bc3f944320b3f7ebaae1fc592e7a823c0967ceedf898b6f805224a3353f92121fb22fb16dbdc41cc066c1f5efaa42945ad4b6326fe73e4b3b34371c64871a99d97bec407ec53b9b01a332ada7a81f8f5f576aedd96b7ec0f51f9977c2ca8c40fbd66779a4743db1622619d23940c59f72b055674bd9ab331a20db20bbcdef4d8184929b1b6bcfc5f155ff0d263e37145f5c98cde541dda165943dec7a56deb81b8f1bd279acfcc8e16e9a968263f8d5c8793e7311a4fe2d114c9d601bf315df05317c0ad89c34e363af79ca4f0c6618f0da51cb8930f2d525779a64f3b657ff0e8b1106ce4f63f775b4cf6', 'hex'), + parent: { + '/': new CID('z4QJh987XTweMqSLmNakYhbReGF55QBJY1P3WqgSYKsfWuwCvHM')}, + tx: { + '/': new CID('z4QJh987RUUrqpBCCdGuhVMh6Gr21KxokFeHppiNiydiydNEut9')}}) + }) + + it('should return an error if block is invalid', async () => { + return shouldThrow(IpldZcash.resolver.tree(invalidBlock)) }) }) @@ -172,19 +145,23 @@ describe('IPLD format resolver API properties', () => { }) }) -const verifyPath = (block, path, expected, done) => { - IpldZcash.resolver.resolve(block, path, (err, value) => { - expect(err).to.not.exist() - expect(value.remainderPath).is.empty() - expect(value.value).to.deep.equal(expected) - done() - }) +const verifyPath = async (block, path, expected) => { + const value = await IpldZcash.resolver.resolve(block, path) + expect(value.remainderPath).is.empty() + expect(value.value).to.deep.equal(expected) } -const verifyError = (block, path, done) => { - IpldZcash.resolver.resolve(block, path, (err, value) => { - expect(value).to.not.exist() - expect(err).to.be.an('error') - done() - }) +const verifyError = async (block, path) => { + return shouldThrow(IpldZcash.resolver.resolve(block, path)) +} + +const shouldThrow = async (promise) => { + try { + await promise + } catch (e) { + expect(e).to.exist() + return + } + + throw new Error('should have thrown') } diff --git a/test/util.spec.js b/test/util.spec.js index 0ce9042..84e939a 100644 --- a/test/util.spec.js +++ b/test/util.spec.js @@ -14,114 +14,81 @@ const fixtureBlockHeader = helpers.headerFromHexBlock(fixtureBlockHex) const invalidDagNode = {invalid: 'dagNode'} describe('IPLD format util API deserialize()', () => { - it('should work correctly', (done) => { - IpldZcash.util.deserialize(fixtureBlockHeader, (err, dagNode) => { - expect(err).to.not.exist() - verifyBlock(dagNode, { - version: 4, - prevHash: '960143fe2c5e22cc0bf0cd5534d7f7f4347f4e75223d07379b9af71400000000', - merkleRoot: '947863a7d7a980a00ef54ce761dcb7b21f4b95fdaf4822f16f37a0e2dea8643e', - reserved: '0000000000000000000000000000000000000000000000000000000000000000', - time: 1481233847, - bits: 477875354, - nonce: '8200000000000000d548af969ea8dceedb6bfad4000000000000000000000000', - solution: '005836fdbc8a7a7d9cbec4f059ba17f62d0e775b19035c8e18f123d3a99f270118325eaac526ae7a68d60c9c8c5acdc3e71e987020cb55ad92e0c37af0ab200d3a19e366389bdfe53cd79f70dbc4a67ea6fdc3700f25e0b1d49cee31a54ba8cf826b34c2561c97a0c239e2872c74a33c41690a44e0de741283d60dbfb738152a90d84b1b8f4dce36c3323d35275e8c43f464e9401b757a85392335fdba2432eda2b225b9549faee001d0ebadf24c106f353a02788c386a2f6bce7d83422e8d3ba8ff5cdd85429484a67c76ce31bfacf968621f0b72d9334dfee6b430d2a811f7954548b419fb9428b6d9a09e1317774ebb628d4dd8f334fbe4fb80200f226af20f1cd089849c6207c9d87869baba2e473b0f6b07e68ada56955322d31879c5653a1a84df97a5180e0655fa8da912d5b09396dc601db16143ac00525a9f16b087b64e4fb6567822f1ed84ba723ffde6ca00f29446a54ce34ad03030e6dd55a992817ede9038436793fa72b7133fcded9443d2340b7dcfb45b02230121c5d0d2958cff63a5633db92b61ed9524f74d230a5429c76a02e12f096e611cc978893683429f89cf03a52533039ae3b7c092589aa9f60cb67b19d5849533c254986a614909ee5765097935f7b162842c09d315526f5f3d77c817eff16204fbe6c949b44e1ac1052482774279e76377431123a189d6716ddff6157c6708985f8f01277d67871e915adcc83119440c8cf6e121911b6d748a4c4b15537273379965ecb0bd89862936cfd7a45d9138b93e564596de4ae5099a371f8cf95f692dffe46523ad5bb0482891df72eac651b9c42f191841e3ad68b0459619367f0341523a03a61ecda6694a7dbcaf1f6d9d11c8c6f132fda2beca91f84cd01d78e2854b5aac4ad7219bff38f94e131e065a48961e6e5468690d0122c832f3ee5570fbed1547d91bc202151d3757d432f1edc793c5f37cf6bd34a9af42970ccb01ae1696ba75067c743b58b9ca4e81e1d7a69203c3b62609150effaab450dd4a0b20d68a31be560808c097f046924acd6e9fc18e3f5d28e698d658a96b06821737a511616bdcb4237c5d3dedd56e53d758bb2d695f52ee58cb49bff3563d38c30411c22e7393b61797d79755a4ea5f9b1232283e4b802100199633b03277e398f70f3e0ef8e7a4b7bf396aba1d55f53a2e03ef089c6720dc456715b08bb94f754d211037c15e0b2078d6226a7a31f4e8f19d885adae07244132dcf0605873a19d4dbef5a03f425975e796956827d6d66072675d10ac87a02db325559bdc9643a32a0beb93723fc3fdbb218b5c2c9d3c2ca9dec65392e1a0fbe0732e66547335f69ab4b81064a4d3fb9830d0e3c547e2a6a554f22928e8762e8941f6f5f5cc509319fb85a2cbf0e433be5a225f94c693bb0691a8ecdba58f71104e12f7cc056a10ae17856e059fb126ea1a5fa43a40f4367901212a3decbea31e0756c37587ff4fdd0271825aa48e0105f8af667977a823fe051dfaa1fb4014f50d6222fed9ccd8787c77563d83e3e52435cf19806c662596988442b39f2611fc80a8ee561bc3f944320b3f7ebaae1fc592e7a823c0967ceedf898b6f805224a3353f92121fb22fb16dbdc41cc066c1f5efaa42945ad4b6326fe73e4b3b34371c64871a99d97bec407ec53b9b01a332ada7a81f8f5f576aedd96b7ec0f51f9977c2ca8c40fbd66779a4743db1622619d23940c59f72b055674bd9ab331a20db20bbcdef4d8184929b1b6bcfc5f155ff0d263e37145f5c98cde541dda165943dec7a56deb81b8f1bd279acfcc8e16e9a968263f8d5c8793e7311a4fe2d114c9d601bf315df05317c0ad89c34e363af79ca4f0c6618f0da51cb8930f2d525779a64f3b657ff0e8b1106ce4f63f775b4cf6' - }) - done() + it('should work correctly', async () => { + const dagNode = await IpldZcash.util.deserialize(fixtureBlockHeader) + return verifyBlock(dagNode, { + version: 4, + prevHash: '960143fe2c5e22cc0bf0cd5534d7f7f4347f4e75223d07379b9af71400000000', + merkleRoot: '947863a7d7a980a00ef54ce761dcb7b21f4b95fdaf4822f16f37a0e2dea8643e', + reserved: '0000000000000000000000000000000000000000000000000000000000000000', + time: 1481233847, + bits: 477875354, + nonce: '8200000000000000d548af969ea8dceedb6bfad4000000000000000000000000', + solution: '005836fdbc8a7a7d9cbec4f059ba17f62d0e775b19035c8e18f123d3a99f270118325eaac526ae7a68d60c9c8c5acdc3e71e987020cb55ad92e0c37af0ab200d3a19e366389bdfe53cd79f70dbc4a67ea6fdc3700f25e0b1d49cee31a54ba8cf826b34c2561c97a0c239e2872c74a33c41690a44e0de741283d60dbfb738152a90d84b1b8f4dce36c3323d35275e8c43f464e9401b757a85392335fdba2432eda2b225b9549faee001d0ebadf24c106f353a02788c386a2f6bce7d83422e8d3ba8ff5cdd85429484a67c76ce31bfacf968621f0b72d9334dfee6b430d2a811f7954548b419fb9428b6d9a09e1317774ebb628d4dd8f334fbe4fb80200f226af20f1cd089849c6207c9d87869baba2e473b0f6b07e68ada56955322d31879c5653a1a84df97a5180e0655fa8da912d5b09396dc601db16143ac00525a9f16b087b64e4fb6567822f1ed84ba723ffde6ca00f29446a54ce34ad03030e6dd55a992817ede9038436793fa72b7133fcded9443d2340b7dcfb45b02230121c5d0d2958cff63a5633db92b61ed9524f74d230a5429c76a02e12f096e611cc978893683429f89cf03a52533039ae3b7c092589aa9f60cb67b19d5849533c254986a614909ee5765097935f7b162842c09d315526f5f3d77c817eff16204fbe6c949b44e1ac1052482774279e76377431123a189d6716ddff6157c6708985f8f01277d67871e915adcc83119440c8cf6e121911b6d748a4c4b15537273379965ecb0bd89862936cfd7a45d9138b93e564596de4ae5099a371f8cf95f692dffe46523ad5bb0482891df72eac651b9c42f191841e3ad68b0459619367f0341523a03a61ecda6694a7dbcaf1f6d9d11c8c6f132fda2beca91f84cd01d78e2854b5aac4ad7219bff38f94e131e065a48961e6e5468690d0122c832f3ee5570fbed1547d91bc202151d3757d432f1edc793c5f37cf6bd34a9af42970ccb01ae1696ba75067c743b58b9ca4e81e1d7a69203c3b62609150effaab450dd4a0b20d68a31be560808c097f046924acd6e9fc18e3f5d28e698d658a96b06821737a511616bdcb4237c5d3dedd56e53d758bb2d695f52ee58cb49bff3563d38c30411c22e7393b61797d79755a4ea5f9b1232283e4b802100199633b03277e398f70f3e0ef8e7a4b7bf396aba1d55f53a2e03ef089c6720dc456715b08bb94f754d211037c15e0b2078d6226a7a31f4e8f19d885adae07244132dcf0605873a19d4dbef5a03f425975e796956827d6d66072675d10ac87a02db325559bdc9643a32a0beb93723fc3fdbb218b5c2c9d3c2ca9dec65392e1a0fbe0732e66547335f69ab4b81064a4d3fb9830d0e3c547e2a6a554f22928e8762e8941f6f5f5cc509319fb85a2cbf0e433be5a225f94c693bb0691a8ecdba58f71104e12f7cc056a10ae17856e059fb126ea1a5fa43a40f4367901212a3decbea31e0756c37587ff4fdd0271825aa48e0105f8af667977a823fe051dfaa1fb4014f50d6222fed9ccd8787c77563d83e3e52435cf19806c662596988442b39f2611fc80a8ee561bc3f944320b3f7ebaae1fc592e7a823c0967ceedf898b6f805224a3353f92121fb22fb16dbdc41cc066c1f5efaa42945ad4b6326fe73e4b3b34371c64871a99d97bec407ec53b9b01a332ada7a81f8f5f576aedd96b7ec0f51f9977c2ca8c40fbd66779a4743db1622619d23940c59f72b055674bd9ab331a20db20bbcdef4d8184929b1b6bcfc5f155ff0d263e37145f5c98cde541dda165943dec7a56deb81b8f1bd279acfcc8e16e9a968263f8d5c8793e7311a4fe2d114c9d601bf315df05317c0ad89c34e363af79ca4f0c6618f0da51cb8930f2d525779a64f3b657ff0e8b1106ce4f63f775b4cf6' }) }) - it('should error on an invalid block', (done) => { + it('should error on an invalid block', async () => { const invalidBlock = Buffer.from('abcdef', 'hex') - IpldZcash.util.deserialize(invalidBlock, (err, dagNode) => { - expect(dagNode).to.not.exist() - expect(err).to.be.an('error') - done() - }) + return shouldThrow(IpldZcash.util.deserialize(invalidBlock)) }) }) describe('IPLD format util API serialize()', () => { - it('should round-trip (de)serialization correctly', (done) => { - IpldZcash.util.deserialize(fixtureBlockHeader, (err, dagNode) => { - expect(err).to.not.exist() - IpldZcash.util.serialize(dagNode, (err, binaryBlob) => { - expect(err).to.not.exist() - expect(binaryBlob).to.deep.equal(fixtureBlockHeader) - done() - }) - }) + it('should round-trip (de)serialization correctly', async () => { + const dagNode = await IpldZcash.util.deserialize(fixtureBlockHeader) + const binaryBlob = await IpldZcash.util.serialize(dagNode) + expect(binaryBlob).to.deep.equal(fixtureBlockHeader) }) - it('should error on an invalid internal representation', (done) => { - IpldZcash.util.serialize(invalidDagNode, (err, binaryBlob) => { - expect(binaryBlob).to.not.exist() - expect(err).to.be.an('error') - done() - }) + it('should error on an invalid internal representation', async () => { + return shouldThrow(IpldZcash.util.serialize(invalidDagNode)) }) }) describe('IPLD format util API cid()', () => { - it('should encode the CID correctly', (done) => { - IpldZcash.util.deserialize(fixtureBlockHeader, (err, dagNode) => { - expect(err).to.not.exist() - verifyCid( - dagNode, - '5620e1451fd8fecefdd9d443f294bc5ae918301922088ba51d35a2a4672c00000000', - done) - }) + it('should encode the CID correctly', async () => { + const dagNode = await IpldZcash.util.deserialize(fixtureBlockHeader) + return verifyCid( + dagNode, + '5620e1451fd8fecefdd9d443f294bc5ae918301922088ba51d35a2a4672c00000000' + ) }) - it('should encode the CID correctly with default options specified', (done) => { - IpldZcash.util.deserialize(fixtureBlockHeader, (err, dagNode) => { - expect(err).to.not.exist() - verifyCid1( - dagNode, - { version: 1, hashAlg: 'dbl-sha2-256' }, - '5620e1451fd8fecefdd9d443f294bc5ae918301922088ba51d35a2a4672c00000000', - done) - }) + it('should encode the CID correctly with default options specified', async () => { + const dagNode = await IpldZcash.util.deserialize(fixtureBlockHeader) + return verifyCid1( + dagNode, + { version: 1, hashAlg: 'dbl-sha2-256' }, + '5620e1451fd8fecefdd9d443f294bc5ae918301922088ba51d35a2a4672c00000000' + ) }) - it('should encode the CID correctly with options', (done) => { - IpldZcash.util.deserialize(fixtureBlockHeader, (err, dagNode) => { - expect(err).to.not.exist() - verifyCid1( - dagNode, - { hashAlg: 'sha3-256' }, - '1620426585d4624b64080d96788c8199562e73fc60f32fde54a82b36f4204c046ce6', - done) - }) + it('should encode the CID correctly with options', async () => { + const dagNode = await IpldZcash.util.deserialize(fixtureBlockHeader) + return verifyCid1( + dagNode, + { hashAlg: 'sha3-256' }, + '1620426585d4624b64080d96788c8199562e73fc60f32fde54a82b36f4204c046ce6' + ) }) - it('should error unknown hash algorithm', (done) => { - IpldZcash.util.deserialize(fixtureBlockHeader, (err, dagNode) => { - expect(err).to.not.exist() - IpldZcash.util.cid(dagNode, { hashAlg: 'unknown' }, (err, cid) => { - expect(err).to.exist() - done() - }) - }) + it('should error unknown hash algorithm', async () => { + const dagNode = await IpldZcash.util.deserialize(fixtureBlockHeader) + return shouldThrow(IpldZcash.util.cid(dagNode, { hashAlg: 'unknown' })) }) - it('should encode the CID correctly and ignore undefined options', (done) => { - IpldZcash.util.deserialize(fixtureBlockHeader, (err, dagNode) => { - expect(err).to.not.exist() - verifyCid1( - dagNode, - undefined, - '5620e1451fd8fecefdd9d443f294bc5ae918301922088ba51d35a2a4672c00000000', - done) - }) + it('should encode the CID correctly and ignore undefined options', async () => { + const dagNode = await IpldZcash.util.deserialize(fixtureBlockHeader) + return verifyCid1( + dagNode, + undefined, + '5620e1451fd8fecefdd9d443f294bc5ae918301922088ba51d35a2a4672c00000000' + ) }) - it('should error on an invalid internal representation', (done) => { - IpldZcash.util.cid(invalidDagNode, (err, cid) => { - expect(cid).to.not.exist() - expect(err).to.be.an('error') - done() - }) + it('should error on an invalid internal representation', async () => { + return shouldThrow(IpldZcash.util.cid(invalidDagNode)) }) }) @@ -136,18 +103,23 @@ const verifyBlock = (header, expected) => { expect(header.solution.toString('hex')).to.equal(expected.solution) } -const verifyCid = (dagNode, expectedCid, doneCb) => { - IpldZcash.util.cid(dagNode, (err, cid) => { - expect(err).to.not.exist() - expect(cid.multihash.toString('hex')).to.equal(expectedCid) - doneCb() - }) +const verifyCid = async (dagNode, expectedCid) => { + const cid = await IpldZcash.util.cid(dagNode) + expect(cid.multihash.toString('hex')).to.equal(expectedCid) } -const verifyCid1 = (dagNode, options, expectedCid, doneCb) => { - IpldZcash.util.cid(dagNode, options, (err, cid) => { - expect(err).to.not.exist() - expect(cid.multihash.toString('hex')).to.equal(expectedCid) - doneCb() - }) +const verifyCid1 = async (dagNode, options, expectedCid) => { + const cid = await IpldZcash.util.cid(dagNode, options) + expect(cid.multihash.toString('hex')).to.equal(expectedCid) +} + +const shouldThrow = async (promise) => { + try { + await promise + } catch (e) { + expect(e).to.exist() + return + } + + throw new Error('should have thrown') }