Skip to content
This repository has been archived by the owner on Dec 6, 2022. It is now read-only.

Better error handling #9

Merged
merged 4 commits into from
Jan 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
42 changes: 30 additions & 12 deletions src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,15 @@ const sha256 = require('hash.js/lib/hash/sha/256')
* @returns {void}
*/
const serialize = (dagNode, callback) => {
const binaryBlob = dagNode.toBuffer()
const err = null
callback(err, binaryBlob)
let err = null
let binaryBlob
try {
binaryBlob = dagNode.toBuffer()
} catch (serializeError) {
err = serializeError
} finally {
callback(err, binaryBlob)
}
}

/**
Expand All @@ -40,9 +46,15 @@ const serialize = (dagNode, callback) => {
* @returns {void}
*/
const deserialize = (binaryBlob, callback) => {
const dagNode = BitcoinjsBlock.fromBuffer(binaryBlob)
const err = null
callback(err, dagNode)
let err = null
let dagNode
try {
dagNode = BitcoinjsBlock.fromBuffer(binaryBlob)
} catch (deserializeError) {
err = deserializeError
} finally {
callback(err, dagNode)
}
}

/**
Expand All @@ -58,13 +70,19 @@ const deserialize = (binaryBlob, callback) => {
* @returns {void}
*/
const cid = (dagNode, callback) => {
// Bitcoin double hashes
const firstHash = sha256().update(dagNode.toBuffer(true)).digest()
const headerHash = sha256().update(Buffer.from(firstHash)).digest()
let err = null
let cid
try {
// Bitcoin double hashes
const firstHash = sha256().update(dagNode.toBuffer(true)).digest()
const headerHash = sha256().update(Buffer.from(firstHash)).digest()

const cid = hashToCid(Buffer.from(headerHash))
const err = null
callback(err, cid)
cid = hashToCid(Buffer.from(headerHash))
} catch (cidError) {
err = cidError
} finally {
callback(err, cid)
}
}

// Convert a Bitcoin hash (as Buffer) to a CID
Expand Down
13 changes: 13 additions & 0 deletions test/resolver.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const IpldBitcoin = require('../src/index')

const fixtureBlockHex = loadFixture(__dirname, 'fixtures/block.hex')
const fixtureBlock = Buffer.from(fixtureBlockHex.toString(), 'hex')
const invalidBlock = Buffer.from('abcdef', 'hex')

describe('IPLD format resolver API resolve()', () => {
it('should return the deserialized node if no path is given', (done) => {
Expand Down Expand Up @@ -88,6 +89,10 @@ describe('IPLD format resolver API resolve()', () => {
done()
})
})

it('should return an error if block is invalid', (done) => {
verifyError(invalidBlock, '/version', done)
})
})

describe('IPLD format resolver API tree()', () => {
Expand Down Expand Up @@ -115,6 +120,14 @@ describe('IPLD format resolver API tree()', () => {
done()
})
})

it('should return an error if block is invalid', (done) => {
IpldBitcoin.resolver.tree(invalidBlock, (err, value) => {
expect(value).to.not.exist()
expect(err).to.be.an('error')
done()
})
})
})

