Skip to content

Commit

Permalink
Merge pull request #42 from zkBob/develop
Browse files Browse the repository at this point in the history
Cold storage, partial tree, separated multithreaded version, ios support, state helper methods
  • Loading branch information
EvgenKor authored Dec 22, 2022
2 parents 714a862 + 9582514 commit 12cbd6d
Show file tree
Hide file tree
Showing 25 changed files with 1,291 additions and 210 deletions.
5 changes: 3 additions & 2 deletions libzkbob-rs-node/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "libzkbob-rs-node"
version = "0.1.27"
version = "0.2.2"
authors = ["Dmitry Vdovin <voidxnull@gmail.com>"]
repository = "https://github.com/zkBob/libzkbob-rs/"
license = "MIT OR Apache-2.0"
Expand All @@ -11,11 +11,12 @@ exclude = ["index.node"]
crate-type = ["cdylib"]

[dependencies]
libzkbob-rs = { version = "0.3.16", features = ["native"] }
libzkbob-rs = { version = "0.9.1", features = ["native"] }
#libzkbob-rs = { path = "../libzkbob-rs", features = ["native"] }
neon = { version = "0.10.0", default-features = false, features = ["channel-api", "napi-6", "promise-api"] }
# FIXME: Using a random fork for now
neon-serde = { git = "https://github.com/NZXTCorp/neon-serde.git", branch = "refactor/update-neon-0.10" }
rayon = "1.5.3"
serde = "1.0.136"
hex = "0.4.3"

