Use tornado.ws for deps
This commit is contained in:
parent
34d687c319
commit
69066e4fd1
1
.npmrc
Normal file
1
.npmrc
Normal file
@ -0,0 +1 @@
|
|||||||
|
@tornado:registry=https://git.tornado.ws/api/packages/tornado-packages/npm/
|
922
dist/tornado.umd.js
vendored
922
dist/tornado.umd.js
vendored
@ -9508,160 +9508,160 @@ exports.bytes = exports.stringToBytes;
|
|||||||
/***/ ((__unused_webpack_module, exports) => {
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.BaseTree = void 0;
|
exports.BaseTree = void 0;
|
||||||
class BaseTree {
|
class BaseTree {
|
||||||
get capacity() {
|
get capacity() {
|
||||||
return 2 ** this.levels;
|
return 2 ** this.levels;
|
||||||
}
|
}
|
||||||
get layers() {
|
get layers() {
|
||||||
return this._layers.slice();
|
return this._layers.slice();
|
||||||
}
|
}
|
||||||
get zeros() {
|
get zeros() {
|
||||||
return this._zeros.slice();
|
return this._zeros.slice();
|
||||||
}
|
}
|
||||||
get elements() {
|
get elements() {
|
||||||
return this._layers[0].slice();
|
return this._layers[0].slice();
|
||||||
}
|
}
|
||||||
get root() {
|
get root() {
|
||||||
var _a;
|
var _a;
|
||||||
return (_a = this._layers[this.levels][0]) !== null && _a !== void 0 ? _a : this._zeros[this.levels];
|
return (_a = this._layers[this.levels][0]) !== null && _a !== void 0 ? _a : this._zeros[this.levels];
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Find an element in the tree
|
* Find an element in the tree
|
||||||
* @param elements elements of tree
|
* @param elements elements of tree
|
||||||
* @param element An element to find
|
* @param element An element to find
|
||||||
* @param comparator A function that checks leaf value equality
|
* @param comparator A function that checks leaf value equality
|
||||||
* @param fromIndex The index to start the search at. If the index is greater than or equal to the array's length, -1 is returned
|
* @param fromIndex The index to start the search at. If the index is greater than or equal to the array's length, -1 is returned
|
||||||
* @returns {number} Index if element is found, otherwise -1
|
* @returns {number} Index if element is found, otherwise -1
|
||||||
*/
|
*/
|
||||||
static indexOf(elements, element, fromIndex, comparator) {
|
static indexOf(elements, element, fromIndex, comparator) {
|
||||||
if (comparator) {
|
if (comparator) {
|
||||||
return elements.findIndex((el) => comparator(element, el));
|
return elements.findIndex((el) => comparator(element, el));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return elements.indexOf(element, fromIndex);
|
return elements.indexOf(element, fromIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Insert new element into the tree
|
* Insert new element into the tree
|
||||||
* @param element Element to insert
|
* @param element Element to insert
|
||||||
*/
|
*/
|
||||||
insert(element) {
|
insert(element) {
|
||||||
if (this._layers[0].length >= this.capacity) {
|
if (this._layers[0].length >= this.capacity) {
|
||||||
throw new Error('Tree is full');
|
throw new Error('Tree is full');
|
||||||
}
|
}
|
||||||
this.update(this._layers[0].length, element);
|
this.update(this._layers[0].length, element);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Insert multiple elements into the tree.
|
* Insert multiple elements into the tree.
|
||||||
* @param {Array} elements Elements to insert
|
* @param {Array} elements Elements to insert
|
||||||
*/
|
*/
|
||||||
bulkInsert(elements) {
|
bulkInsert(elements) {
|
||||||
if (!elements.length) {
|
if (!elements.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this._layers[0].length + elements.length > this.capacity) {
|
if (this._layers[0].length + elements.length > this.capacity) {
|
||||||
throw new Error('Tree is full');
|
throw new Error('Tree is full');
|
||||||
}
|
}
|
||||||
// First we insert all elements except the last one
|
// First we insert all elements except the last one
|
||||||
// updating only full subtree hashes (all layers where inserted element has odd index)
|
// updating only full subtree hashes (all layers where inserted element has odd index)
|
||||||
// the last element will update the full path to the root making the tree consistent again
|
// the last element will update the full path to the root making the tree consistent again
|
||||||
for (let i = 0; i < elements.length - 1; i++) {
|
for (let i = 0; i < elements.length - 1; i++) {
|
||||||
this._layers[0].push(elements[i]);
|
this._layers[0].push(elements[i]);
|
||||||
let level = 0;
|
let level = 0;
|
||||||
let index = this._layers[0].length - 1;
|
let index = this._layers[0].length - 1;
|
||||||
while (index % 2 === 1) {
|
while (index % 2 === 1) {
|
||||||
level++;
|
level++;
|
||||||
index >>= 1;
|
index >>= 1;
|
||||||
const left = this._layers[level - 1][index * 2];
|
const left = this._layers[level - 1][index * 2];
|
||||||
const right = this._layers[level - 1][index * 2 + 1];
|
const right = this._layers[level - 1][index * 2 + 1];
|
||||||
this._layers[level][index] = this._hashFn(left, right);
|
this._layers[level][index] = this._hashFn(left, right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.insert(elements[elements.length - 1]);
|
this.insert(elements[elements.length - 1]);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Change an element in the tree
|
* Change an element in the tree
|
||||||
* @param {number} index Index of element to change
|
* @param {number} index Index of element to change
|
||||||
* @param element Updated element value
|
* @param element Updated element value
|
||||||
*/
|
*/
|
||||||
update(index, element) {
|
update(index, element) {
|
||||||
if (isNaN(Number(index)) || index < 0 || index > this._layers[0].length || index >= this.capacity) {
|
if (isNaN(Number(index)) || index < 0 || index > this._layers[0].length || index >= this.capacity) {
|
||||||
throw new Error('Insert index out of bounds: ' + index);
|
throw new Error('Insert index out of bounds: ' + index);
|
||||||
}
|
}
|
||||||
this._layers[0][index] = element;
|
this._layers[0][index] = element;
|
||||||
this._processUpdate(index);
|
this._processUpdate(index);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get merkle path to a leaf
|
* Get merkle path to a leaf
|
||||||
* @param {number} index Leaf index to generate path for
|
* @param {number} index Leaf index to generate path for
|
||||||
* @returns {{pathElements: Object[], pathIndex: number[]}} An object containing adjacent elements and left-right index
|
* @returns {{pathElements: Object[], pathIndex: number[]}} An object containing adjacent elements and left-right index
|
||||||
*/
|
*/
|
||||||
path(index) {
|
path(index) {
|
||||||
if (isNaN(Number(index)) || index < 0 || index >= this._layers[0].length) {
|
if (isNaN(Number(index)) || index < 0 || index >= this._layers[0].length) {
|
||||||
throw new Error('Index out of bounds: ' + index);
|
throw new Error('Index out of bounds: ' + index);
|
||||||
}
|
}
|
||||||
let elIndex = +index;
|
let elIndex = +index;
|
||||||
const pathElements = [];
|
const pathElements = [];
|
||||||
const pathIndices = [];
|
const pathIndices = [];
|
||||||
const pathPositions = [];
|
const pathPositions = [];
|
||||||
for (let level = 0; level < this.levels; level++) {
|
for (let level = 0; level < this.levels; level++) {
|
||||||
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) {
|
||||||
pathElements[level] = this._layers[level][leafIndex];
|
pathElements[level] = this._layers[level][leafIndex];
|
||||||
pathPositions[level] = leafIndex;
|
pathPositions[level] = leafIndex;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pathElements[level] = this._zeros[level];
|
pathElements[level] = this._zeros[level];
|
||||||
pathPositions[level] = 0;
|
pathPositions[level] = 0;
|
||||||
}
|
}
|
||||||
elIndex >>= 1;
|
elIndex >>= 1;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
pathElements,
|
pathElements,
|
||||||
pathIndices,
|
pathIndices,
|
||||||
pathPositions,
|
pathPositions,
|
||||||
pathRoot: this.root,
|
pathRoot: this.root,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
_buildZeros() {
|
_buildZeros() {
|
||||||
this._zeros = [this.zeroElement];
|
this._zeros = [this.zeroElement];
|
||||||
for (let i = 1; i <= this.levels; i++) {
|
for (let i = 1; i <= this.levels; i++) {
|
||||||
this._zeros[i] = this._hashFn(this._zeros[i - 1], this._zeros[i - 1]);
|
this._zeros[i] = this._hashFn(this._zeros[i - 1], this._zeros[i - 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_processNodes(nodes, layerIndex) {
|
_processNodes(nodes, layerIndex) {
|
||||||
const length = nodes.length;
|
const length = nodes.length;
|
||||||
let currentLength = Math.ceil(length / 2);
|
let currentLength = Math.ceil(length / 2);
|
||||||
const currentLayer = new Array(currentLength);
|
const currentLayer = new Array(currentLength);
|
||||||
currentLength--;
|
currentLength--;
|
||||||
const starFrom = length - ((length % 2) ^ 1);
|
const starFrom = length - ((length % 2) ^ 1);
|
||||||
let j = 0;
|
let j = 0;
|
||||||
for (let i = starFrom; i >= 0; i -= 2) {
|
for (let i = starFrom; i >= 0; i -= 2) {
|
||||||
if (nodes[i - 1] === undefined)
|
if (nodes[i - 1] === undefined)
|
||||||
break;
|
break;
|
||||||
const left = nodes[i - 1];
|
const left = nodes[i - 1];
|
||||||
const right = (i === starFrom && length % 2 === 1) ? this._zeros[layerIndex - 1] : nodes[i];
|
const right = (i === starFrom && length % 2 === 1) ? this._zeros[layerIndex - 1] : nodes[i];
|
||||||
currentLayer[currentLength - j] = this._hashFn(left, right);
|
currentLayer[currentLength - j] = this._hashFn(left, right);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
return currentLayer;
|
return currentLayer;
|
||||||
}
|
}
|
||||||
_processUpdate(index) {
|
_processUpdate(index) {
|
||||||
for (let level = 1; level <= this.levels; level++) {
|
for (let level = 1; level <= this.levels; level++) {
|
||||||
index >>= 1;
|
index >>= 1;
|
||||||
const left = this._layers[level - 1][index * 2];
|
const left = this._layers[level - 1][index * 2];
|
||||||
const right = index * 2 + 1 < this._layers[level - 1].length
|
const right = index * 2 + 1 < this._layers[level - 1].length
|
||||||
? this._layers[level - 1][index * 2 + 1]
|
? this._layers[level - 1][index * 2 + 1]
|
||||||
: this._zeros[level - 1];
|
: this._zeros[level - 1];
|
||||||
this._layers[level][index] = this._hashFn(left, right);
|
this._layers[level][index] = this._hashFn(left, right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.BaseTree = BaseTree;
|
exports.BaseTree = BaseTree;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@ -9670,120 +9670,120 @@ exports.BaseTree = BaseTree;
|
|||||||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
const simpleHash_1 = __importDefault(__webpack_require__(5319));
|
const simpleHash_1 = __importDefault(__webpack_require__(5319));
|
||||||
const BaseTree_1 = __webpack_require__(7736);
|
const BaseTree_1 = __webpack_require__(7736);
|
||||||
class MerkleTree extends BaseTree_1.BaseTree {
|
class MerkleTree extends BaseTree_1.BaseTree {
|
||||||
constructor(levels, elements = [], { hashFunction = simpleHash_1.default, zeroElement = 0, } = {}) {
|
constructor(levels, elements = [], { hashFunction = simpleHash_1.default, zeroElement = 0, } = {}) {
|
||||||
super();
|
super();
|
||||||
this.levels = levels;
|
this.levels = levels;
|
||||||
if (elements.length > this.capacity) {
|
if (elements.length > this.capacity) {
|
||||||
throw new Error('Tree is full');
|
throw new Error('Tree is full');
|
||||||
}
|
}
|
||||||
this._hashFn = hashFunction;
|
this._hashFn = hashFunction;
|
||||||
this.zeroElement = zeroElement;
|
this.zeroElement = zeroElement;
|
||||||
this._layers = [];
|
this._layers = [];
|
||||||
const leaves = elements.slice();
|
const leaves = elements.slice();
|
||||||
this._layers = [leaves];
|
this._layers = [leaves];
|
||||||
this._buildZeros();
|
this._buildZeros();
|
||||||
this._buildHashes();
|
this._buildHashes();
|
||||||
}
|
}
|
||||||
_buildHashes() {
|
_buildHashes() {
|
||||||
for (let layerIndex = 1; layerIndex <= this.levels; layerIndex++) {
|
for (let layerIndex = 1; layerIndex <= this.levels; layerIndex++) {
|
||||||
const nodes = this._layers[layerIndex - 1];
|
const nodes = this._layers[layerIndex - 1];
|
||||||
this._layers[layerIndex] = this._processNodes(nodes, layerIndex);
|
this._layers[layerIndex] = this._processNodes(nodes, layerIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Insert multiple elements into the tree.
|
* Insert multiple elements into the tree.
|
||||||
* @param {Array} elements Elements to insert
|
* @param {Array} elements Elements to insert
|
||||||
*/
|
*/
|
||||||
bulkInsert(elements) {
|
bulkInsert(elements) {
|
||||||
if (!elements.length) {
|
if (!elements.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this._layers[0].length + elements.length > this.capacity) {
|
if (this._layers[0].length + elements.length > this.capacity) {
|
||||||
throw new Error('Tree is full');
|
throw new Error('Tree is full');
|
||||||
}
|
}
|
||||||
// First we insert all elements except the last one
|
// First we insert all elements except the last one
|
||||||
// updating only full subtree hashes (all layers where inserted element has odd index)
|
// updating only full subtree hashes (all layers where inserted element has odd index)
|
||||||
// the last element will update the full path to the root making the tree consistent again
|
// the last element will update the full path to the root making the tree consistent again
|
||||||
for (let i = 0; i < elements.length - 1; i++) {
|
for (let i = 0; i < elements.length - 1; i++) {
|
||||||
this._layers[0].push(elements[i]);
|
this._layers[0].push(elements[i]);
|
||||||
let level = 0;
|
let level = 0;
|
||||||
let index = this._layers[0].length - 1;
|
let index = this._layers[0].length - 1;
|
||||||
while (index % 2 === 1) {
|
while (index % 2 === 1) {
|
||||||
level++;
|
level++;
|
||||||
index >>= 1;
|
index >>= 1;
|
||||||
this._layers[level][index] = this._hashFn(this._layers[level - 1][index * 2], this._layers[level - 1][index * 2 + 1]);
|
this._layers[level][index] = this._hashFn(this._layers[level - 1][index * 2], this._layers[level - 1][index * 2 + 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.insert(elements[elements.length - 1]);
|
this.insert(elements[elements.length - 1]);
|
||||||
}
|
}
|
||||||
indexOf(element, comparator) {
|
indexOf(element, comparator) {
|
||||||
return BaseTree_1.BaseTree.indexOf(this._layers[0], element, 0, comparator);
|
return BaseTree_1.BaseTree.indexOf(this._layers[0], element, 0, comparator);
|
||||||
}
|
}
|
||||||
proof(element) {
|
proof(element) {
|
||||||
const index = this.indexOf(element);
|
const index = this.indexOf(element);
|
||||||
return this.path(index);
|
return this.path(index);
|
||||||
}
|
}
|
||||||
getTreeEdge(edgeIndex) {
|
getTreeEdge(edgeIndex) {
|
||||||
const edgeElement = this._layers[0][edgeIndex];
|
const edgeElement = this._layers[0][edgeIndex];
|
||||||
if (edgeElement === undefined) {
|
if (edgeElement === undefined) {
|
||||||
throw new Error('Element not found');
|
throw new Error('Element not found');
|
||||||
}
|
}
|
||||||
const edgePath = this.path(edgeIndex);
|
const edgePath = this.path(edgeIndex);
|
||||||
return { edgePath, edgeElement, edgeIndex, edgeElementsCount: this._layers[0].length };
|
return { edgePath, edgeElement, edgeIndex, edgeElementsCount: this._layers[0].length };
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 🪓
|
* 🪓
|
||||||
* @param count
|
* @param count
|
||||||
*/
|
*/
|
||||||
getTreeSlices(count = 4) {
|
getTreeSlices(count = 4) {
|
||||||
const length = this._layers[0].length;
|
const length = this._layers[0].length;
|
||||||
let size = Math.ceil(length / count);
|
let size = Math.ceil(length / count);
|
||||||
if (size % 2)
|
if (size % 2)
|
||||||
size++;
|
size++;
|
||||||
const slices = [];
|
const slices = [];
|
||||||
for (let i = 0; i < length; i += size) {
|
for (let i = 0; i < length; i += size) {
|
||||||
const edgeLeft = i;
|
const edgeLeft = i;
|
||||||
const edgeRight = i + size;
|
const edgeRight = i + size;
|
||||||
slices.push({ edge: this.getTreeEdge(edgeLeft), elements: this.elements.slice(edgeLeft, edgeRight) });
|
slices.push({ edge: this.getTreeEdge(edgeLeft), elements: this.elements.slice(edgeLeft, edgeRight) });
|
||||||
}
|
}
|
||||||
return slices;
|
return slices;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Serialize entire tree state including intermediate layers into a plain object
|
* Serialize entire tree state including intermediate layers into a plain object
|
||||||
* Deserializing it back will not require to recompute any hashes
|
* Deserializing it back will not require to recompute any hashes
|
||||||
* Elements are not converted to a plain type, this is responsibility of the caller
|
* Elements are not converted to a plain type, this is responsibility of the caller
|
||||||
*/
|
*/
|
||||||
serialize() {
|
serialize() {
|
||||||
return {
|
return {
|
||||||
levels: this.levels,
|
levels: this.levels,
|
||||||
_zeros: this._zeros,
|
_zeros: this._zeros,
|
||||||
_layers: this._layers,
|
_layers: this._layers,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Deserialize data into a MerkleTree instance
|
* Deserialize data into a MerkleTree instance
|
||||||
* Make sure to provide the same hashFunction as was used in the source tree,
|
* Make sure to provide the same hashFunction as was used in the source tree,
|
||||||
* otherwise the tree state will be invalid
|
* otherwise the tree state will be invalid
|
||||||
*/
|
*/
|
||||||
static deserialize(data, hashFunction) {
|
static deserialize(data, hashFunction) {
|
||||||
const instance = Object.assign(Object.create(this.prototype), data);
|
const instance = Object.assign(Object.create(this.prototype), data);
|
||||||
instance._hashFn = hashFunction || simpleHash_1.default;
|
instance._hashFn = hashFunction || simpleHash_1.default;
|
||||||
instance.zeroElement = instance._zeros[0];
|
instance.zeroElement = instance._zeros[0];
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
toString() {
|
toString() {
|
||||||
return JSON.stringify(this.serialize());
|
return JSON.stringify(this.serialize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports["default"] = MerkleTree;
|
exports["default"] = MerkleTree;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@ -9792,165 +9792,165 @@ exports["default"] = MerkleTree;
|
|||||||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.PartialMerkleTree = void 0;
|
exports.PartialMerkleTree = void 0;
|
||||||
const simpleHash_1 = __importDefault(__webpack_require__(5319));
|
const simpleHash_1 = __importDefault(__webpack_require__(5319));
|
||||||
const BaseTree_1 = __webpack_require__(7736);
|
const BaseTree_1 = __webpack_require__(7736);
|
||||||
class PartialMerkleTree extends BaseTree_1.BaseTree {
|
class PartialMerkleTree extends BaseTree_1.BaseTree {
|
||||||
constructor(levels, { edgePath, edgeElement, edgeIndex, edgeElementsCount, }, leaves, { hashFunction, zeroElement } = {}) {
|
constructor(levels, { edgePath, edgeElement, edgeIndex, edgeElementsCount, }, leaves, { hashFunction, zeroElement } = {}) {
|
||||||
super();
|
super();
|
||||||
if (edgeIndex + leaves.length !== edgeElementsCount)
|
if (edgeIndex + leaves.length !== edgeElementsCount)
|
||||||
throw new Error('Invalid number of elements');
|
throw new Error('Invalid number of elements');
|
||||||
this._edgeLeafProof = edgePath;
|
this._edgeLeafProof = edgePath;
|
||||||
this._initialRoot = edgePath.pathRoot;
|
this._initialRoot = edgePath.pathRoot;
|
||||||
this.zeroElement = zeroElement !== null && zeroElement !== void 0 ? zeroElement : 0;
|
this.zeroElement = zeroElement !== null && zeroElement !== void 0 ? zeroElement : 0;
|
||||||
this._edgeLeaf = { data: edgeElement, index: edgeIndex };
|
this._edgeLeaf = { data: edgeElement, index: edgeIndex };
|
||||||
this._leavesAfterEdge = leaves;
|
this._leavesAfterEdge = leaves;
|
||||||
this.levels = levels;
|
this.levels = levels;
|
||||||
this._hashFn = hashFunction || simpleHash_1.default;
|
this._hashFn = hashFunction || simpleHash_1.default;
|
||||||
this._createProofMap();
|
this._createProofMap();
|
||||||
this._buildTree();
|
this._buildTree();
|
||||||
}
|
}
|
||||||
get edgeIndex() {
|
get edgeIndex() {
|
||||||
return this._edgeLeaf.index;
|
return this._edgeLeaf.index;
|
||||||
}
|
}
|
||||||
get edgeElement() {
|
get edgeElement() {
|
||||||
return this._edgeLeaf.data;
|
return this._edgeLeaf.data;
|
||||||
}
|
}
|
||||||
get edgeLeafProof() {
|
get edgeLeafProof() {
|
||||||
return this._edgeLeafProof;
|
return this._edgeLeafProof;
|
||||||
}
|
}
|
||||||
_createProofMap() {
|
_createProofMap() {
|
||||||
this._proofMap = this.edgeLeafProof.pathPositions.reduce((p, c, i) => {
|
this._proofMap = this.edgeLeafProof.pathPositions.reduce((p, c, i) => {
|
||||||
p.set(i, [c, this.edgeLeafProof.pathElements[i]]);
|
p.set(i, [c, this.edgeLeafProof.pathElements[i]]);
|
||||||
return p;
|
return p;
|
||||||
}, new Map());
|
}, new Map());
|
||||||
this._proofMap.set(this.levels, [0, this.edgeLeafProof.pathRoot]);
|
this._proofMap.set(this.levels, [0, this.edgeLeafProof.pathRoot]);
|
||||||
}
|
}
|
||||||
_buildTree() {
|
_buildTree() {
|
||||||
const edgeLeafIndex = this._edgeLeaf.index;
|
const edgeLeafIndex = this._edgeLeaf.index;
|
||||||
this._leaves = Array(edgeLeafIndex).concat(this._leavesAfterEdge);
|
this._leaves = Array(edgeLeafIndex).concat(this._leavesAfterEdge);
|
||||||
if (this._proofMap.has(0)) {
|
if (this._proofMap.has(0)) {
|
||||||
const [proofPos, proofEl] = this._proofMap.get(0);
|
const [proofPos, proofEl] = this._proofMap.get(0);
|
||||||
this._leaves[proofPos] = proofEl;
|
this._leaves[proofPos] = proofEl;
|
||||||
}
|
}
|
||||||
this._layers = [this._leaves];
|
this._layers = [this._leaves];
|
||||||
this._buildZeros();
|
this._buildZeros();
|
||||||
this._buildHashes();
|
this._buildHashes();
|
||||||
}
|
}
|
||||||
_buildHashes() {
|
_buildHashes() {
|
||||||
for (let layerIndex = 1; layerIndex <= this.levels; layerIndex++) {
|
for (let layerIndex = 1; layerIndex <= this.levels; layerIndex++) {
|
||||||
const nodes = this._layers[layerIndex - 1];
|
const nodes = this._layers[layerIndex - 1];
|
||||||
const currentLayer = this._processNodes(nodes, layerIndex);
|
const currentLayer = this._processNodes(nodes, layerIndex);
|
||||||
if (this._proofMap.has(layerIndex)) {
|
if (this._proofMap.has(layerIndex)) {
|
||||||
const [proofPos, proofEl] = this._proofMap.get(layerIndex);
|
const [proofPos, proofEl] = this._proofMap.get(layerIndex);
|
||||||
if (!currentLayer[proofPos])
|
if (!currentLayer[proofPos])
|
||||||
currentLayer[proofPos] = proofEl;
|
currentLayer[proofPos] = proofEl;
|
||||||
}
|
}
|
||||||
this._layers[layerIndex] = currentLayer;
|
this._layers[layerIndex] = currentLayer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Change an element in the tree
|
* Change an element in the tree
|
||||||
* @param {number} index Index of element to change
|
* @param {number} index Index of element to change
|
||||||
* @param element Updated element value
|
* @param element Updated element value
|
||||||
*/
|
*/
|
||||||
update(index, element) {
|
update(index, element) {
|
||||||
if (isNaN(Number(index)) || index < 0 || index > this._layers[0].length || index >= this.capacity) {
|
if (isNaN(Number(index)) || index < 0 || index > this._layers[0].length || index >= this.capacity) {
|
||||||
throw new Error('Insert index out of bounds: ' + index);
|
throw new Error('Insert index out of bounds: ' + index);
|
||||||
}
|
}
|
||||||
if (index < this._edgeLeaf.index) {
|
if (index < this._edgeLeaf.index) {
|
||||||
throw new Error(`Index ${index} is below the edge: ${this._edgeLeaf.index}`);
|
throw new Error(`Index ${index} is below the edge: ${this._edgeLeaf.index}`);
|
||||||
}
|
}
|
||||||
this._layers[0][index] = element;
|
this._layers[0][index] = element;
|
||||||
this._processUpdate(index);
|
this._processUpdate(index);
|
||||||
}
|
}
|
||||||
path(index) {
|
path(index) {
|
||||||
var _a;
|
var _a;
|
||||||
if (isNaN(Number(index)) || index < 0 || index >= this._layers[0].length) {
|
if (isNaN(Number(index)) || index < 0 || index >= this._layers[0].length) {
|
||||||
throw new Error('Index out of bounds: ' + index);
|
throw new Error('Index out of bounds: ' + index);
|
||||||
}
|
}
|
||||||
if (index < this._edgeLeaf.index) {
|
if (index < this._edgeLeaf.index) {
|
||||||
throw new Error(`Index ${index} is below the edge: ${this._edgeLeaf.index}`);
|
throw new Error(`Index ${index} is below the edge: ${this._edgeLeaf.index}`);
|
||||||
}
|
}
|
||||||
let elIndex = Number(index);
|
let elIndex = Number(index);
|
||||||
const pathElements = [];
|
const pathElements = [];
|
||||||
const pathIndices = [];
|
const pathIndices = [];
|
||||||
const pathPositions = [];
|
const pathPositions = [];
|
||||||
for (let level = 0; level < this.levels; level++) {
|
for (let level = 0; level < this.levels; level++) {
|
||||||
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) {
|
||||||
pathElements[level] = this._layers[level][leafIndex];
|
pathElements[level] = this._layers[level][leafIndex];
|
||||||
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);
|
const [proofPos, proofEl] = this._proofMap.get(level);
|
||||||
pathElements[level] = (_a = pathElements[level]) !== null && _a !== void 0 ? _a : (proofPos === leafIndex ? proofEl : this._zeros[level]);
|
pathElements[level] = (_a = pathElements[level]) !== null && _a !== void 0 ? _a : (proofPos === leafIndex ? proofEl : this._zeros[level]);
|
||||||
elIndex >>= 1;
|
elIndex >>= 1;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
pathElements,
|
pathElements,
|
||||||
pathIndices,
|
pathIndices,
|
||||||
pathPositions,
|
pathPositions,
|
||||||
pathRoot: this.root,
|
pathRoot: this.root,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
indexOf(element, comparator) {
|
indexOf(element, comparator) {
|
||||||
return BaseTree_1.BaseTree.indexOf(this._layers[0], element, this.edgeIndex, comparator);
|
return BaseTree_1.BaseTree.indexOf(this._layers[0], element, this.edgeIndex, comparator);
|
||||||
}
|
}
|
||||||
proof(element) {
|
proof(element) {
|
||||||
const index = this.indexOf(element);
|
const index = this.indexOf(element);
|
||||||
return this.path(index);
|
return this.path(index);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Shifts edge of tree to left
|
* Shifts edge of tree to left
|
||||||
* @param edge new TreeEdge below current edge
|
* @param edge new TreeEdge below current edge
|
||||||
* @param elements leaves between old and new edge
|
* @param elements leaves between old and new edge
|
||||||
*/
|
*/
|
||||||
shiftEdge(edge, elements) {
|
shiftEdge(edge, elements) {
|
||||||
if (this._edgeLeaf.index <= edge.edgeIndex) {
|
if (this._edgeLeaf.index <= edge.edgeIndex) {
|
||||||
throw new Error(`New edgeIndex should be smaller then ${this._edgeLeaf.index}`);
|
throw new Error(`New edgeIndex should be smaller then ${this._edgeLeaf.index}`);
|
||||||
}
|
}
|
||||||
if (elements.length !== (this._edgeLeaf.index - edge.edgeIndex)) {
|
if (elements.length !== (this._edgeLeaf.index - edge.edgeIndex)) {
|
||||||
throw new Error(`Elements length should be ${this._edgeLeaf.index - edge.edgeIndex}`);
|
throw new Error(`Elements length should be ${this._edgeLeaf.index - edge.edgeIndex}`);
|
||||||
}
|
}
|
||||||
this._edgeLeafProof = edge.edgePath;
|
this._edgeLeafProof = edge.edgePath;
|
||||||
this._edgeLeaf = { index: edge.edgeIndex, data: edge.edgeElement };
|
this._edgeLeaf = { index: edge.edgeIndex, data: edge.edgeElement };
|
||||||
this._leavesAfterEdge = [...elements, ...this._leavesAfterEdge];
|
this._leavesAfterEdge = [...elements, ...this._leavesAfterEdge];
|
||||||
this._createProofMap();
|
this._createProofMap();
|
||||||
this._buildTree();
|
this._buildTree();
|
||||||
}
|
}
|
||||||
serialize() {
|
serialize() {
|
||||||
return {
|
return {
|
||||||
_edgeLeafProof: this._edgeLeafProof,
|
_edgeLeafProof: this._edgeLeafProof,
|
||||||
_edgeLeaf: this._edgeLeaf,
|
_edgeLeaf: this._edgeLeaf,
|
||||||
_layers: this._layers,
|
_layers: this._layers,
|
||||||
_zeros: this._zeros,
|
_zeros: this._zeros,
|
||||||
levels: this.levels,
|
levels: this.levels,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
static deserialize(data, hashFunction) {
|
static deserialize(data, hashFunction) {
|
||||||
const instance = Object.assign(Object.create(this.prototype), data);
|
const instance = Object.assign(Object.create(this.prototype), data);
|
||||||
instance._hashFn = hashFunction || simpleHash_1.default;
|
instance._hashFn = hashFunction || simpleHash_1.default;
|
||||||
instance._initialRoot = data._edgeLeafProof.pathRoot;
|
instance._initialRoot = data._edgeLeafProof.pathRoot;
|
||||||
instance.zeroElement = instance._zeros[0];
|
instance.zeroElement = instance._zeros[0];
|
||||||
instance._leavesAfterEdge = instance._layers[0].slice(data._edgeLeaf.index);
|
instance._leavesAfterEdge = instance._layers[0].slice(data._edgeLeaf.index);
|
||||||
instance._createProofMap();
|
instance._createProofMap();
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
toString() {
|
toString() {
|
||||||
return JSON.stringify(this.serialize());
|
return JSON.stringify(this.serialize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.PartialMerkleTree = PartialMerkleTree;
|
exports.PartialMerkleTree = PartialMerkleTree;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@ -9959,19 +9959,19 @@ exports.PartialMerkleTree = PartialMerkleTree;
|
|||||||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.MerkleTree = exports.simpleHash = exports.PartialMerkleTree = void 0;
|
exports.MerkleTree = exports.simpleHash = exports.PartialMerkleTree = void 0;
|
||||||
const FixedMerkleTree_1 = __importDefault(__webpack_require__(9093));
|
const FixedMerkleTree_1 = __importDefault(__webpack_require__(9093));
|
||||||
Object.defineProperty(exports, "MerkleTree", ({ enumerable: true, get: function () { return FixedMerkleTree_1.default; } }));
|
Object.defineProperty(exports, "MerkleTree", ({ enumerable: true, get: function () { return FixedMerkleTree_1.default; } }));
|
||||||
var PartialMerkleTree_1 = __webpack_require__(91230);
|
var PartialMerkleTree_1 = __webpack_require__(91230);
|
||||||
Object.defineProperty(exports, "PartialMerkleTree", ({ enumerable: true, get: function () { return PartialMerkleTree_1.PartialMerkleTree; } }));
|
Object.defineProperty(exports, "PartialMerkleTree", ({ enumerable: true, get: function () { return PartialMerkleTree_1.PartialMerkleTree; } }));
|
||||||
var simpleHash_1 = __webpack_require__(5319);
|
var simpleHash_1 = __webpack_require__(5319);
|
||||||
Object.defineProperty(exports, "simpleHash", ({ enumerable: true, get: function () { return simpleHash_1.simpleHash; } }));
|
Object.defineProperty(exports, "simpleHash", ({ enumerable: true, get: function () { return simpleHash_1.simpleHash; } }));
|
||||||
exports["default"] = FixedMerkleTree_1.default;
|
exports["default"] = FixedMerkleTree_1.default;
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
@ -9980,27 +9980,27 @@ exports["default"] = FixedMerkleTree_1.default;
|
|||||||
/***/ ((__unused_webpack_module, exports) => {
|
/***/ ((__unused_webpack_module, exports) => {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.simpleHash = void 0;
|
exports.simpleHash = void 0;
|
||||||
/***
|
/***
|
||||||
* This is insecure hash function, just for example only
|
* This is insecure hash function, just for example only
|
||||||
* @param data
|
* @param data
|
||||||
* @param seed
|
* @param seed
|
||||||
* @param hashLength
|
* @param hashLength
|
||||||
*/
|
*/
|
||||||
function simpleHash(data, seed, hashLength = 40) {
|
function simpleHash(data, seed, hashLength = 40) {
|
||||||
const str = data.join('');
|
const str = data.join('');
|
||||||
let i, l, hval = seed !== null && seed !== void 0 ? seed : 0x811c9dcc5;
|
let i, l, hval = seed !== null && seed !== void 0 ? seed : 0x811c9dcc5;
|
||||||
for (i = 0, l = str.length; i < l; i++) {
|
for (i = 0, l = str.length; i < l; i++) {
|
||||||
hval ^= str.charCodeAt(i);
|
hval ^= str.charCodeAt(i);
|
||||||
hval += (hval << 1) + (hval << 4) + (hval << 6) + (hval << 8) + (hval << 24);
|
hval += (hval << 1) + (hval << 4) + (hval << 6) + (hval << 8) + (hval << 24);
|
||||||
}
|
}
|
||||||
const hash = (hval >>> 0).toString(16);
|
const hash = (hval >>> 0).toString(16);
|
||||||
return BigInt('0x' + hash.padEnd(hashLength - (hash.length - 1), '0')).toString(10);
|
return BigInt('0x' + hash.padEnd(hashLength - (hash.length - 1), '0')).toString(10);
|
||||||
}
|
}
|
||||||
exports.simpleHash = simpleHash;
|
exports.simpleHash = simpleHash;
|
||||||
exports["default"] = (left, right) => simpleHash([left, right]);
|
exports["default"] = (left, right) => simpleHash([left, right]);
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
@ -32,10 +32,10 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@metamask/eth-sig-util": "^8.0.0",
|
"@metamask/eth-sig-util": "^8.0.0",
|
||||||
"@tornado/contracts": "git+https://codeberg.org/tornadocash/tornado-contracts.git#1b1d707878c16a3dc60d295299d4f0e7ce6ba831",
|
"@tornado/contracts": "git+https://git.tornado.ws/tornadocontrib/tornado-contracts.git#1b1d707878c16a3dc60d295299d4f0e7ce6ba831",
|
||||||
"@tornado/fixed-merkle-tree": "git+https://codeberg.org/tornadocash/fixed-merkle-tree.git#5c3fca4cb11255760ad5f4fd95d7c6eb45c1fc99",
|
"@tornado/fixed-merkle-tree": "^0.7.3",
|
||||||
"@tornado/snarkjs": "git+https://codeberg.org/tornadocash/snarkjs.git#d3915a760c437cde7bd317f9ea2c627954900656",
|
"@tornado/snarkjs": "^0.1.20",
|
||||||
"@tornado/websnark": "git+https://codeberg.org/tornadocash/websnark.git#b0c9fce5359ceba55167a2ad01a29d1e137843ec",
|
"@tornado/websnark": "^0.0.4",
|
||||||
"ajv": "^8.17.1",
|
"ajv": "^8.17.1",
|
||||||
"bn.js": "^5.2.1",
|
"bn.js": "^5.2.1",
|
||||||
"circomlibjs": "0.1.7",
|
"circomlibjs": "0.1.7",
|
||||||
|
21
yarn.lock
21
yarn.lock
@ -872,21 +872,23 @@
|
|||||||
"@noble/hashes" "~1.4.0"
|
"@noble/hashes" "~1.4.0"
|
||||||
"@scure/base" "~1.1.6"
|
"@scure/base" "~1.1.6"
|
||||||
|
|
||||||
"@tornado/contracts@git+https://codeberg.org/tornadocash/tornado-contracts.git#1b1d707878c16a3dc60d295299d4f0e7ce6ba831":
|
"@tornado/contracts@git+https://git.tornado.ws/tornadocontrib/tornado-contracts.git#1b1d707878c16a3dc60d295299d4f0e7ce6ba831":
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "git+https://codeberg.org/tornadocash/tornado-contracts.git#1b1d707878c16a3dc60d295299d4f0e7ce6ba831"
|
resolved "git+https://git.tornado.ws/tornadocontrib/tornado-contracts.git#1b1d707878c16a3dc60d295299d4f0e7ce6ba831"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@openzeppelin/contracts" "5.0.2"
|
"@openzeppelin/contracts" "5.0.2"
|
||||||
"@openzeppelin/contracts-v3" "npm:@openzeppelin/contracts@3.2.0-rc.0"
|
"@openzeppelin/contracts-v3" "npm:@openzeppelin/contracts@3.2.0-rc.0"
|
||||||
ethers "^6.13.4"
|
ethers "^6.13.4"
|
||||||
|
|
||||||
"@tornado/fixed-merkle-tree@git+https://codeberg.org/tornadocash/fixed-merkle-tree.git#5c3fca4cb11255760ad5f4fd95d7c6eb45c1fc99":
|
"@tornado/fixed-merkle-tree@^0.7.3":
|
||||||
version "0.7.3"
|
version "0.7.3"
|
||||||
resolved "git+https://codeberg.org/tornadocash/fixed-merkle-tree.git#5c3fca4cb11255760ad5f4fd95d7c6eb45c1fc99"
|
resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Ffixed-merkle-tree/-/0.7.3/fixed-merkle-tree-0.7.3.tgz#6636ce9d334553c5f17e5a564fd22f2e9ec04472"
|
||||||
|
integrity sha512-8UWvIzz0/rMGBkzXACwmCv/5I1VJmnshAKc4C+nkTfOdmnX8Pf1bBa0GlxUIZ25ZFGiU/h2IKEHYckmHovwzEA==
|
||||||
|
|
||||||
"@tornado/snarkjs@git+https://codeberg.org/tornadocash/snarkjs.git#d3915a760c437cde7bd317f9ea2c627954900656":
|
"@tornado/snarkjs@^0.1.20":
|
||||||
version "0.1.20"
|
version "0.1.20"
|
||||||
resolved "git+https://codeberg.org/tornadocash/snarkjs.git#d3915a760c437cde7bd317f9ea2c627954900656"
|
resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Fsnarkjs/-/0.1.20/snarkjs-0.1.20.tgz#d7610cd3c8dc10598da7dc3e40e5d7470c3aa8c7"
|
||||||
|
integrity sha512-mn+ePoQjqOHyDyK8AMy8SXYqNSxJWVswWVmMYvuc75/9bBtJ7SNtwrTByxmfWjrf4S3BM3IrGfHqBHEXY6gR4Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
big-integer "^1.6.43"
|
big-integer "^1.6.43"
|
||||||
chai "^4.2.0"
|
chai "^4.2.0"
|
||||||
@ -895,11 +897,12 @@
|
|||||||
keccak "^2.0.0"
|
keccak "^2.0.0"
|
||||||
yargs "^12.0.5"
|
yargs "^12.0.5"
|
||||||
|
|
||||||
"@tornado/websnark@git+https://codeberg.org/tornadocash/websnark.git#b0c9fce5359ceba55167a2ad01a29d1e137843ec":
|
"@tornado/websnark@^0.0.4":
|
||||||
version "0.0.4"
|
version "0.0.4"
|
||||||
resolved "git+https://codeberg.org/tornadocash/websnark.git#b0c9fce5359ceba55167a2ad01a29d1e137843ec"
|
resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Fwebsnark/-/0.0.4/websnark-0.0.4.tgz#4c603259b71172225a70e3d454344fa172710970"
|
||||||
|
integrity sha512-dHbaS41ILPq5NyVBDW8AmUPoSKvamtkTeIhyuKKmoyOrZMAUhJ9y1B2zRcejUKfhCZkIjAgCt9bvdzdOGGswwQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@tornado/snarkjs" "git+https://codeberg.org/tornadocash/snarkjs.git#d3915a760c437cde7bd317f9ea2c627954900656"
|
"@tornado/snarkjs" "^0.1.20"
|
||||||
big-integer "1.6.42"
|
big-integer "1.6.42"
|
||||||
|
|
||||||
"@typechain/ethers-v6@^0.5.1":
|
"@typechain/ethers-v6@^0.5.1":
|
||||||
|
Loading…
Reference in New Issue
Block a user