/* eslint camelcase: 0 */ const test = require('tape') const { keccak256 } = require('ethereumjs-util') const { MerkleMountainRange } = require('../') const { soliditySha3 } = require('web3-utils') const hashLeaf = (index, dataHash) => { const hash = soliditySha3({ t: 'uint256', v: index }, { t: 'bytes32', v: '0x' + dataHash.toString('hex') }) return hash } const peakBagging = (size, peaks) => { const a = [{ t: 'uint256', v: size }, ...peaks.map(x => ({ t: 'bytes32', v: x.toString('hex') }))] const x = soliditySha3(...a) const b = [{ t: 'uint256', v: size }, { t: 'bytes32', v: x.toString('hex') }] const res = soliditySha3(...b) return res } const hashBranch = (index, left, right) => { const args = [] if (index !== undefined) { args.push({ t: 'uint256', v: index }) } if (left !== undefined) { args.push({ t: 'bytes32', v: '0x' + left.toString('hex') }) } if (right !== undefined) { args.push({ t: 'bytes32', v: '0x' + right.toString('hex') }) } const hash = soliditySha3(...args) return hash } test('merkle mountain range', t => { t.plan(6) const leaves = [ '0xf6c5123c17fe0d9c8fc675504ffa8cc8f1613c185d16fc8099ffab31cc0f39b8', '0x6579ce25f7cc6797b1386af5acc4ff8acc9f8054b65dad5fb0c3b0a32c6c4610', '0x6423808868aca9b46c7ccf2d060ff079cb8cf252f87abe767ea3bdce6c933d0c', '0xf0f21a35fc749991e54d26c2a7e6ae3509667bc0d897ac7bcf6a462d1bbe7996', '0x2db0abbe3ef9894b15b7e5e25b538b68ce19812792e3245746cb16c6cfc14345', '0xfcd354a2e527cb6040e15b1f04aa6df4eb5cd7f250ead21809ef16a348beca6b', '0xe747a507a27368d45b0e9df1b6cc2cff173e3f739daff1e8bbdd7159263ba8ad', '0x07d438f3191418363c43a92bcf0555a8b2cf5451d6854932259ede6096c59ed4', '0xd49690a48a2c2a6772092af6d6eec62cc4285a88997cae9fa4835bf0835c2b4d', '0x50b25445c2139a3cec3c593b49273f1f47af0eb7d9d9ed37667ef5673d163bb9', '0x22a6e30c867f4109491e90313ebd0b1438bd8b559cbe85ee9239aa8902a67e74', '0x1b70b853c66181ccf5d149c263c7cf5e1123d6655bcc0f668c9957db1d98e038', '0x527efa47060e8eead056eb3b2b7c20821bf6e246828fdd835f3ccc16946568b1', '0x22a33bbf9177edebe708656bcbe42b7cf077965d2d5fe268dff8878654db06d6', '0x02c4f6983e8616f6b3e600b3c8b768e71755220a04173b8281440c6b8eb91cd9', '0x3ed1f8b63a683529477f8813c0955ae058048b9a4fd9a706454f73f86baf977f', '0x70153ddc9ab0028e922b6b2f9eb319a9a6f1ae37866e7f9771f2866dfbecbc1d', '0x4c26cfe12f5b2e8b2d992d99c9359a261d0bf50450acb10a5060231b5d41c31c', '0x86da6c8cc46b60f9eec99353c42e144525a202880db5c877d6d55ee0568c66e4', '0x1b6a474c3e33a28104dd0e75484414b9d35e93c878823bc3b4d9fb5a5109e9eb' ] const tree = new MerkleMountainRange(keccak256, leaves, hashLeaf, peakBagging, hashBranch) const root = tree.getHexRoot() const proof = tree.getMerkleProof(2) t.equal(root, '0x5d6caccebed1b6720659b4a6c022b77d7ed5706ece976aaf44b7cf8e34650eb7') t.equal(proof.root.toString('hex'), '5d6caccebed1b6720659b4a6c022b77d7ed5706ece976aaf44b7cf8e34650eb7') t.equal(proof.width, leaves.length) t.deepEqual(proof.peakBagging.map(x => x.toString('hex')), [ '4965af1a91b3f41c5440e5fd5b529aae6fbf28c7c04a4fc151be321fabe4a784', '581f3f6a99cd8f276fd07845f619d1a271d763dd4ab049c7f8ac98602da58b7f' ]) t.deepEqual(proof.siblings.map(x => x.toString('hex')), [ 'd3185c77a90c0b4f44e9c38468ce303924345c756d19f5ee342a1043f308d606', 'fc5341e2e1127e54327c793c2b930ca9ca93cd4db16e234b73d04fdb11fa9df7', 'db3261e4e8d9dcfcc6a4973172a13338a013fb455a7a10ca90bfcc49699688b1', '37bc386efc898c6c36b1c2e5a754dafd614398abf146904bcea607af5068605c' ]) const leaf = leaves[1] const index = 2 const verified = tree.verify(proof.root, proof.width, index, leaf, proof.peakBagging, proof.siblings) t.equal(verified, true) }) test('merkle mountain range - rollUp', t => { t.plan(3) const leaves = [ '0xf6c5123c17fe0d9c8fc675504ffa8cc8f1613c185d16fc8099ffab31cc0f39b8', '0x6579ce25f7cc6797b1386af5acc4ff8acc9f8054b65dad5fb0c3b0a32c6c4610', '0x6423808868aca9b46c7ccf2d060ff079cb8cf252f87abe767ea3bdce6c933d0c', '0xf0f21a35fc749991e54d26c2a7e6ae3509667bc0d897ac7bcf6a462d1bbe7996', '0x2db0abbe3ef9894b15b7e5e25b538b68ce19812792e3245746cb16c6cfc14345', '0xfcd354a2e527cb6040e15b1f04aa6df4eb5cd7f250ead21809ef16a348beca6b', '0xe747a507a27368d45b0e9df1b6cc2cff173e3f739daff1e8bbdd7159263ba8ad', '0x07d438f3191418363c43a92bcf0555a8b2cf5451d6854932259ede6096c59ed4', '0xd49690a48a2c2a6772092af6d6eec62cc4285a88997cae9fa4835bf0835c2b4d', '0x50b25445c2139a3cec3c593b49273f1f47af0eb7d9d9ed37667ef5673d163bb9', '0x22a6e30c867f4109491e90313ebd0b1438bd8b559cbe85ee9239aa8902a67e74', '0x1b70b853c66181ccf5d149c263c7cf5e1123d6655bcc0f668c9957db1d98e038', '0x527efa47060e8eead056eb3b2b7c20821bf6e246828fdd835f3ccc16946568b1', '0x22a33bbf9177edebe708656bcbe42b7cf077965d2d5fe268dff8878654db06d6', '0x02c4f6983e8616f6b3e600b3c8b768e71755220a04173b8281440c6b8eb91cd9', '0x3ed1f8b63a683529477f8813c0955ae058048b9a4fd9a706454f73f86baf977f', '0x70153ddc9ab0028e922b6b2f9eb319a9a6f1ae37866e7f9771f2866dfbecbc1d', '0x4c26cfe12f5b2e8b2d992d99c9359a261d0bf50450acb10a5060231b5d41c31c', '0x86da6c8cc46b60f9eec99353c42e144525a202880db5c877d6d55ee0568c66e4', '0x1b6a474c3e33a28104dd0e75484414b9d35e93c878823bc3b4d9fb5a5109e9eb' ] const tree = new MerkleMountainRange(keccak256, [], hashLeaf, peakBagging, hashBranch) const root = tree.getHexRoot() t.equal(root, '0x') const hashedLeaves = leaves.map(x => keccak256(Buffer.from(x.replace('0x', ''), 'hex'))) const rollupRoot = tree.rollUp(tree.root, tree.width, tree.getPeaks(), hashedLeaves) for (const leaf of leaves) { tree.append(leaf) } const newRoot = tree.getHexRoot() t.equal(newRoot, '0x5d6caccebed1b6720659b4a6c022b77d7ed5706ece976aaf44b7cf8e34650eb7') t.equal(newRoot, tree.bufferToHex(rollupRoot)) })