Skip to content

Commit

Permalink
[feat] Implement adding new leaves to the stump #267 (#283)
Browse files Browse the repository at this point in the history
  • Loading branch information
baitcode authored Oct 22, 2024
1 parent 3f9696f commit 2c6b36b
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 8 deletions.
1 change: 1 addition & 0 deletions packages/utils/src/numeric.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub fn u32_byte_reverse(word: u32) -> u32 {
}

/// Computes the next power of two of a u64 variable.
/// returns 2^x, where x is the smallest integer such that 2^x >= n.
pub fn u64_next_power_of_two(mut n: u64) -> u64 {
if n == 0 {
return 1;
Expand Down
42 changes: 39 additions & 3 deletions packages/utreexo/src/stump/accumulator.cairo
Original file line number Diff line number Diff line change
@@ -1,13 +1,49 @@
use core::traits::DivRem;
use crate::stump::state::UtreexoStumpState;
use crate::stump::proof::{UtreexoBatchProof, UtreexoBatchProofTrait};
use crate::parent_hash;


#[generate_trait]
pub impl StumpUtreexoAccumulatorImpl of StumpUtreexoAccumulator {
/// Adds multiple items to the accumulator.
fn add(self: @UtreexoStumpState, hashes: Span<felt252>) -> UtreexoStumpState {
// TODO: check if vanilla implementation is compatible with rustreexo, add tests
// https://github.com/mit-dci/rustreexo/blob/6a8fe53fa545df8f1a30733fa6ca9f7b0077d051/src/accumulator/stump.rs#L252
*self
let mut leaves = *self.num_leaves;

// This array will hold state of roots after adding new hashes
// IMPORTANT: This line copies all roots from the current state
// to the new array
let mut new_roots: Array<Option<felt252>> = (*self.roots).into();

for add in hashes {
// We will use new_roots_span to iterate over the roots that we
// will merge (thus remove from the state) with the new hash.
let mut new_roots_span = new_roots.span();
let mut to_add = *add;

// This is similar to the vanilla algorithm
let (mut next_row_len, mut has_root) = DivRem::div_rem(leaves, 2);
while has_root == 1 {
// Checks that new_roots_span is not empty
if let Option::Some(root) = new_roots_span.pop_back() {
// Checks that root has value
if let Option::Some(root) = root {
// Merging with the hash
to_add = parent_hash(*root, to_add);
}
}

let (q, r) = DivRem::div_rem(next_row_len, 2);
next_row_len = q;
has_root = r;
};

new_roots = new_roots_span.into();
new_roots.append(Option::Some(to_add));
leaves += 1;
};

UtreexoStumpState { roots: new_roots.span(), num_leaves: leaves, }
}

/// Verifies that specified leaves are part of the utreexo forest given a proof.
Expand Down
4 changes: 3 additions & 1 deletion packages/utreexo/src/test.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct Args {
fn main(mut arguments: Span<felt252>, _flags: felt252) {
let mut gas_before = get_available_gas();

let Args { mut state, proof, leaves_to_del, leaves_to_add: _, expected_state } =
let Args { mut state, proof, leaves_to_del, leaves_to_add, expected_state } =
Serde::deserialize(
ref arguments
)
Expand All @@ -29,6 +29,8 @@ fn main(mut arguments: Span<felt252>, _flags: felt252) {
}
}

state = state.add(leaves_to_add.span());

if state != expected_state {
println!(
"FAIL: gas_spent={} error='expected state {:?}, actual {:?}'",
Expand Down
4 changes: 0 additions & 4 deletions packages/utreexo/tests/data/ignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ deletion_test_case_4.json
deletion_test_case_5.json
deletion_test_case_6.json
deletion_test_case_10.json
insertion_test_case_0.json
insertion_test_case_1.json
insertion_test_case_2.json
insertion_test_case_3.json
update_data_test_case_0.json
update_data_test_case_1.json
update_data_test_case_2.json
Expand Down

0 comments on commit 2c6b36b

Please sign in to comment.