22 changes: 15 additions & 7 deletions libzkbob-rs-node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ This project was bootstrapped by [create-neon](https://www.npmjs.com/package/cre

Installing libzkbob-rs-node requires a [supported version of Node and Rust](https://github.com/neon-bindings/neon#platform-support).

You can install the project with npm. In the project directory, run:
You can install the project with yarn. In the project directory, run:

```sh
$ npm install
$ yarn install
```

This fully installs the project, including installing any dependencies and running the build.
Expand All @@ -19,7 +19,7 @@ This fully installs the project, including installing any dependencies and runni
If you have already installed the project and only want to run the build, run:

```sh
$ npm run build
$ yarn build
```

This command uses the [cargo-cp-artifact](https://github.com/neon-bindings/cargo-cp-artifact) utility to run the Rust build and copy the built library into `./index.node`.
Expand All @@ -44,15 +44,23 @@ console.log('Proof', proof);

In the project directory, you can run:

### `npm install`
### `yarn install`

Installs the project, including running `npm run build`.
Installs the project, including running `yarn build`.

### `npm build`
### `yarn build`

Builds the Node addon (`index.node`) from source.

### `npm test`
### `yarn test`

Runs the unit tests by calling `cargo test`. You can learn more about [adding tests to your Rust code](https://doc.rust-lang.org/book/ch11-01-writing-tests.html) from the [Rust book](https://doc.rust-lang.org/book/).

## Testing suite

You can find the library usage example with few tests in `test.js` file
You can launch it with the following command after building the local library:

```sh
$ node test.js
```
7 changes: 6 additions & 1 deletion libzkbob-rs-node/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ declare class MerkleTree {
new_hashes_left_index: number,
new_hashes_right_index: number,
): any;
rollback(index: number): void;
rollback(index: number): number;
wipe(): void;
getLeftSiblings(index: number): string[];
getLastStableIndex(): number;
setLastStableIndex(index: number): void;
getRootAt(index: number): string;
}

declare class TxStorage {
Expand Down
20 changes: 20 additions & 0 deletions libzkbob-rs-node/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,26 @@ class MerkleTree {
rollback(index) {
return zp.merkleRollback(this.inner, index)
}

wipe() {
zp.merkleWipe(this.inner)
}

getLeftSiblings(index) {
return zp.merkleGetLeftSiblings(this.inner, index)
}

getLastStableIndex() {
return zp.merkleGetLastStableIndex(this.inner)
}

setLastStableIndex(index) {
zp.merkleSetLastStableIndex(this.inner, index)
};

getRootAt(index) {
return zp.merkleGetRootAt(this.inner, index)
}
}

class TxStorage {
Expand Down
32 changes: 0 additions & 32 deletions libzkbob-rs-node/package-lock.json

This file was deleted.

2 changes: 1 addition & 1 deletion libzkbob-rs-node/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "libzkbob-rs-node",
"version": "0.1.27",
"version": "0.2.2",
"description": "Neon version of libzkbob-rs",
"main": "index.js",
"types": "index.d.ts",
Expand Down
5 changes: 5 additions & 0 deletions libzkbob-rs-node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ fn main(mut cx: ModuleContext) -> NeonResult<()> {
cx.export_function("merkleGetAllNodes", merkle::merkle_get_all_nodes)?;
cx.export_function("merkleGetVirtualNode", merkle::merkle_get_virtual_node)?;
cx.export_function("merkleRollback", merkle::merkle_rollback)?;
cx.export_function("merkleWipe", merkle::merkle_wipe)?;
cx.export_function("merkleGetLeftSiblings", merkle::merkle_get_left_siblings)?;
cx.export_function("merkleGetLastStableIndex", merkle::merkle_get_last_stable_index)?;
cx.export_function("merkleSetLastStableIndex", merkle::merkle_set_last_stable_index)?;
cx.export_function("merkleGetRootAt", merkle::merkle_get_root_at)?;

cx.export_function("txStorageNew", storage::tx_storage_new)?;
cx.export_function("txStorageAdd", storage::tx_storage_add)?;
Expand Down
104 changes: 97 additions & 7 deletions libzkbob-rs-node/src/merkle.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use std::collections::HashMap;
use std::sync::RwLock;
use std::vec::Vec;

use libzkbob_rs::libzeropool::fawkes_crypto::borsh::BorshDeserialize;
use libzkbob_rs::libzeropool::fawkes_crypto::borsh::{BorshSerialize, BorshDeserialize};
use libzkbob_rs::libzeropool::fawkes_crypto::ff_uint::Num;
use libzkbob_rs::libzeropool::{
constants::{HEIGHT, OUTPLUSONELOG},
constants::{HEIGHT, OUT, OUTPLUSONELOG},
POOL_PARAMS,
};
use libzkbob_rs::merkle::NativeMerkleTree;
use neon::prelude::*;
use neon::types::buffer::TypedArray;
//use serde::Serialize;

use crate::PoolParams;

Expand Down Expand Up @@ -148,9 +148,9 @@ pub fn merkle_get_node(mut cx: FunctionContext) -> JsResult<JsValue> {
pub fn merkle_get_next_index(mut cx: FunctionContext) -> JsResult<JsValue> {
let tree = cx.argument::<BoxedMerkleTree>(0)?;

let root = tree.read().unwrap().inner.next_index();
let next_index = tree.read().unwrap().inner.next_index();

let result = neon_serde::to_value(&mut cx, &root).unwrap();
let result = neon_serde::to_value(&mut cx, &next_index).unwrap();

Ok(result)
}
Expand Down Expand Up @@ -209,15 +209,105 @@ pub fn merkle_get_virtual_node(mut cx: FunctionContext) -> JsResult<JsValue> {
Ok(result)
}

pub fn merkle_rollback(mut cx: FunctionContext) -> JsResult<JsUndefined> {
pub fn merkle_rollback(mut cx: FunctionContext) -> JsResult<JsValue> {
let tree = cx.argument::<BoxedMerkleTree>(0)?;
let rollback_index = {
let num = cx.argument::<JsNumber>(1)?;
num.value(&mut cx) as u64
};

let mut a = tree.write().unwrap();
a.inner.rollback(rollback_index);
let new_next_index = a.inner.rollback(rollback_index);

let result = neon_serde::to_value(&mut cx, &new_next_index).unwrap();

Ok(result)
}

pub fn merkle_wipe(mut cx: FunctionContext) -> JsResult<JsUndefined> {
let tree = cx.argument::<BoxedMerkleTree>(0)?;

tree.write().unwrap().inner.wipe();

Ok(cx.undefined())
}

pub fn merkle_get_left_siblings(mut cx: FunctionContext) -> JsResult<JsValue> {
let tree = cx.argument::<BoxedMerkleTree>(0)?;
let index = {
let num = cx.argument::<JsNumber>(1)?;
num.value(&mut cx) as u64
};

if index & OUTPLUSONELOG as u64 != 0 {
return cx.throw_error(format!("Index to get sibling from should be multiple of {}", OUT + 1));
}

let siblings = tree.read().unwrap().inner.get_left_siblings(index);
let array = match siblings {
Some(val) => {
let result: Result<Vec<String>, String> = val
.into_iter()
.map(|node| {
let mut node_bytes = vec![];
node.value.serialize(&mut node_bytes).unwrap();
node_bytes.reverse();
let node_string = hex::encode(node_bytes);


let res = format!("{:02x}{:012x}{}", node.height, node.index, node_string);

if res.len() != 78 {
return Err(format!("Internal error (sibling length {} is invalid)", res.len()));
}

Ok(res)
})
.collect();

result
},
None => Err(format!("Tree is undefined at index {}", index))
};

match array {
Ok(val) => Ok(neon_serde::to_value(&mut cx, &val).unwrap()),
Err(e) => cx.throw_error(e),
}
}

pub fn merkle_get_last_stable_index(mut cx: FunctionContext) -> JsResult<JsValue> {
let tree = cx.argument::<BoxedMerkleTree>(0)?;

let stable_index = tree.read().unwrap().inner.get_last_stable_index();

let result = neon_serde::to_value(&mut cx, &stable_index).unwrap();

Ok(result)
}

pub fn merkle_set_last_stable_index(mut cx: FunctionContext) -> JsResult<JsUndefined> {
let tree = cx.argument::<BoxedMerkleTree>(0)?;
let stable_index = {
let num = cx.argument::<JsNumber>(1)?;
num.value(&mut cx) as u64
};

tree.write().unwrap().inner.set_last_stable_index(Some(stable_index));

Ok(cx.undefined())
}

pub fn merkle_get_root_at(mut cx: FunctionContext) -> JsResult<JsValue> {
let tree = cx.argument::<BoxedMerkleTree>(0)?;

let index = {
let num = cx.argument::<JsNumber>(1)?;
num.value(&mut cx) as u64
};

let root = tree.read().unwrap().inner.get_root_at(index);
let result = neon_serde::to_value(&mut cx, &root).unwrap();

Ok(result)
}
44 changes: 41 additions & 3 deletions libzkbob-rs-node/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,47 @@ const zp = require('./index.js')

let tree = new zp.MerkleTree('./testdb');

for (let i = 0; i < 100; ++i) {
tree.addHash(i, Buffer.alloc(32));
console.log(`Root at index ${tree.getNextIndex()}: ${tree.getRoot()}`);

console.log('Building the tree...');
for (let i = 0; i < 512; ++i) {;
tree.addHash(i, Buffer.alloc(32).fill(i % 10));
}

console.log('Calculating proof...')
let proof = tree.getProof(50);
console.log('Proof', proof);
console.log('Proof', proof);

let fixed_index = tree.getNextIndex();
console.log(`Root at index ${tree.getNextIndex()}: ${tree.getRoot()}`);
tree.setLastStableIndex(fixed_index);

console.log('Appending hashes...');
for (let i = 0; i < 256; ++i) {
tree.addHash(i + fixed_index, Buffer.alloc(32).fill(i % 20));
}

const siblingsIndex = 640;
console.log(`Getting siblings at index ${siblingsIndex} ...`);
try {
let siblings = tree.getLeftSiblings(siblingsIndex);
console.log(siblings);
} catch(err) {
console.error(`Cannot get siblings: ${err}`);
}

console.log(`Root at index ${tree.getNextIndex()}: ${tree.getRoot()}`);

console.log(`Rollback tree to the index ${fixed_index}...`);
tree.rollback(tree.getLastStableIndex());

console.log(`Root at index ${tree.getNextIndex()}: ${tree.getRoot()}`);

console.log(`Wipe Merkle tree...`);
tree.wipe();

console.log(`Root at index ${tree.getNextIndex()}: ${tree.getRoot()}`);




8 changes: 4 additions & 4 deletions libzkbob-rs-node/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# yarn lockfile v1


"cargo-cp-artifact@^0.1":
"integrity" "sha512-CQw0doK/aaF7j041666XzuilHxqMxaKkn+I5vmBsd8SAwS0cO5CqVEVp0xJwOKstyqWZ6WK4Ww3O6p26x/Goyg=="
"resolved" "https://registry.npmjs.org/cargo-cp-artifact/-/cargo-cp-artifact-0.1.6.tgz"
"version" "0.1.6"
cargo-cp-artifact@^0.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/cargo-cp-artifact/-/cargo-cp-artifact-0.1.7.tgz#1181b9d6e71f00f17c068c05e3cd1b0864783341"
integrity sha512-pxEV9p1on8vu3BOKstVisF9TwMyGKCBRvzaVpQHuU2sLULCKrn3MJWx/4XlNzmG6xNCTPf78DJ7WCGgr2mOzjg==
Loading

0 comments on commit 12cbd6d

Please sign in to comment.