From 048efb3ccb695520af54b63dfd8aff28ab59fce5 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Tue, 4 Aug 2020 15:28:44 +0100 Subject: [PATCH 1/3] fix: replace node buffers with unit8arrays This module now accepts Uint8Arrays as well as node Buffers and returns Uint8Arrays. Internally it converts non-Buffers into Buffers because the ethereum libs require that. BREAKING CHANGES: - `util.serialize` returns a `Uint8Array` - `util.cid` returns `CID`s with a breaking API change - see https://github.com/multiformats/js-cid/pull/117 for changes --- eth-block/test/resolver.spec.js | 3 ++- package.json | 13 ++++++------- util/createResolver.js | 5 ++--- util/createTrieResolver.js | 1 - util/createUtil.js | 18 ++++++++++++++---- 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/eth-block/test/resolver.spec.js b/eth-block/test/resolver.spec.js index 081c56f..c4f42de 100644 --- a/eth-block/test/resolver.spec.js +++ b/eth-block/test/resolver.spec.js @@ -9,6 +9,7 @@ const EthBlockHeader = require('ethereumjs-block/header') const multihash = require('multihashes') const multicodec = require('multicodec') const { Buffer } = require('buffer') +const uint8ArrayToString = require('uint8arrays/to-string') const ipldEthBlock = require('../index') const resolver = ipldEthBlock.resolver @@ -51,7 +52,7 @@ describe('IPLD format resolver (local)', () => { const reconstructedCid = new CID(encodedCid) expect(cid.version).to.equal(reconstructedCid.version) expect(cid.codec).to.equal(reconstructedCid.codec) - expect(cid.multihash.toString('hex')).to.equal(reconstructedCid.multihash.toString('hex')) + expect(uint8ArrayToString(cid.multihash, 'base16')).to.equal(uint8ArrayToString(reconstructedCid.multihash, 'base16')) }) describe('resolver.resolve', () => { diff --git a/package.json b/package.json index 0ef05c9..89885fb 100644 --- a/package.json +++ b/package.json @@ -22,21 +22,20 @@ "license": "MIT", "dependencies": { "buffer": "^5.6.0", - "cids": "^0.8.3", + "cids": "^1.0.0", "ethereumjs-account": "^3.0.0", "ethereumjs-block": "^2.2.1", "ethereumjs-tx": "^2.1.1", "merkle-patricia-tree": "^3.0.0", - "multicodec": "^1.0.0", - "multihashes": "^1.0.1", - "multihashing-async": "^1.0.0", + "multicodec": "^2.0.0", + "multihashes": "^3.0.1", + "multihashing-async": "^2.0.0", "rlp": "^2.2.4" }, "devDependencies": { "aegir": "^25.0.0", - "chai": "^4.2.0", - "dirty-chai": "^2.0.1", - "promisify-es6": "^1.0.3" + "promisify-es6": "^1.0.3", + "uint8arrays": "^1.0.0" }, "contributors": [ "kumavis ", diff --git a/util/createResolver.js b/util/createResolver.js index e243094..9c84e25 100644 --- a/util/createResolver.js +++ b/util/createResolver.js @@ -1,7 +1,6 @@ 'use strict' const CID = require('cids') const multicodec = require('multicodec') -const { Buffer } = require('buffer') const createUtil = require('../util/createUtil') const createResolver = (codec, deserialize) => { @@ -13,7 +12,7 @@ const createResolver = (codec, deserialize) => { * Returns the value or a link and the partial mising path. This way the * IPLD Resolver can fetch the link and continue to resolve. * - * @param {Buffer} binaryBlob - Binary representation of a Ethereum block + * @param {Uint8Array} binaryBlob - Binary representation of a Ethereum block * @param {string} [path='/'] - Path that should be resolved * @returns {Object} result - Result of the path it it was resolved successfully * @returns {*} result.value - Value the path resolves to @@ -48,7 +47,7 @@ const createResolver = (codec, deserialize) => { const _traverse = function * (node, path) { // Traverse only objects and arrays - if (Buffer.isBuffer(node) || CID.isCID(node) || typeof node === 'string' || + if (node instanceof Uint8Array || CID.isCID(node) || typeof node === 'string' || node === null) { return } diff --git a/util/createTrieResolver.js b/util/createTrieResolver.js index 8d48b67..88f0b0c 100644 --- a/util/createTrieResolver.js +++ b/util/createTrieResolver.js @@ -3,7 +3,6 @@ const rlp = require('rlp') const EthTrieNode = require('merkle-patricia-tree/trieNode') const cidFromHash = require('./cidFromHash') const createResolver = require('./createResolver') -const createUtil = require('./createUtil') // A `nibble` is an array of nested keys. So for example `[2, 1, 3]` would // mean an item with value `"foo"` would be in an object like this: diff --git a/util/createUtil.js b/util/createUtil.js index b870538..74c6bd0 100644 --- a/util/createUtil.js +++ b/util/createUtil.js @@ -9,17 +9,27 @@ const createUtil = (codec, deserialize) => { /** * Deserialize Ethereum block into the internal representation. * - * @param {Buffer} serialized - Binary representation of a Ethereum block. + * @param {Uint8Array|Array} serialized - Binary representation of a Ethereum block. * @returns {Object} */ - deserialize, + deserialize: (serialized) => { + if (Array.isArray(serialized)) { + if (!Buffer.isBuffer(serialized[0])) { + serialized = serialized.map(s => Buffer.from(s)) + } + } else if (!Buffer.isBuffer(serialized)) { + serialized = Buffer.from(serialized) + } + + return deserialize(serialized) + }, /** * Serialize internal representation into a binary Ethereum block. * * @param {Object} deserialized - Internal representation of a Bitcoin block - * @returns {Buffer} + * @returns {Uint8Array} */ - serialize: (deserialized) => deserialized._ethObj.serialize(), + serialize: (deserialized) => Uint8Array.from(deserialized._ethObj.serialize()), /** * Calculate the CID of the binary blob. * From 53b98e56d260c531cee59c555cc841fe66dd556b Mon Sep 17 00:00:00 2001 From: achingbrain Date: Tue, 4 Aug 2020 16:09:29 +0100 Subject: [PATCH 2/3] chore: use no-copy buffer conversion --- util/createUtil.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/createUtil.js b/util/createUtil.js index 74c6bd0..35b512c 100644 --- a/util/createUtil.js +++ b/util/createUtil.js @@ -15,10 +15,10 @@ const createUtil = (codec, deserialize) => { deserialize: (serialized) => { if (Array.isArray(serialized)) { if (!Buffer.isBuffer(serialized[0])) { - serialized = serialized.map(s => Buffer.from(s)) + serialized = serialized.map(s => Buffer.from(s, s.byteOffset, s.byteLength)) } } else if (!Buffer.isBuffer(serialized)) { - serialized = Buffer.from(serialized) + serialized = Buffer.from(serialized, serialized.byteOffset, serialized.byteLength) } return deserialize(serialized) From 3c7a6ac82c403116482e27a1c95bf68817f3cf07 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Tue, 4 Aug 2020 16:17:41 +0100 Subject: [PATCH 3/3] chore: refactor expect require --- eth-account-snapshot/test/resolver.spec.js | 4 +--- eth-block-list/test/resolver.spec.js | 4 +--- eth-block/test/resolver.spec.js | 4 +--- eth-state-trie/test/resolver.spec.js | 4 +--- eth-storage-trie/test/resolver.spec.js | 4 +--- eth-tx-trie/test/resolver.spec.js | 4 +--- eth-tx/test/resolver.spec.js | 4 +--- 7 files changed, 7 insertions(+), 21 deletions(-) diff --git a/eth-account-snapshot/test/resolver.spec.js b/eth-account-snapshot/test/resolver.spec.js index 8349f76..c68f157 100644 --- a/eth-account-snapshot/test/resolver.spec.js +++ b/eth-account-snapshot/test/resolver.spec.js @@ -1,9 +1,7 @@ /* eslint-env mocha */ 'use strict' -const chai = require('chai') -chai.use(require('dirty-chai')) -const expect = chai.expect +const { expect } = require('aegir/utils/chai') const dagEthAccount = require('../index') const resolver = dagEthAccount.resolver const Account = require('ethereumjs-account').default diff --git a/eth-block-list/test/resolver.spec.js b/eth-block-list/test/resolver.spec.js index 894c849..d98a8ca 100644 --- a/eth-block-list/test/resolver.spec.js +++ b/eth-block-list/test/resolver.spec.js @@ -1,9 +1,7 @@ /* eslint-env mocha */ 'use strict' -const chai = require('chai') -chai.use(require('dirty-chai')) -const expect = chai.expect +const { expect } = require('aegir/utils/chai') const CID = require('cids') const multihash = require('multihashes') const multicodec = require('multicodec') diff --git a/eth-block/test/resolver.spec.js b/eth-block/test/resolver.spec.js index c4f42de..b2658f3 100644 --- a/eth-block/test/resolver.spec.js +++ b/eth-block/test/resolver.spec.js @@ -1,9 +1,7 @@ /* eslint-env mocha */ 'use strict' -const chai = require('chai') -chai.use(require('dirty-chai')) -const expect = chai.expect +const { expect } = require('aegir/utils/chai') const CID = require('cids') const EthBlockHeader = require('ethereumjs-block/header') const multihash = require('multihashes') diff --git a/eth-state-trie/test/resolver.spec.js b/eth-state-trie/test/resolver.spec.js index e43344a..c5c3de9 100644 --- a/eth-state-trie/test/resolver.spec.js +++ b/eth-state-trie/test/resolver.spec.js @@ -1,9 +1,7 @@ /* eslint-env mocha */ 'use strict' -const chai = require('chai') -chai.use(require('dirty-chai')) -const expect = chai.expect +const { expect } = require('aegir/utils/chai') const Account = require('ethereumjs-account').default const Trie = require('merkle-patricia-tree') const multicodec = require('multicodec') diff --git a/eth-storage-trie/test/resolver.spec.js b/eth-storage-trie/test/resolver.spec.js index 04c356a..4a2d8c1 100644 --- a/eth-storage-trie/test/resolver.spec.js +++ b/eth-storage-trie/test/resolver.spec.js @@ -1,9 +1,7 @@ /* eslint-env mocha */ 'use strict' -const chai = require('chai') -chai.use(require('dirty-chai')) -const expect = chai.expect +const { expect } = require('aegir/utils/chai') const CID = require('cids') const Trie = require('merkle-patricia-tree') const multicodec = require('multicodec') diff --git a/eth-tx-trie/test/resolver.spec.js b/eth-tx-trie/test/resolver.spec.js index 7b53fae..c5389e5 100644 --- a/eth-tx-trie/test/resolver.spec.js +++ b/eth-tx-trie/test/resolver.spec.js @@ -1,9 +1,7 @@ /* eslint-env mocha */ 'use strict' -const chai = require('chai') -chai.use(require('dirty-chai')) -const expect = chai.expect +const { expect } = require('aegir/utils/chai') const CID = require('cids') const EthBlock = require('ethereumjs-block') const EthTx = require('ethereumjs-tx').Transaction diff --git a/eth-tx/test/resolver.spec.js b/eth-tx/test/resolver.spec.js index 7f24c2b..4005fd0 100644 --- a/eth-tx/test/resolver.spec.js +++ b/eth-tx/test/resolver.spec.js @@ -1,9 +1,7 @@ /* eslint-env mocha */ 'use strict' -const chai = require('chai') -chai.use(require('dirty-chai')) -const expect = chai.expect +const { expect } = require('aegir/utils/chai') const Transaction = require('ethereumjs-tx').Transaction const dagEthTx = require('../index') const resolver = dagEthTx.resolver