7 Commits

Author SHA1 Message Date
c79653ccba Update dependecies & change package name for self-hosting in tornado scope 2023-09-18 01:35:33 -07:00
poma
96e254a46b serialization 2020-09-23 19:22:14 +03:00
poma
53cb08d9b9 build failure notification 2020-08-19 11:35:14 +03:00
poma
0eb38e0b2d update dependency 2020-08-19 01:35:12 +03:00
poma
1bc8dfa338 update circomlib 2020-08-16 02:24:55 +03:00
Alexey
3d95212b1d findIndex optimization 2020-08-06 18:04:08 +03:00
Alexey
523094bdc8 add comparator for indexOf 2020-08-06 18:00:13 +03:00
8 changed files with 6540 additions and 420 deletions

View File

@@ -1,4 +1,4 @@
name: Node.js CI name: build
on: on:
pull_request: pull_request:
@@ -16,6 +16,14 @@ jobs:
node-version: 14.7.0 node-version: 14.7.0
- run: npm ci - run: npm ci
- run: npm run test - run: npm run test
- name: Telegram Failure Notification
uses: appleboy/telegram-action@0.0.7
if: failure()
with:
message: ❗ Build failed for [${{ github.repository }}](https://github.com/${{ github.repository }}/actions) because of ${{ github.actor }}
format: markdown
to: ${{ secrets.TELEGRAM_CHAT_ID }}
token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -26,6 +34,14 @@ jobs:
node-version: 14.7.0 node-version: 14.7.0
- run: npm ci - run: npm ci
- run: npm run lint - run: npm run lint
- name: Telegram Failure Notification
uses: appleboy/telegram-action@0.0.7
if: failure()
with:
message: ❗ Build failed for [${{ github.repository }}](https://github.com/${{ github.repository }}/actions) because of ${{ github.actor }}
format: markdown
to: ${{ secrets.TELEGRAM_CHAT_ID }}
token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
publish: publish:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -65,3 +81,12 @@ jobs:
message: 🚀 Published [${{ steps.vars.outputs.repo_name }}](https://github.com/${{ github.repository }}) version [${{ steps.vars.outputs.version }}](https://www.npmjs.com/package/${{ steps.vars.outputs.repo_name }}/v/${{ steps.vars.outputs.version }}) to npm message: 🚀 Published [${{ steps.vars.outputs.repo_name }}](https://github.com/${{ github.repository }}) version [${{ steps.vars.outputs.version }}](https://www.npmjs.com/package/${{ steps.vars.outputs.repo_name }}/v/${{ steps.vars.outputs.version }}) to npm
debug: true debug: true
format: markdown format: markdown
- name: Telegram Failure Notification
uses: appleboy/telegram-action@0.0.7
if: failure()
with:
message: ❗ Failed to publish [${{ steps.vars.outputs.repo_name }}](https://github.com/${{ github.repository }}/actions) because of ${{ env.GITHUB_ACTOR }}
format: markdown
to: ${{ secrets.TELEGRAM_CHAT_ID }}
token: ${{ secrets.TELEGRAM_BOT_TOKEN }}

1
.npmrc Normal file
View File

@@ -0,0 +1 @@
@tornado:registry=https://git.tornado.ws/api/packages/tornado-packages/npm/

View File

@@ -1,4 +1,4 @@
# Merkle Tree [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/tornadocash/fixed-merkle-tree/Node.js%20CI)](https://github.com/tornadocash/fixed-merkle-tree/actions) [![npm](https://img.shields.io/npm/v/fixed-merkle-tree)](https://www.npmjs.com/package/fixed-merkle-tree) # Merkle Tree [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/tornadocash/fixed-merkle-tree/build)](https://github.com/tornadocash/fixed-merkle-tree/actions) [![npm](https://img.shields.io/npm/v/fixed-merkle-tree)](https://www.npmjs.com/package/fixed-merkle-tree)
This is a fixed depth merkle tree implementation with sequential inserts This is a fixed depth merkle tree implementation with sequential inserts

6847
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +1,29 @@
{ {
"name": "fixed-merkle-tree", "name": "@tornado/fixed-merkle-tree",
"version": "0.3.1", "version": "0.4.0",
"description": "Fixed depth merkle tree implementation with sequential inserts", "description": "Fixed depth merkle tree implementation with sequential inserts",
"main": "src/merkleTree.js", "main": "src/merkleTree.js",
"repository": {
"type": "git",
"url": "https://git.tornado.ws/tornado-packages/fixed-merkle-tree.git"
},
"scripts": { "scripts": {
"test": "mocha", "test": "mocha",
"lint": "eslint ." "lint": "eslint ."
}, },
"keywords": ["merkle", "tree", "merkleTree"], "keywords": [
"merkle",
"tree",
"merkleTree"
],
"author": "Roman Semenov <semenov.roma@gmail.com>", "author": "Roman Semenov <semenov.roma@gmail.com>",
"license": "ISC", "license": "ISC",
"files": ["src/*"], "files": [
"src/*"
],
"dependencies": { "dependencies": {
"snarkjs": "git+https://github.com/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5", "@tornado/circomlib": "^0.0.21",
"circomlib": "git+https://github.com/tornadocash/circomlib.git#c372f14d324d57339c88451834bf2824e73bbdbc" "@tornado/snarkjs": "^0.1.20"
}, },
"devDependencies": { "devDependencies": {
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",

View File

@@ -134,10 +134,15 @@ class MerkleTree {
/** /**
* Find an element in the tree * Find an element in the tree
* @param element An element to find * @param element An element to find
* @param comparator A function that checks leaf value equality
* @returns {number} Index if element is found, otherwise -1 * @returns {number} Index if element is found, otherwise -1
*/ */
indexOf(element) { indexOf(element, comparator) {
return this._layers[0].indexOf(element) if (comparator) {
return this._layers[0].findIndex((el) => comparator(element, el))
} else {
return this._layers[0].indexOf(element)
}
} }
/** /**
@@ -147,6 +152,36 @@ class MerkleTree {
elements() { elements() {
return this._layers[0].slice() return this._layers[0].slice()
} }
/**
* Serialize entire tree state including intermediate layers into a plain object
* Deserializing it back will not require to recompute any hashes
* Elements are not converted to a plain type, this is responsibility of the caller
*/
serialize() {
return {
levels: this.levels,
capacity: this.capacity,
zeroElement: this.zeroElement,
_zeros: this._zeros,
_layers: this._layers,
}
}
/**
* Deserialize data into a MerkleTree instance
* Make sure to provide the same hashFunction as was used in the source tree,
* otherwise the tree state will be invalid
*
* @param data
* @param hashFunction
* @returns {MerkleTree}
*/
static deserialize(data, hashFunction) {
const instance = Object.assign(Object.create(this.prototype), data)
instance._hash = hashFunction || defaultHash
return instance
}
} }
module.exports = MerkleTree module.exports = MerkleTree

View File

@@ -1,3 +1,4 @@
const { mimcsponge } = require('circomlib') const { mimcsponge } = require("@tornado/circomlib");
const { bigInt } = require('snarkjs') const { bigInt } = require("@tornado/snarkjs");
module.exports = (left, right) => mimcsponge.multiHash([bigInt(left), bigInt(right)]).toString() module.exports = (left, right) =>
mimcsponge.multiHash([bigInt(left), bigInt(right)]).toString();

View File

@@ -202,4 +202,19 @@ describe('MerkleTree', () => {
]) ])
}) })
}) })
describe('#serialize', () => {
it('should work', () => {
const src = new MerkleTree(10, [1, 2, 3])
const data = src.serialize()
const dst = MerkleTree.deserialize(data)
src.root().should.equal(dst.root())
src.insert(10)
dst.insert(10)
src.root().should.equal(dst.root())
})
})
}) })