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

test: add readonly e2e test #1512

Merged
merged 5 commits into from
Jan 26, 2025
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,4 @@ program-tests/e2e-test/**/*.txt
output.txt
.nx/cache
.nx/workspace-data
output1.txt
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions forester/src/indexer_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,15 @@ impl<R: RpcConnection + light_client::rpc::merkle_tree::MerkleTreeExt> IndexerTy
async fn finalize_batch_address_tree_update(
rpc: &mut R,
indexer: &mut impl Indexer<R>,
new_merkle_tree_pubkey: Pubkey,
merkle_tree_pubkey: Pubkey,
) {
if let Some(test_indexer) = (indexer as &mut dyn Any).downcast_mut::<TestIndexer<R>>() {
let mut account = rpc.get_account(merkle_tree_pubkey).await.unwrap().unwrap();
test_indexer
.finalize_batched_address_tree_update(rpc, new_merkle_tree_pubkey)
.finalize_batched_address_tree_update(
merkle_tree_pubkey,
account.data.as_mut_slice(),
)
Comment on lines +124 to +127
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

had to adapt it to use it in E2eTestEnv (borrowing both &mut self.rpc and &mut self.indexer doesn't work)

.await;
}
}
Expand Down
39 changes: 18 additions & 21 deletions program-libs/batched-merkle-tree/src/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ pub struct Batch {
/// Number of inserted elements in the zkp batch.
num_inserted: u64,
state: u64,
current_zkp_batch_index: u64,
pub(crate) current_zkp_batch_index: u64,
num_inserted_zkps: u64,
/// Number of iterations for the bloom_filter.
pub num_iters: u64,
Expand Down Expand Up @@ -239,10 +239,11 @@ impl Batch {
/// Returns the index of a value by leaf index in the value store,
/// provided it could exist in the batch.
pub fn get_value_index_in_batch(&self, leaf_index: u64) -> Result<u64, BatchedMerkleTreeError> {
self.leaf_index_could_exist_in_batch(leaf_index)?;
leaf_index
self.check_leaf_index_exists(leaf_index)?;
let index = leaf_index
.checked_sub(self.start_index)
.ok_or(BatchedMerkleTreeError::LeafIndexNotInBatch)
.ok_or(BatchedMerkleTreeError::LeafIndexNotInBatch)?;
Ok(index)
}

/// Stores the value in a value store,
Expand Down Expand Up @@ -392,18 +393,22 @@ impl Batch {
Ok(self.get_state())
}

pub fn check_leaf_index_exists(&self, leaf_index: u64) -> Result<(), BatchedMerkleTreeError> {
if !self.leaf_index_exists(leaf_index) {
return Err(BatchedMerkleTreeError::LeafIndexNotInBatch);
}
Ok(())
}

/// Returns true if value of leaf index could exist in batch.
/// `True` doesn't mean that the value exists in the batch,
/// just that it is plausible. The value might already be spent
/// or never inserted in case an invalid index was provided.
pub fn leaf_index_could_exist_in_batch(
&self,
leaf_index: u64,
) -> Result<bool, BatchedMerkleTreeError> {
pub fn leaf_index_exists(&self, leaf_index: u64) -> bool {
let max_batch_leaf_index =
self.get_num_zkp_batches() * self.zkp_batch_size + self.start_index;
let min_batch_leaf_index = self.start_index;
Ok(leaf_index < max_batch_leaf_index && leaf_index >= min_batch_leaf_index)
leaf_index < max_batch_leaf_index && leaf_index >= min_batch_leaf_index
}
}

Expand Down Expand Up @@ -740,21 +745,13 @@ mod tests {
let highest_eligible_value =
batch.start_index + batch.get_num_zkp_batches() * batch.zkp_batch_size - 1;
// 1. Failing test lowest value in eligble range - 1
assert!(!batch
.leaf_index_could_exist_in_batch(lowest_eligible_value - 1)
.unwrap());
assert!(!batch.leaf_index_exists(lowest_eligible_value - 1));
// 2. Functional test lowest value in eligble range
assert!(batch
.leaf_index_could_exist_in_batch(lowest_eligible_value)
.unwrap());
assert!(batch.leaf_index_exists(lowest_eligible_value));
// 3. Functional test highest value in eligble range
assert!(batch
.leaf_index_could_exist_in_batch(highest_eligible_value)
.unwrap());
assert!(batch.leaf_index_exists(highest_eligible_value));
// 4. Failing test eligble range + 1
assert!(!batch
.leaf_index_could_exist_in_batch(highest_eligible_value + 1)
.unwrap());
assert!(!batch.leaf_index_exists(highest_eligible_value + 1));
}

/// 1. Failing: empty batch
Expand Down
3 changes: 3 additions & 0 deletions program-libs/batched-merkle-tree/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ pub enum BatchedMerkleTreeError {
TreeIsFull,
#[error("Value already exists in bloom filter.")]
NonInclusionCheckFailed,
#[error("Bloom filter must be zeroed prior to reusing a batch.")]
BloomFilterNotZeroed,
}

#[cfg(feature = "solana")]
Expand All @@ -62,6 +64,7 @@ impl From<BatchedMerkleTreeError> for u32 {
BatchedMerkleTreeError::InvalidIndex => 14309,
BatchedMerkleTreeError::TreeIsFull => 14310,
BatchedMerkleTreeError::NonInclusionCheckFailed => 14311,
BatchedMerkleTreeError::BloomFilterNotZeroed => 14312,
BatchedMerkleTreeError::Hasher(e) => e.into(),
BatchedMerkleTreeError::ZeroCopy(e) => e.into(),
BatchedMerkleTreeError::MerkleTreeMetadata(e) => e.into(),
Expand Down
Loading
Loading