From cc33277ba17d21cd6ac81cb74fe069be7b527a96 Mon Sep 17 00:00:00 2001 From: smart_ex Date: Fri, 25 Mar 2022 15:11:57 +1000 Subject: [PATCH] more test. fix nullish alloc --- lib/PartialMerkleTree.js | 3 ++- package.json | 2 +- src/PartialMerkleTree.ts | 2 +- test/fixedMerkleTree.spec.ts | 13 +++++++++++-- test/partialMerkleTree.spec.ts | 22 ++++++++++++++++------ 5 files changed, 31 insertions(+), 11 deletions(-) diff --git a/lib/PartialMerkleTree.js b/lib/PartialMerkleTree.js index 101f9b6..bc04346 100644 --- a/lib/PartialMerkleTree.js +++ b/lib/PartialMerkleTree.js @@ -76,6 +76,7 @@ class PartialMerkleTree extends BaseTree_1.BaseTree { this._processUpdate(index); } path(index) { + var _a; if (isNaN(Number(index)) || index < 0 || index >= this._layers[0].length) { throw new Error('Index out of bounds: ' + index); } @@ -91,7 +92,7 @@ class PartialMerkleTree extends BaseTree_1.BaseTree { const leafIndex = elIndex ^ 1; if (leafIndex < this._layers[level].length) { const [proofPos, proofEl] = this._proofMap.get(level); - pathElements[level] = this._layers[level][leafIndex] || (proofPos === leafIndex ? proofEl : null); + pathElements[level] = (_a = this._layers[level][leafIndex]) !== null && _a !== void 0 ? _a : (proofPos === leafIndex ? proofEl : null); pathPositions[level] = leafIndex; } else { diff --git a/package.json b/package.json index 4edf257..3b2eda7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fixed-merkle-tree", - "version": "0.7.1", + "version": "0.7.2", "description": "Fixed depth merkle tree implementation with sequential inserts", "repository": "https://github.com/tornadocash/fixed-merkle-tree.git", "main": "lib/index.js", diff --git a/src/PartialMerkleTree.ts b/src/PartialMerkleTree.ts index 3f204a2..074ab90 100644 --- a/src/PartialMerkleTree.ts +++ b/src/PartialMerkleTree.ts @@ -114,7 +114,7 @@ export class PartialMerkleTree extends BaseTree { const leafIndex = elIndex ^ 1 if (leafIndex < this._layers[level].length) { const [proofPos, proofEl] = this._proofMap.get(level) - pathElements[level] = this._layers[level][leafIndex] || (proofPos === leafIndex ? proofEl : null) + pathElements[level] = this._layers[level][leafIndex] ?? (proofPos === leafIndex ? proofEl : null) pathPositions[level] = leafIndex } else { pathElements[level] = this._zeros[level] diff --git a/test/fixedMerkleTree.spec.ts b/test/fixedMerkleTree.spec.ts index ef74d86..649038b 100644 --- a/test/fixedMerkleTree.spec.ts +++ b/test/fixedMerkleTree.spec.ts @@ -294,7 +294,7 @@ describe('MerkleTree', () => { describe('#getTreeSlices', () => { let fullTree: MerkleTree before(async () => { - const elements = Array.from({ length: 2 ** 8 + 11 }, (_, i) => i) + const elements = Array.from({ length: 2 ** 10 }, (_, i) => i) fullTree = new MerkleTree(10, elements) return Promise.resolve() }) @@ -315,12 +315,21 @@ describe('MerkleTree', () => { const lastSlice = slices.pop() const partialTree = new PartialMerkleTree(10, lastSlice.edge, lastSlice.elements) slices.reverse().forEach(({ edge, elements }) => { - console.log(edge.edgeIndex, elements.length) partialTree.shiftEdge(edge, elements) }) assert.deepEqual(fullTree.layers, partialTree.layers) }).timeout(10000) + it('should return same path', () => { + const slices = fullTree.getTreeSlices() + const lastSlice = slices.pop() + const partialTree = new PartialMerkleTree(10, lastSlice.edge, lastSlice.elements) + slices.reverse().forEach(({ edge, elements }) => { + partialTree.shiftEdge(edge, elements) + }) + assert.deepEqual(fullTree.path(100), partialTree.path(100)) + }).timeout(10000) + it('should throw if invalid number of elements', () => { const [firstSlice] = fullTree.getTreeSlices() const call = () => new PartialMerkleTree(10, firstSlice.edge, firstSlice.elements) diff --git a/test/partialMerkleTree.spec.ts b/test/partialMerkleTree.spec.ts index bd3839b..a625ae4 100644 --- a/test/partialMerkleTree.spec.ts +++ b/test/partialMerkleTree.spec.ts @@ -230,20 +230,30 @@ describe('PartialMerkleTree', () => { }) }) describe('#shiftEdge', () => { + const levels = 20 + const elements: Element[] = Array.from({ length: 2 ** 18 }, (_, i) => i) + const tree = new MerkleTree(levels, elements) it('should work', () => { - const levels = 10 - const elements: Element[] = Array.from({ length: 21 ** 2 }, (_, i) => i) - const tree = new MerkleTree(levels, elements) const edge1 = tree.getTreeEdge(200) const edge2 = tree.getTreeEdge(100) - const edge3 = tree.getTreeEdge(10) const partialTree = new PartialMerkleTree(levels, edge1, elements.slice(edge1.edgeIndex)) partialTree.shiftEdge(edge2, elements.slice(edge2.edgeIndex, partialTree.edgeIndex)) - partialTree.shiftEdge(edge3, elements.slice(edge3.edgeIndex, partialTree.edgeIndex)) tree.insert('1111') partialTree.insert('1111') - assert.deepEqual(partialTree.path(50), tree.path(50)) + assert.deepEqual(partialTree.path(150), tree.path(150)) }) + it('should be able to build full tree from slices', () => { + const slices = tree.getTreeSlices(6) + const lastSlice = slices.pop() + const partialTree = new PartialMerkleTree(levels, lastSlice.edge, lastSlice.elements) + for (let i = slices.length - 1; i >= 0; i--) { + partialTree.shiftEdge(slices[i].edge, slices[i].elements) + } + partialTree.insert('1') + tree.insert('1') + assert.deepStrictEqual(partialTree.path(432), tree.path(432)) + }).timeout(10000) + it('should fail if new edge index is over current edge', () => { const { fullTree, partialTree } = getTestTrees(10, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 4) const newEdge = fullTree.getTreeEdge(4)