Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

incremental merkle tree #8

Merged
merged 13 commits into from
Nov 7, 2023
7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ uuid = { version = "1.4.1", features = ["v4"] } # UUID
parking_lot = "0.12.1" # Sync mutex
num-bigint = "0.4.4" # Bigints in hashers (TODO: double check if needed)
num-traits = "0.2.17" # Bigints in hashers (TODO: double check if needed)
indexmap = "2.1.0"

[dev-dependencies]
criterion = { version = "0.4", features = ["html_reports"] } # Benchmarking
Expand All @@ -25,6 +26,10 @@ criterion = { version = "0.4", features = ["html_reports"] } # Benchmarking
name = "mmr_benchmark"
harness = false

[[bench]]
name = "incremental_benchmark"
harness = false

[features]
default = ["store", "hasher"]
all = ["store", "sqlite", "hasher", "keccak", "poseidon", "pedersen", "mmr", "infinitely_stackable_mmr", "merkle_tree", "incremental_merkle_tree"]
Expand All @@ -37,4 +42,4 @@ pedersen = ["hasher"]
mmr = ["hasher", "store"]
infinitely_stackable_mmr = ["mmr"]
merkle_tree = ["hasher", "store"]
incremental_merkle_tree = ["merkle_tree"]
incremental_merkle_tree = ["merkle_tree"]
45 changes: 3 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,9 @@

[![Cargo Test](https://github.com/HerodotusDev/rust-mmr/actions/workflows/ci.yml/badge.svg)](https://github.com/HerodotusDev/rust-mmr/actions/workflows/ci.yml)

## Example

```rust
use accumulators::{
hasher::{stark_poseidon::StarkPoseidonHasher, Hasher},
mmr::{
helpers::{AppendResult, Proof, ProofOptions},
MMR,
},
store::sqlite::SQLiteStore,
};

let store = SQLiteStore::new(":memory:").unwrap();
let hasher = StarkPoseidonHasher::new(Some(false));
store.init().expect("Failed to init store");

let mut mmr = MMR::new(store, hasher.clone(), None);

let _ = mmr.append("1".to_string()).unwrap();
let _ = mmr.append("2".to_string()).unwrap();
let _ = mmr.append("3".to_string()).unwrap();
let append_result = mmr.append("4".to_string()).unwrap();

let proof4 = mmr
.get_proof(append_result.element_index,
ProofOptions {
elements_count: None,
formatting_opts: None,
},
)
.unwrap();

mmr.verify_proof(
proof4,
"4".to_string(),
ProofOptions {
elements_count: None,
formatting_opts: None,
},
)
.unwrap(); //return true
```
## TODO: Description of available accumulators, stores, hashers, etc.

## TODO: How to use with features, what features are available, etc.

## Reference

Expand Down
34 changes: 34 additions & 0 deletions benches/incremental_benchmark.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use accumulators::{
hasher::stark_poseidon::StarkPoseidonHasher, merkle_tree::incremental::IncrementalMerkleTree,
store::sqlite::SQLiteStore,
};
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};

fn prepare_incremental(count: usize) -> IncrementalMerkleTree<SQLiteStore, StarkPoseidonHasher> {
let hasher = StarkPoseidonHasher::new(Some(false));

let store = SQLiteStore::new(":memory:").unwrap();
store.init().expect("Failed to init store");

IncrementalMerkleTree::initialize(count, "0x0".to_string(), hasher, store, None)
}

fn bench(c: &mut Criterion) {
{
let mut group = c.benchmark_group("Incremental Merkle Tree insertion");
let inputs = [10_000, 1_000_000];

for input in inputs.iter() {
group.bench_with_input(BenchmarkId::new("times", input), &input, |b, &&size| {
b.iter(|| prepare_incremental(size));
});
}
}
}

criterion_group!(
name = benches;
config = Criterion::default().sample_size(10);
targets = bench
);
criterion_main!(benches);
32 changes: 32 additions & 0 deletions src/merkle_tree/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Incremental Merkle Tree

Incremental Merkle Tree is a structure that contains a constant amount of hashes, allows updating a given hash and proving efficiently. Time complexity of both operations is O(log tree_size).

## Example

```rust
use accumulators::{
hasher::stark_poseidon::StarkPoseidonHasher, merkle_tree::incremental::IncrementalMerkleTree,
store::sqlite::SQLiteStore,
};
let store = SQLiteStore::new(":memory:").unwrap();
let hasher = StarkPoseidonHasher::new(Some(false));
store.init().expect("Failed to init store");
let tree = IncrementalMerkleTree::initialize(16, "0x0".to_string(), hasher, store, None);

let path = tree.get_inclusion_proof(10).unwrap();
let valid_proof = tree.verify_proof(10, "0x0", &path).unwrap();
assert_eq!(valid_proof, true);

let invalid_proof = tree.verify_proof(10, "0x1", &path).unwrap();
assert_eq!(invalid_proof, false);
```

### Benchmark

```sh
Incremental Merkle Tree insertion/times/10000
time: [154.39 ms 154.89 ms 155.38 ms]
Incremental Merkle Tree insertion/times/1000000
time: [17.946 s 18.027 s 18.125 s]
```
Loading