fix deserialize method

This commit is contained in:
smart_ex 2022-03-28 17:44:50 +10:00
parent cc33277ba1
commit 7d439740b1
9 changed files with 40 additions and 44 deletions

@ -95,7 +95,10 @@ class MerkleTree extends BaseTree_1.BaseTree {
* otherwise the tree state will be invalid * otherwise the tree state will be invalid
*/ */
static deserialize(data, hashFunction) { static deserialize(data, hashFunction) {
return new MerkleTree(data.levels, data._layers[0], { hashFunction, zeroElement: data._zeros[0] }); const instance = Object.assign(Object.create(this.prototype), data);
instance._hashFn = hashFunction || simpleHash_1.default;
instance.zeroElement = instance._zeros[0];
return instance;
} }
toString() { toString() {
return JSON.stringify(this.serialize()); return JSON.stringify(this.serialize());

@ -91,14 +91,15 @@ class PartialMerkleTree extends BaseTree_1.BaseTree {
pathIndices[level] = elIndex % 2; pathIndices[level] = elIndex % 2;
const leafIndex = elIndex ^ 1; const leafIndex = elIndex ^ 1;
if (leafIndex < this._layers[level].length) { if (leafIndex < this._layers[level].length) {
const [proofPos, proofEl] = this._proofMap.get(level); pathElements[level] = this._layers[level][leafIndex];
pathElements[level] = (_a = this._layers[level][leafIndex]) !== null && _a !== void 0 ? _a : (proofPos === leafIndex ? proofEl : null);
pathPositions[level] = leafIndex; pathPositions[level] = leafIndex;
} }
else { else {
pathElements[level] = this._zeros[level]; pathElements[level] = this._zeros[level];
pathPositions[level] = 0; pathPositions[level] = 0;
} }
const [proofPos, proofEl] = this._proofMap.get(level);
pathElements[level] = (_a = pathElements[level]) !== null && _a !== void 0 ? _a : (proofPos === leafIndex ? proofEl : this._zeros[level]);
elIndex >>= 1; elIndex >>= 1;
} }
return { return {
@ -127,27 +128,22 @@ class PartialMerkleTree extends BaseTree_1.BaseTree {
this._buildTree(); this._buildTree();
} }
serialize() { serialize() {
const leaves = this.layers[0].slice(this._edgeLeaf.index);
return { return {
_edgeLeafProof: this._edgeLeafProof, _edgeLeafProof: this._edgeLeafProof,
_edgeLeaf: this._edgeLeaf, _edgeLeaf: this._edgeLeaf,
_edgeElementsCount: this._layers[0].length, _layers: this._layers,
levels: this.levels,
leaves,
_zeros: this._zeros, _zeros: this._zeros,
levels: this.levels,
}; };
} }
static deserialize(data, hashFunction) { static deserialize(data, hashFunction) {
const edge = { const instance = Object.assign(Object.create(this.prototype), data);
edgePath: data._edgeLeafProof, instance._hashFn = hashFunction || simpleHash_1.default;
edgeElement: data._edgeLeaf.data, instance._initialRoot = data._edgeLeafProof.pathRoot;
edgeIndex: data._edgeLeaf.index, instance.zeroElement = instance._zeros[0];
edgeElementsCount: data._edgeElementsCount, instance._leavesAfterEdge = instance._layers[0].slice(data._edgeLeaf.index);
}; instance._createProofMap();
return new PartialMerkleTree(data.levels, edge, data.leaves, { return instance;
hashFunction,
zeroElement: data._zeros[0],
});
} }
toString() { toString() {
return JSON.stringify(this.serialize()); return JSON.stringify(this.serialize());

3
lib/index.d.ts vendored

@ -18,8 +18,7 @@ export declare type SerializedTreeState = {
}; };
export declare type SerializedPartialTreeState = { export declare type SerializedPartialTreeState = {
levels: number; levels: number;
leaves: Element[]; _layers: Element[][];
_edgeElementsCount: number;
_zeros: Array<Element>; _zeros: Array<Element>;
_edgeLeafProof: ProofPath; _edgeLeafProof: ProofPath;
_edgeLeaf: LeafWithIndex; _edgeLeaf: LeafWithIndex;

2
package-lock.json generated

@ -1,6 +1,6 @@
{ {
"name": "fixed-merkle-tree", "name": "fixed-merkle-tree",
"version": "0.7.1", "version": "0.7.3",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

@ -1,6 +1,6 @@
{ {
"name": "fixed-merkle-tree", "name": "fixed-merkle-tree",
"version": "0.7.2", "version": "0.7.3",
"description": "Fixed depth merkle tree implementation with sequential inserts", "description": "Fixed depth merkle tree implementation with sequential inserts",
"repository": "https://github.com/tornadocash/fixed-merkle-tree.git", "repository": "https://github.com/tornadocash/fixed-merkle-tree.git",
"main": "lib/index.js", "main": "lib/index.js",

@ -106,7 +106,10 @@ export default class MerkleTree extends BaseTree {
* otherwise the tree state will be invalid * otherwise the tree state will be invalid
*/ */
static deserialize(data: SerializedTreeState, hashFunction?: HashFunction<Element>): MerkleTree { static deserialize(data: SerializedTreeState, hashFunction?: HashFunction<Element>): MerkleTree {
return new MerkleTree(data.levels, data._layers[0], { hashFunction, zeroElement: data._zeros[0] }) const instance: MerkleTree = Object.assign(Object.create(this.prototype), data)
instance._hashFn = hashFunction || defaultHash
instance.zeroElement = instance._zeros[0]
return instance
} }
toString() { toString() {

@ -113,13 +113,14 @@ export class PartialMerkleTree extends BaseTree {
pathIndices[level] = elIndex % 2 pathIndices[level] = elIndex % 2
const leafIndex = elIndex ^ 1 const leafIndex = elIndex ^ 1
if (leafIndex < this._layers[level].length) { if (leafIndex < this._layers[level].length) {
const [proofPos, proofEl] = this._proofMap.get(level) pathElements[level] = this._layers[level][leafIndex]
pathElements[level] = this._layers[level][leafIndex] ?? (proofPos === leafIndex ? proofEl : null)
pathPositions[level] = leafIndex pathPositions[level] = leafIndex
} else { } else {
pathElements[level] = this._zeros[level] pathElements[level] = this._zeros[level]
pathPositions[level] = 0 pathPositions[level] = 0
} }
const [proofPos, proofEl] = this._proofMap.get(level)
pathElements[level] = pathElements[level] ?? (proofPos === leafIndex ? proofEl : this._zeros[level])
elIndex >>= 1 elIndex >>= 1
} }
return { return {
@ -152,28 +153,23 @@ export class PartialMerkleTree extends BaseTree {
} }
serialize(): SerializedPartialTreeState { serialize(): SerializedPartialTreeState {
const leaves = this.layers[0].slice(this._edgeLeaf.index)
return { return {
_edgeLeafProof: this._edgeLeafProof, _edgeLeafProof: this._edgeLeafProof,
_edgeLeaf: this._edgeLeaf, _edgeLeaf: this._edgeLeaf,
_edgeElementsCount: this._layers[0].length, _layers: this._layers,
levels: this.levels,
leaves,
_zeros: this._zeros, _zeros: this._zeros,
levels: this.levels,
} }
} }
static deserialize(data: SerializedPartialTreeState, hashFunction?: HashFunction<Element>): PartialMerkleTree { static deserialize(data: SerializedPartialTreeState, hashFunction?: HashFunction<Element>): PartialMerkleTree {
const edge: TreeEdge = { const instance: PartialMerkleTree = Object.assign(Object.create(this.prototype), data)
edgePath: data._edgeLeafProof, instance._hashFn = hashFunction || defaultHash
edgeElement: data._edgeLeaf.data, instance._initialRoot = data._edgeLeafProof.pathRoot
edgeIndex: data._edgeLeaf.index, instance.zeroElement = instance._zeros[0]
edgeElementsCount: data._edgeElementsCount, instance._leavesAfterEdge = instance._layers[0].slice(data._edgeLeaf.index)
} instance._createProofMap()
return new PartialMerkleTree(data.levels, edge, data.leaves, { return instance
hashFunction,
zeroElement: data._zeros[0],
})
} }
toString() { toString() {

@ -22,8 +22,7 @@ export type SerializedTreeState = {
export type SerializedPartialTreeState = { export type SerializedPartialTreeState = {
levels: number levels: number
leaves: Element[] _layers: Element[][]
_edgeElementsCount: number
_zeros: Array<Element> _zeros: Array<Element>
_edgeLeafProof: ProofPath _edgeLeafProof: ProofPath
_edgeLeaf: LeafWithIndex _edgeLeaf: LeafWithIndex

@ -276,7 +276,7 @@ describe('PartialMerkleTree', () => {
partialTree.insert(10) partialTree.insert(10)
dst.insert(10) dst.insert(10)
assert.deepStrictEqual(partialTree.path(6), dst.path(6))
should().equal(partialTree.root, dst.root) should().equal(partialTree.root, dst.root)
}) })
}) })
@ -285,12 +285,12 @@ describe('PartialMerkleTree', () => {
const { partialTree } = getTestTrees(5, [1, 2, 3, 4, 5, 6, 7, 8, 9], 5) const { partialTree } = getTestTrees(5, [1, 2, 3, 4, 5, 6, 7, 8, 9], 5)
const str = partialTree.toString() const str = partialTree.toString()
const dst = PartialMerkleTree.deserialize(JSON.parse(str)) const dst = PartialMerkleTree.deserialize(JSON.parse(str))
should().equal(partialTree.root, dst.root) assert.deepStrictEqual(partialTree.path(6), dst.path(6))
partialTree.insert(10) partialTree.insert(10)
dst.insert(10) dst.insert(10)
should().equal(partialTree.root, dst.root) assert.deepStrictEqual(partialTree.path(6), dst.path(6))
assert.deepStrictEqual(partialTree.root, dst.root)
}) })
}) })
}) })