Skip to content

Commit

Permalink
Merge pull request #8 from HerodotusDev/feat/incremental-merkle-tree
Browse files Browse the repository at this point in the history
incremental merkle tree
  • Loading branch information
rkdud007 authored Nov 7, 2023
2 parents ba2609a + d0b4c0d commit 0fd0c8e
Show file tree
Hide file tree
Showing 9 changed files with 647 additions and 45 deletions.
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

0 comments on commit 0fd0c8e

Please sign in to comment.