Skip to content

Commit

Permalink
fixed onchain indexed Merkle tree concurrency
Browse files Browse the repository at this point in the history
  • Loading branch information
ananas-block committed Jun 26, 2024
1 parent ed1be81 commit 63335aa
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 101 deletions.
2 changes: 1 addition & 1 deletion merkle-tree/concurrent/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ where
return Err(ConcurrentMerkleTreeError::CannotUpdateEmpty);
}

if self.canopy_depth > 0 {
if self.canopy_depth > 0 && proof.len() != self.height {
self.update_proof_from_canopy(leaf_index, proof)?;
}
if changelog_index != self.changelog_index() {
Expand Down
5 changes: 2 additions & 3 deletions merkle-tree/indexed/src/changelog.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use light_bounded_vec::BoundedVec;
use light_concurrent_merkle_tree::event::RawIndexedElement;

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct IndexedChangelogEntry<I>
pub struct IndexedChangelogEntry<I, const NET_HEIGHT: usize>
where
I: Clone,
{
/// Element that was a subject to the change.
pub element: RawIndexedElement<I>,
/// Merkle proof of that operation.
pub proof: BoundedVec<[u8; 32]>,
pub proof: [[u8; 32]; NET_HEIGHT], // TODO: add const generic HEIGHT - CANOPY_DEPTH
/// Index of a changelog entry in `ConcurrentMerkleTree` corresponding to
/// the same operation.
pub changelog_index: usize,
Expand Down
4 changes: 4 additions & 0 deletions merkle-tree/indexed/src/copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,13 @@ where
ConcurrentMerkleTreeError::BufferSize(expected_size, bytes.len()),
));
}
println!("pre offset {} ", offset);

let indexed_changelog =
unsafe { read_cyclic_bounded_vec_at(bytes, &mut offset, &indexed_changelog_metadata) };
println!("pre offset {} ", offset);
println!("meta data {:?}", indexed_changelog_metadata);
println!("bytes len {}", bytes.len());

Ok(Self(IndexedMerkleTree {
merkle_tree,
Expand Down
72 changes: 48 additions & 24 deletions merkle-tree/indexed/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use crate::errors::IndexedMerkleTreeError;

pub const HIGHEST_ADDRESS_PLUS_ONE: &str =
"452312848583266388373324160190187140051835877600158453279131187530910662655";

// , const NET_HEIGHT: usize
#[derive(Debug)]
#[repr(C)]
pub struct IndexedMerkleTree<H, I, const HEIGHT: usize>
Expand All @@ -47,7 +47,7 @@ where
usize: From<I>,
{
pub merkle_tree: ConcurrentMerkleTree<H, HEIGHT>,
pub indexed_changelog: CyclicBoundedVec<IndexedChangelogEntry<I>>,
pub indexed_changelog: CyclicBoundedVec<IndexedChangelogEntry<I, HEIGHT>>,

_index: PhantomData<I>,
}
Expand Down Expand Up @@ -96,7 +96,7 @@ where
// indexed_changelog (metadata)
+ mem::size_of::<CyclicBoundedVecMetadata>()
// indexed_changelog
+ mem::size_of::<IndexedChangelogEntry<I>>() * indexed_changelog_size
+ mem::size_of::<IndexedChangelogEntry<I, HEIGHT>>() * indexed_changelog_size
}

pub fn new(
Expand Down Expand Up @@ -135,9 +135,16 @@ where
next_value: [0_u8; 32],
index: I::zero(),
};
#[cfg(target_os = "solana")]
{
use solana_program::msg;
msg!("height: {}", self.height);
msg!("canopy_depth: {}", self.merkle_tree.canopy_depth);
msg!("height - canopy_depth: {}", self.height);
}
let changelog_entry = IndexedChangelogEntry {
element,
proof: BoundedVec::from_slice(&H::zero_bytes()[..self.height]),
proof: H::zero_bytes()[..self.height].try_into().unwrap(),
changelog_index: 0,
};
self.indexed_changelog.push(changelog_entry);
Expand Down Expand Up @@ -180,7 +187,7 @@ where
)?;

// Emit changelog for low element.
let proof = BoundedVec::from_slice(&H::zero_bytes()[..self.height]);
// let proof = BoundedVec::from_slice(&);
let low_element = RawIndexedElement {
value: bigint_to_be_bytes_array::<32>(&element_bundle.new_low_element.value)?,
next_index: element_bundle.new_low_element.next_index,
Expand All @@ -189,7 +196,7 @@ where
};
let low_element_changelog_entry = IndexedChangelogEntry {
element: low_element,
proof,
proof: H::zero_bytes()[..self.height].try_into().unwrap(),
changelog_index,
};
self.indexed_changelog.push(low_element_changelog_entry);
Expand All @@ -209,7 +216,7 @@ where
};
let new_element_changelog_entry = IndexedChangelogEntry {
element: new_element,
proof,
proof: proof.to_array()?,
changelog_index,
};
self.indexed_changelog.push(new_element_changelog_entry);
Expand Down Expand Up @@ -320,7 +327,12 @@ where
// Patch the next value.
*low_element_next_value = BigUint::from_bytes_be(&changelog_entry.element.next_value);
// Patch the proof.
low_leaf_proof.clone_from(&changelog_entry.proof);
// low_leaf_proof.clone_from(&BoundedVec::from_slice(&changelog_entry.proof[0..len]));
for i in 0..low_leaf_proof.len() {
low_leaf_proof[i] = changelog_entry.proof[i];
}
#[cfg(target_os = "solana")]
solana_program::msg!("low_leaf_proof len: {:?}", low_leaf_proof.len());
}

