mirror of
https://github.com/tornadocash/fixed-merkle-tree.git
synced 2024-11-22 01:37:09 +01:00
add shiftEdge method
This commit is contained in:
parent
e0817b8389
commit
5ebbf81959
@ -60,6 +60,14 @@ export class PartialMerkleTree {
|
|||||||
return this._layers[this.levels][0] ?? this._zeros[this.levels]
|
return this._layers[this.levels][0] ?? this._zeros[this.levels]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get edgeIndex(): number {
|
||||||
|
return this._edgeLeaf.index
|
||||||
|
}
|
||||||
|
|
||||||
|
get edgeElement(): Element {
|
||||||
|
return this._edgeLeaf.data
|
||||||
|
}
|
||||||
|
|
||||||
private _buildTree(): void {
|
private _buildTree(): void {
|
||||||
const edgeLeafIndex = this._edgeLeaf.index
|
const edgeLeafIndex = this._edgeLeaf.index
|
||||||
this._leaves = [...Array.from({ length: edgeLeafIndex }, () => null), ...this._leavesAfterEdge]
|
this._leaves = [...Array.from({ length: edgeLeafIndex }, () => null), ...this._leavesAfterEdge]
|
||||||
@ -69,7 +77,6 @@ export class PartialMerkleTree {
|
|||||||
this._layers = [this._leaves]
|
this._layers = [this._leaves]
|
||||||
this._buildZeros()
|
this._buildZeros()
|
||||||
this._buildHashes()
|
this._buildHashes()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _buildZeros() {
|
private _buildZeros() {
|
||||||
@ -210,6 +217,25 @@ export class PartialMerkleTree {
|
|||||||
return this.path(index)
|
return this.path(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shifts edge of tree to left
|
||||||
|
* @param edge new TreeEdge below current edge
|
||||||
|
* @param elements leaves between old and new edge
|
||||||
|
*/
|
||||||
|
|
||||||
|
shiftEdge(edge: TreeEdge, elements: Element[]) {
|
||||||
|
if (this._edgeLeaf.index <= edge.edgeIndex) {
|
||||||
|
throw new Error(`New edgeIndex should be smaller then ${this._edgeLeaf.index}`)
|
||||||
|
}
|
||||||
|
if (elements.length !== (this._edgeLeaf.index - edge.edgeIndex)) {
|
||||||
|
throw new Error(`Elements length should be ${elements.length}`)
|
||||||
|
}
|
||||||
|
this._edgeLeafProof = edge.edgePath
|
||||||
|
this._edgeLeaf = { index: edge.edgeIndex, data: edge.edgeElement }
|
||||||
|
this._leavesAfterEdge = [...elements, ...this._leavesAfterEdge]
|
||||||
|
this._buildTree()
|
||||||
|
}
|
||||||
|
|
||||||
serialize(): SerializedPartialTreeState {
|
serialize(): SerializedPartialTreeState {
|
||||||
const leaves = this.layers[0].slice(this._edgeLeaf.index)
|
const leaves = this.layers[0].slice(this._edgeLeaf.index)
|
||||||
return {
|
return {
|
||||||
|
@ -224,7 +224,31 @@ describe('PartialMerkleTree', () => {
|
|||||||
should().throw(call, 'Index 2 is below the edge: 4')
|
should().throw(call, 'Index 2 is below the edge: 4')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
describe('#shiftEdge', () => {
|
||||||
|
it('should work', () => {
|
||||||
|
const levels = 20
|
||||||
|
const elements: Element[] = Array.from({ length: levels ** 2 }, (_, i) => i)
|
||||||
|
const tree = new MerkleTree(levels, elements)
|
||||||
|
const edge1 = tree.getTreeEdge(200)
|
||||||
|
const edge2 = tree.getTreeEdge(100)
|
||||||
|
const partialTree1 = new PartialMerkleTree(levels, edge1, elements.slice(edge1.edgeIndex), tree.root)
|
||||||
|
const partialTree2 = new PartialMerkleTree(levels, edge2, elements.slice(edge2.edgeIndex), tree.root)
|
||||||
|
partialTree1.shiftEdge(edge2, elements.slice(edge2.edgeIndex, partialTree1.edgeIndex))
|
||||||
|
assert.deepEqual(partialTree1.path(105), partialTree2.path(105))
|
||||||
|
})
|
||||||
|
it('should fail if new edge index is over current edge', () => {
|
||||||
|
const { fullTree, partialTree } = getTestTrees(10, [1, 2, 3, 4, 5, 6, 7, 8, 9], 5)
|
||||||
|
const newEdge = fullTree.getTreeEdge(6)
|
||||||
|
const call = () => partialTree.shiftEdge(newEdge, [1, 2])
|
||||||
|
should().throw(call, 'New edgeIndex should be smaller then 4')
|
||||||
|
})
|
||||||
|
it('should fail if elements length are incorrect', () => {
|
||||||
|
const { fullTree, partialTree } = getTestTrees(10, [1, 2, 3, 4, 5, 6, 7, 8, 9], 5)
|
||||||
|
const newEdge = fullTree.getTreeEdge(4)
|
||||||
|
const call = () => partialTree.shiftEdge(newEdge, [1, 2])
|
||||||
|
should().throw(call, 'Elements length should be 2')
|
||||||
|
})
|
||||||
|
})
|
||||||
describe('#serialize', () => {
|
describe('#serialize', () => {
|
||||||
it('should work', () => {
|
it('should work', () => {
|
||||||
const { partialTree } = getTestTrees(5, [1, 2, 3, 4, 5, 6, 7, 8, 9], 6)
|
const { partialTree } = getTestTrees(5, [1, 2, 3, 4, 5, 6, 7, 8, 9], 6)
|
||||||
|
Loading…
Reference in New Issue
Block a user