const verifyPath = (block, path, expected, done) => {
Expand Down
88 changes: 59 additions & 29 deletions test/util.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ const expect = chai.expect
chai.use(dirtyChai)
const IpldBitcoin = require('../src/index')

describe('IPLD format util API', () => {
const fixtureBlockHex = loadFixture(__dirname, 'fixtures/block.hex')
const fixtureBlock = Buffer.from(fixtureBlockHex.toString(), 'hex')
const fixtureBlockHex = loadFixture(__dirname, 'fixtures/block.hex')
const fixtureBlock = Buffer.from(fixtureBlockHex.toString(), 'hex')
const invalidDagNode = {invalid: 'dagNode'}

it('should deserialize correctly', (done) => {
describe('IPLD format util API deserialize()', () => {
it('should work correctly', (done) => {
IpldBitcoin.util.deserialize(fixtureBlock, (err, dagNode) => {
expect(err).to.not.exist()
verifyBlock(dagNode, {
Expand All @@ -27,28 +28,7 @@ describe('IPLD format util API', () => {
})
})

it('should round-trip (de)serialization correctly', (done) => {
IpldBitcoin.util.deserialize(fixtureBlock, (err, dagNode) => {
expect(err).to.not.exist()
IpldBitcoin.util.serialize(dagNode, (err, binaryBlob) => {
expect(err).to.not.exist()
expect(binaryBlob.equals(fixtureBlock)).to.be.true()
done()
})
})
})

it('should encode the CID correctly', (done) => {
IpldBitcoin.util.deserialize(fixtureBlock, (err, dagNode) => {
expect(err).to.not.exist()
verifyCid(
dagNode,
'56203ec2c691d447b2fd0d6a94742345af1f351037dab1ab9e900200000000000000',
done)
})
})

it('should decode Segwit correctly (a)', (done) => {
it('should deserialize Segwit correctly (a)', (done) => {
const segwitBlockHex = loadFixture(__dirname, 'fixtures/segwit.hex')
const segwitBlock = Buffer.from(segwitBlockHex.toString(), 'hex')
IpldBitcoin.util.deserialize(segwitBlock, (err, dagNode) => {
Expand All @@ -68,7 +48,7 @@ describe('IPLD format util API', () => {
})
})

it('should decode Segwit correctly (b)', (done) => {
it('should deserialize Segwit correctly (b)', (done) => {
const segwitBlockHex = loadFixture(__dirname, 'fixtures/segwit2.hex')
const segwitBlock = Buffer.from(segwitBlockHex.toString(), 'hex')
IpldBitcoin.util.deserialize(segwitBlock, (err, dagNode) => {
Expand All @@ -88,7 +68,7 @@ describe('IPLD format util API', () => {
})
})

it('should decode Segwit correctly (c)', (done) => {
it('should deserialize Segwit correctly (c)', (done) => {
const segwitBlockHex = loadFixture(__dirname, 'fixtures/segwit3.hex')
const segwitBlock = Buffer.from(segwitBlockHex.toString(), 'hex')
IpldBitcoin.util.deserialize(segwitBlock, (err, dagNode) => {
Expand All @@ -108,7 +88,7 @@ describe('IPLD format util API', () => {
})
})

it('should decode a block without transations', (done) => {
it('should deserialize a block without transactions', (done) => {
const hexData = '01000000000102e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffff0280969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac80969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d1398'
const block = Buffer.from(hexData.toString(), 'hex')
IpldBitcoin.util.deserialize(block, (err, dagNode) => {
Expand All @@ -120,6 +100,56 @@ describe('IPLD format util API', () => {
done)
})
})

it('should error on an invalid block', (done) => {
const invalidBlock = Buffer.from('abcdef', 'hex')
IpldBitcoin.util.deserialize(invalidBlock, (err, dagNode) => {
expect(dagNode).to.not.exist()
expect(err).to.be.an('error')
done()
})
})
})

describe('IPLD format util API serialize()', () => {
it('should round-trip (de)serialization correctly', (done) => {
IpldBitcoin.util.deserialize(fixtureBlock, (err, dagNode) => {
expect(err).to.not.exist()
IpldBitcoin.util.serialize(dagNode, (err, binaryBlob) => {
expect(err).to.not.exist()
expect(binaryBlob).to.deep.equal(fixtureBlock)
done()
})
})
})

it('should error on an invalid internal representation', (done) => {
IpldBitcoin.util.serialize(invalidDagNode, (err, binaryBlob) => {
expect(binaryBlob).to.not.exist()
expect(err).to.be.an('error')
done()
})
})
})

describe('IPLD format util API cid()', () => {
it('should encode the CID correctly', (done) => {
IpldBitcoin.util.deserialize(fixtureBlock, (err, dagNode) => {
expect(err).to.not.exist()
verifyCid(
dagNode,
'56203ec2c691d447b2fd0d6a94742345af1f351037dab1ab9e900200000000000000',
done)
})
})

it('should error on an invalid internal representation', (done) => {
IpldBitcoin.util.cid(invalidDagNode, (err, cid) => {
expect(cid).to.not.exist()
expect(err).to.be.an('error')
done()
})
})
})

const verifyBlock = (dagNode, expected) => {
Expand Down