// If we found a new low element.
Expand All @@ -342,18 +354,18 @@ where
solana_program::msg!("low_leaf_proof len: {:?}", low_leaf_proof.len());
#[cfg(target_os = "solana")]
{
solana_program::msg!(
"new_low_element_changelog_entry len: {:?}",
new_low_element_changelog_entry.proof.len()
);
solana_program::msg!(
"new_low_element_changelog_entry proof: {:?}",
new_low_element_changelog_entry.proof
);
solana_program::msg!(
"new_low_element_changelog_entry element: {:?}",
new_low_element_changelog_entry.element
);
// solana_program::msg!(
// "new_low_element_changelog_entry len: {:?}",
// new_low_element_changelog_entry.proof.len()
// );
// solana_program::msg!(
// "new_low_element_changelog_entry proof: {:?}",
// new_low_element_changelog_entry.proof
// );
// solana_program::msg!(
// "new_low_element_changelog_entry element: {:?}",
// new_low_element_changelog_entry.element
// );
}
#[cfg(not(target_os = "solana"))]
{
Expand All @@ -371,7 +383,12 @@ where
);
}

low_leaf_proof.clone_from(&new_low_element_changelog_entry.proof);
// low_leaf_proof.clone_from(&BoundedVec::from_slice(
// &new_low_element_changelog_entry.proof[0..len],
// ));
for i in 0..low_leaf_proof.len() {
low_leaf_proof[i] = new_low_element_changelog_entry.proof[i];
}
#[cfg(target_os = "solana")]
solana_program::msg!("low_leaf_proof len: {:?}", low_leaf_proof.len());
new_element.next_index = low_element.next_index;
Expand Down Expand Up @@ -399,6 +416,10 @@ where
mut low_element_next_value: BigUint,
low_leaf_proof: &mut BoundedVec<[u8; 32]>,
) -> Result<IndexedMerkleTreeUpdate<I>, IndexedMerkleTreeError> {
#[cfg(target_os = "solana")]
{
solana_program::msg!("low leaf proof capacity {:?}", low_leaf_proof.capacity());
}
self.patch_elements_and_proof(
indexed_changelog_index,
&mut changelog_index,
Expand All @@ -407,7 +428,10 @@ where
&mut low_element_next_value,
low_leaf_proof,
)?;

#[cfg(target_os = "solana")]
{
solana_program::msg!("low leaf proof capacity {:?}", low_leaf_proof.capacity());
}
// Check that the value of `new_element` belongs to the range
// of `old_low_element`.
if low_element.next_index == I::zero() {
Expand Down Expand Up @@ -461,7 +485,7 @@ where
};
let low_element_changelog_entry = IndexedChangelogEntry {
element: new_low_element,
proof: low_leaf_proof.clone(),
proof: low_leaf_proof.to_array()?,
changelog_index: new_changelog_index,
};

Expand Down Expand Up @@ -499,7 +523,7 @@ where
// Emit changelog entry for new element.
let new_element_changelog_entry = IndexedChangelogEntry {
element: raw_new_element,
proof,
proof: proof.to_array()?,
changelog_index: new_changelog_index,
};
self.indexed_changelog.push(new_element_changelog_entry);
Expand Down
6 changes: 6 additions & 0 deletions merkle-tree/indexed/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,12 @@ fn perform_change_log_test<
}
}
}
let mut bytes = vec![
0u8;
IndexedMerkleTree::<Poseidon, usize, HEIGHT>::size_in_account(
HEIGHT, 1400, ROOTS, 10, 256
)
];
}

fn perform_change_log_test_2<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub fn process_initialize_address_queue<'info>(
} else {
0
};

msg!(" addres squeue rollover_fee: {}", rollover_fee);
address_queue.init(
AccessMetadata::new(owner, program_owner),
RolloverMetadata::new(
Expand Down
16 changes: 8 additions & 8 deletions test-utils/src/assert_address_merkle_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,14 @@ pub async fn assert_address_merkle_tree_initialized<R: RpcConnection>(
);
assert_eq!(&merkle_tree.rightmost_leaf(), expected_rightmost_leaf);

assert_eq!(
merkle_tree.changelog.len(),
expected_indexed_changelog_length
);
assert_eq!(
merkle_tree.changelog.len(),
expected_indexed_changelog_length
);
// assert_eq!(
// merkle_tree.changelog.len(),
// expected_indexed_changelog_length
// );
// assert_eq!(
// merkle_tree.changelog.capacity(),
// expected_indexed_changelog_length
// );
// for i in merkle_tree.changelog.iter() {
// println!("changelog: {:?}", i);
// }
Expand Down
2 changes: 1 addition & 1 deletion test-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ where

ConcurrentMerkleTreeCopy::from_bytes_copy(&account.data[8 + mem::size_of::<T>()..]).unwrap()
}

// TODO: do discriminator check
/// Fetches the fiven account, then copies and serializes it as an
/// `IndexedMerkleTree`.
pub async fn get_indexed_merkle_tree<T, R, H, I, const HEIGHT: usize>(
Expand Down
Loading

0 comments on commit 63335aa

Please sign in to comment.