Skip to content
This repository has been archived by the owner on Aug 11, 2021. It is now read-only.

[WIP] feat: async await #28

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 2 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ version: "{build}"

environment:
matrix:
- nodejs_version: "6"
- nodejs_version: "8"
- nodejs_version: "10"

matrix:
fast_finish: true
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
118 changes: 46 additions & 72 deletions src/resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -19,96 +17,72 @@ 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<ResolveObject>}
*/
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.<string, *>[]} 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.
*
* @param {Buffer} binaryBlob - Binary representation of a Zcash block
* @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<string[] | Object.<string, *>[]>} -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
Expand Down
74 changes: 16 additions & 58 deletions src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,95 +4,53 @@ 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<Buffer>}
*/
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<dagNode>}
*/
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.
*
* @param {ZcashBlock} dagNode - Internal representation of a Zcash block
* @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<CID>}
*/
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
Expand Down
Loading