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

fix: make e2e test with address queue updates concurrent #872

Merged
merged 5 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Large diffs are not rendered by default.

13 changes: 7 additions & 6 deletions forester/src/nullifier/address_queue_nullifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub async fn empty_address_queue<T: Indexer, R: RpcConnection>(

loop {
let merkle_tree =
get_indexed_merkle_tree::<AddressMerkleTreeAccount, R, Poseidon, usize, 26>(
get_indexed_merkle_tree::<AddressMerkleTreeAccount, R, Poseidon, usize, 26, 16>(
rpc,
address_merkle_tree_pubkey,
)
Expand Down Expand Up @@ -97,11 +97,12 @@ pub async fn get_changelog_indices<R: RpcConnection>(
merkle_tree_pubkey: &Pubkey,
client: &mut R,
) -> Result<(usize, usize), ForesterError> {
let merkle_tree = get_indexed_merkle_tree::<AddressMerkleTreeAccount, R, Poseidon, usize, 26>(
client,
*merkle_tree_pubkey,
)
.await;
let merkle_tree =
get_indexed_merkle_tree::<AddressMerkleTreeAccount, R, Poseidon, usize, 26, 16>(
client,
*merkle_tree_pubkey,
)
.await;
let changelog_index = merkle_tree.changelog_index();
let indexed_changelog_index = merkle_tree.indexed_changelog_index();
Ok((changelog_index, indexed_changelog_index))
Expand Down
2 changes: 1 addition & 1 deletion js/stateless.js/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export const STATE_MERKLE_TREE_ROLLOVER_FEE = new BN(185);
*
* Is charged per newly created address.
*/
export const ADDRESS_QUEUE_ROLLOVER_FEE = new BN(188);
export const ADDRESS_QUEUE_ROLLOVER_FEE = new BN(202);

/**
* Is charged if the transaction nullifies at least one compressed account.
Expand Down
6 changes: 3 additions & 3 deletions merkle-tree/indexed/src/changelog.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use light_bounded_vec::BoundedVec;
use light_concurrent_merkle_tree::event::RawIndexedElement;

/// NET_HEIGHT = HEIGHT - CANOPY_DEPTH
#[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],
/// Index of a changelog entry in `ConcurrentMerkleTree` corresponding to
/// the same operation.
pub changelog_index: usize,
Expand Down
30 changes: 18 additions & 12 deletions merkle-tree/indexed/src/copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use num_traits::{CheckedAdd, CheckedSub, ToBytes, Unsigned};
use crate::{errors::IndexedMerkleTreeError, IndexedMerkleTree};

#[derive(Debug)]
pub struct IndexedMerkleTreeCopy<H, I, const HEIGHT: usize>(IndexedMerkleTree<H, I, HEIGHT>)
pub struct IndexedMerkleTreeCopy<H, I, const HEIGHT: usize, const NET_HEIGHT: usize>(
IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>,
)
where
H: Hasher,
I: CheckedAdd
Expand All @@ -25,7 +27,8 @@ where
+ Unsigned,
usize: From<I>;

impl<H, I, const HEIGHT: usize> IndexedMerkleTreeCopy<H, I, HEIGHT>
impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize>
IndexedMerkleTreeCopy<H, I, HEIGHT, NET_HEIGHT>
where
H: Hasher,
I: CheckedAdd
Expand Down Expand Up @@ -53,7 +56,7 @@ where
let indexed_changelog_metadata: CyclicBoundedVecMetadata =
unsafe { read_value_at(bytes, &mut offset) };

let expected_size = IndexedMerkleTree::<H, I, HEIGHT>::size_in_account(
let expected_size = IndexedMerkleTree::<H, I, HEIGHT, NET_HEIGHT>::size_in_account(
merkle_tree.height,
merkle_tree.changelog.capacity(),
merkle_tree.roots.capacity(),
Expand All @@ -65,7 +68,6 @@ where
ConcurrentMerkleTreeError::BufferSize(expected_size, bytes.len()),
));
}

let indexed_changelog =
unsafe { read_cyclic_bounded_vec_at(bytes, &mut offset, &indexed_changelog_metadata) };

Expand All @@ -77,7 +79,8 @@ where
}
}

impl<H, I, const HEIGHT: usize> Deref for IndexedMerkleTreeCopy<H, I, HEIGHT>
impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize> Deref
for IndexedMerkleTreeCopy<H, I, HEIGHT, NET_HEIGHT>
where
H: Hasher,
I: CheckedAdd
Expand All @@ -91,7 +94,7 @@ where
+ Unsigned,
usize: From<I>,
{
type Target = IndexedMerkleTree<H, I, HEIGHT>;
type Target = IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>;

fn deref(&self) -> &Self::Target {
&self.0
Expand All @@ -116,8 +119,9 @@ mod test {
const CANOPY_DEPTH: usize,
const INDEXED_CHANGELOG_SIZE: usize,
const OPERATIONS: usize,
const NET_HEIGHT: usize,
>() {
let mut mt_1 = IndexedMerkleTree::<Poseidon, usize, HEIGHT>::new(
let mut mt_1 = IndexedMerkleTree::<Poseidon, usize, HEIGHT, NET_HEIGHT>::new(
HEIGHT,
CHANGELOG_SIZE,
ROOTS,
Expand All @@ -129,7 +133,7 @@ mod test {

let mut bytes = vec![
0u8;
IndexedMerkleTree::<Poseidon, usize, HEIGHT>::size_in_account(
IndexedMerkleTree::<Poseidon, usize, HEIGHT, NET_HEIGHT>::size_in_account(
HEIGHT,
CHANGELOG_SIZE,
ROOTS,
Expand All @@ -140,7 +144,7 @@ mod test {

{
let mut mt_2 =
IndexedMerkleTreeZeroCopyMut::<Poseidon, usize, HEIGHT>::from_bytes_zero_copy_init(
IndexedMerkleTreeZeroCopyMut::<Poseidon, usize, HEIGHT, NET_HEIGHT>::from_bytes_zero_copy_init(
&mut bytes,
HEIGHT,
CANOPY_DEPTH,
Expand All @@ -159,7 +163,7 @@ mod test {
for _ in 0..OPERATIONS {
// Reload the tree from bytes on each iteration.
let mut mt_2 =
IndexedMerkleTreeZeroCopyMut::<Poseidon, usize, HEIGHT>::from_bytes_zero_copy_mut(
IndexedMerkleTreeZeroCopyMut::<Poseidon, usize, HEIGHT,NET_HEIGHT>::from_bytes_zero_copy_mut(
&mut bytes,
)
.unwrap();
Expand All @@ -173,7 +177,8 @@ mod test {

// Read a copy of that Merkle tree.
let mt_2 =
IndexedMerkleTreeCopy::<Poseidon, usize, HEIGHT>::from_bytes_copy(&bytes).unwrap();
IndexedMerkleTreeCopy::<Poseidon, usize, HEIGHT, NET_HEIGHT>::from_bytes_copy(&bytes)
.unwrap();

assert_eq!(mt_1, *mt_2);
}
Expand All @@ -185,7 +190,7 @@ mod test {
const ROOTS: usize = 2400;
const CANOPY_DEPTH: usize = 10;
const INDEXED_CHANGELOG_SIZE: usize = 256;

const NET_HEIGHT: usize = 16;
const OPERATIONS: usize = 1024;

from_bytes_copy::<
Expand All @@ -195,6 +200,7 @@ mod test {
CANOPY_DEPTH,
INDEXED_CHANGELOG_SIZE,
OPERATIONS,
NET_HEIGHT,
>()
}
}
50 changes: 28 additions & 22 deletions merkle-tree/indexed/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub const HIGHEST_ADDRESS_PLUS_ONE: &str =

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

_index: PhantomData<I>,
}

pub type IndexedMerkleTree22<H, I> = IndexedMerkleTree<H, I, 22>;
pub type IndexedMerkleTree26<H, I> = IndexedMerkleTree<H, I, 26>;
pub type IndexedMerkleTree32<H, I> = IndexedMerkleTree<H, I, 32>;
pub type IndexedMerkleTree40<H, I> = IndexedMerkleTree<H, I, 40>;
pub type IndexedMerkleTree22<H, I> = IndexedMerkleTree<H, I, 22, 12>;
pub type IndexedMerkleTree26<H, I> = IndexedMerkleTree<H, I, 26, 16>;
pub type IndexedMerkleTree32<H, I> = IndexedMerkleTree<H, I, 32, 22>;
pub type IndexedMerkleTree40<H, I> = IndexedMerkleTree<H, I, 40, 30>;

impl<H, I, const HEIGHT: usize> IndexedMerkleTree<H, I, HEIGHT>
impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize> IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>
where
H: Hasher,
I: CheckedAdd
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, NET_HEIGHT>>() * indexed_changelog_size
}

pub fn new(
Expand Down Expand Up @@ -137,11 +137,10 @@ where
};
let changelog_entry = IndexedChangelogEntry {
element,
proof: BoundedVec::from_slice(&H::zero_bytes()[..self.height]),
proof: H::zero_bytes()[..NET_HEIGHT].try_into().unwrap(),
changelog_index: 0,
};
self.indexed_changelog.push(changelog_entry);

Ok(())
}

Expand Down Expand Up @@ -180,16 +179,16 @@ where
)?;

// Emit changelog for low element.
let proof = BoundedVec::from_slice(&H::zero_bytes()[..self.height]);
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,
next_value: bigint_to_be_bytes_array::<32>(&element_bundle.new_element.value)?,
index: element_bundle.new_low_element.index,
};

let low_element_changelog_entry = IndexedChangelogEntry {
element: low_element,
proof,
proof: H::zero_bytes()[..NET_HEIGHT].try_into().unwrap(),
changelog_index,
};
self.indexed_changelog.push(low_element_changelog_entry);
Expand All @@ -209,9 +208,10 @@ where
};
let new_element_changelog_entry = IndexedChangelogEntry {
element: new_element,
proof,
proof: proof.as_slice()[..NET_HEIGHT].try_into().unwrap(),
changelog_index,
};

self.indexed_changelog.push(new_element_changelog_entry);

Ok(())
Expand Down Expand Up @@ -297,21 +297,25 @@ 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);
for i in 0..low_leaf_proof.len() {
low_leaf_proof[i] = changelog_entry.proof[i];
}
}

// If we found a new low element.
if let Some((new_low_element_changelog_index, new_low_element)) = new_low_element {
let new_low_element_changelog_entry =
&self.indexed_changelog[new_low_element_changelog_index];

*changelog_index = new_low_element_changelog_entry.changelog_index;
*low_element = IndexedElement {
index: new_low_element_changelog_entry.element.index,
value: new_low_element.clone(),
next_index: new_low_element_changelog_entry.element.next_index,
};
low_leaf_proof.clone_from(&new_low_element_changelog_entry.proof);

for i in 0..low_leaf_proof.len() {
low_leaf_proof[i] = new_low_element_changelog_entry.proof[i];
}
new_element.next_index = low_element.next_index;

// Start the patching process from scratch for the new low element.
Expand Down Expand Up @@ -345,7 +349,6 @@ where
&mut low_element_next_value,
low_leaf_proof,
)?;

// 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 @@ -399,7 +402,7 @@ where
};
let low_element_changelog_entry = IndexedChangelogEntry {
element: new_low_element,
proof: low_leaf_proof.clone(),
proof: low_leaf_proof.as_slice()[..NET_HEIGHT].try_into().unwrap(),
changelog_index: new_changelog_index,
};

Expand Down Expand Up @@ -428,7 +431,7 @@ where
// Emit changelog entry for new element.
let new_element_changelog_entry = IndexedChangelogEntry {
element: raw_new_element,
proof,
proof: proof.as_slice()[..NET_HEIGHT].try_into().unwrap(),
changelog_index: new_changelog_index,
};
self.indexed_changelog.push(new_element_changelog_entry);
Expand All @@ -444,7 +447,8 @@ where
}
}

impl<H, I, const HEIGHT: usize> Deref for IndexedMerkleTree<H, I, HEIGHT>
impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize> Deref
for IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>
where
H: Hasher,
I: CheckedAdd
Expand All @@ -465,7 +469,8 @@ where
}
}

impl<H, I, const HEIGHT: usize> DerefMut for IndexedMerkleTree<H, I, HEIGHT>
impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize> DerefMut
for IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>
where
H: Hasher,
I: CheckedAdd
Expand All @@ -484,7 +489,8 @@ where
}
}

impl<H, I, const HEIGHT: usize> PartialEq for IndexedMerkleTree<H, I, HEIGHT>
impl<H, I, const HEIGHT: usize, const NET_HEIGHT: usize> PartialEq
for IndexedMerkleTree<H, I, HEIGHT, NET_HEIGHT>
where
H: Hasher,
I: CheckedAdd
Expand Down
Loading