Skip to content

Commit

Permalink
chore: add tests merkle-tree-metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
ananas-block committed Jan 21, 2025
1 parent 9054b6f commit 300edc6
Show file tree
Hide file tree
Showing 7 changed files with 311 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ fn test_rnd_account_init() {
}
let mut mt_account_data = vec![0; mt_account_size];

let merkle_tree_rent = rng.gen_range(0..10000000);
let merkle_tree_rent = rng.gen_range(1..10000000);

init_batched_address_merkle_tree_account(
owner,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,9 @@ fn test_rnd_account_init() {
let mut mt_account_data = vec![0; mt_account_size];
let mt_pubkey = Pubkey::new_unique();

let merkle_tree_rent = rng.gen_range(0..10000000);
let queue_rent = rng.gen_range(0..10000000);
let additional_bytes_rent = rng.gen_range(0..10000000);
let merkle_tree_rent = rng.gen_range(1..10000000);
let queue_rent = rng.gen_range(1..10000000);
let additional_bytes_rent = rng.gen_range(1..10000000);
init_batched_state_merkle_tree_accounts(
owner,
params,
Expand Down
17 changes: 17 additions & 0 deletions program-libs/merkle-tree-metadata/src/access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,20 @@ impl AccessMetadata {
}
}
}

#[test]
fn test_new() {
let owner = Pubkey::new_unique();
let program_owner = Pubkey::new_unique();
let forester = Pubkey::new_unique();
let access_metadata = AccessMetadata::new(owner, Some(program_owner), Some(forester));
assert_eq!(access_metadata.owner, owner);
assert_eq!(access_metadata.program_owner, program_owner);
assert_eq!(access_metadata.forester, forester);

// With no program owner and forester
let access_metadata = AccessMetadata::new(owner, None, None);
assert_eq!(access_metadata.owner, owner);
assert_eq!(access_metadata.program_owner, Pubkey::default());
assert_eq!(access_metadata.forester, Pubkey::default());
}
43 changes: 43 additions & 0 deletions program-libs/merkle-tree-metadata/src/merkle_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,46 @@ impl MerkleTreeMetadata {
Ok(())
}
}

#[test]
fn test() {
let owner = Pubkey::new_unique();
let program_owner = Some(Pubkey::new_unique());
let forester = Some(Pubkey::new_unique());
let access_metadata = AccessMetadata::new(owner, program_owner, forester);
let rollover_metadata = RolloverMetadata::new(1, 2, Some(95), 100, Some(1000), Some(1));
let associated_queue = Pubkey::new_unique();
let mut merkle_tree_metadata = MerkleTreeMetadata::default();
// 1. Functional - init
{
merkle_tree_metadata.init(access_metadata, rollover_metadata, associated_queue);
assert_eq!(merkle_tree_metadata.access_metadata, access_metadata);
assert_eq!(merkle_tree_metadata.rollover_metadata, rollover_metadata);
}
let next_merkle_tree = Pubkey::new_unique();
// 2. Failing - rollover with invalid associated queue
{
let invalid_associated_queue = Pubkey::new_unique();
let result = merkle_tree_metadata.rollover(invalid_associated_queue, next_merkle_tree);
assert_eq!(
result,
Err(MerkleTreeMetadataError::MerkleTreeAndQueueNotAssociated)
);
}
// 3. Functional - rollover
{
merkle_tree_metadata
.rollover(associated_queue, next_merkle_tree)
.unwrap();
assert_eq!(merkle_tree_metadata.next_merkle_tree, next_merkle_tree);
assert_eq!(merkle_tree_metadata.rollover_metadata.rolledover_slot, 1);
}
// 4. Failing - rollover with invalid associated queue
{
let result = merkle_tree_metadata.rollover(associated_queue, next_merkle_tree);
assert_eq!(
result,
Err(MerkleTreeMetadataError::MerkleTreeAlreadyRolledOver)
);
}
}
154 changes: 154 additions & 0 deletions program-libs/merkle-tree-metadata/src/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,157 @@ impl QueueMetadata {
Ok(())
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::access;

/// Helper function to create a default `QueueMetadata` struct for testing.
fn create_queue_metadata(
associated_merkle_tree: Pubkey,
queue_type: QueueType,
) -> QueueMetadata {
QueueMetadata {
access_metadata: AccessMetadata {
owner: Pubkey::new_unique(),
program_owner: Pubkey::new_unique(),
forester: Pubkey::new_unique(),
},
rollover_metadata: RolloverMetadata {
index: 0,
rollover_fee: 1000,
rollover_threshold: 95,
network_fee: 10,
rolledover_slot: u64::MAX,
close_threshold: 200,
additional_bytes: 0,
},
associated_merkle_tree,
next_queue: Pubkey::default(),
queue_type: queue_type as u64,
}
}

#[test]
fn test_check_queue_type_valid() {
let valid_queue_type = QueueType::NullifierQueue;
assert!(check_queue_type(&(valid_queue_type as u64), &valid_queue_type).is_ok());
}

#[test]
fn test_check_queue_type_invalid() {
let queue_type = QueueType::NullifierQueue;
let expected_queue_type = QueueType::AddressQueue;
assert!(matches!(
check_queue_type(&(queue_type as u64), &expected_queue_type),
Err(MerkleTreeMetadataError::InvalidQueueType)
));
}

#[test]
fn test_init_method() {
let associated_merkle_tree = Pubkey::new_unique();
let queue_type = QueueType::BatchedInput;
let access_metadata = access::AccessMetadata {
owner: Pubkey::new_unique(),
program_owner: Pubkey::new_unique(),
forester: Pubkey::new_unique(),
};
let rollover_metadata = RolloverMetadata {
index: 1,
rollover_fee: 1000,
rollover_threshold: 95,
network_fee: 10,
rolledover_slot: u64::MAX,
close_threshold: 200,
additional_bytes: 1,
};
let mut queue_metadata = QueueMetadata::default();
queue_metadata.init(
access_metadata,
rollover_metadata,
associated_merkle_tree,
queue_type,
);
assert_eq!(queue_metadata.access_metadata, access_metadata);
assert_eq!(queue_metadata.rollover_metadata, rollover_metadata);
assert_eq!(
queue_metadata.associated_merkle_tree,
associated_merkle_tree
);
assert_eq!(queue_metadata.queue_type, queue_type as u64);
}

#[test]
fn test_rollover_method_valid() {
let associated_merkle_tree = Pubkey::new_unique();
let next_queue = Pubkey::new_unique();
let mut queue_metadata =
create_queue_metadata(associated_merkle_tree, QueueType::NullifierQueue);

// Update the next queue as part of the method.
assert!(queue_metadata
.rollover(associated_merkle_tree, next_queue)
.is_ok());
assert_eq!(queue_metadata.next_queue, next_queue);
}

#[test]
fn test_rollover_method_invalid_merkle_tree() {
let associated_merkle_tree = Pubkey::new_unique();
let wrong_tree = Pubkey::new_unique();
let next_queue = Pubkey::new_unique();
let mut queue_metadata =
create_queue_metadata(associated_merkle_tree, QueueType::NullifierQueue);

// Should fail because `wrong_tree` does not match the associated merkle tree.
assert!(matches!(
queue_metadata.rollover(wrong_tree, next_queue),
Err(MerkleTreeMetadataError::MerkleTreeAndQueueNotAssociated)
));
}

#[test]
fn test_rollover_method_not_configured() {
let associated_merkle_tree = Pubkey::new_unique();
let mut queue_metadata =
create_queue_metadata(associated_merkle_tree, QueueType::NullifierQueue);

// Simulate a case where rollover threshold is not configured.
queue_metadata.rollover_metadata.rollover_threshold = u64::MAX;
assert!(matches!(
queue_metadata.rollover_metadata.rollover(),
Err(MerkleTreeMetadataError::RolloverNotConfigured)
));
}

#[test]
fn test_rollover_method_already_rolled_over() {
let associated_merkle_tree = Pubkey::new_unique();
let mut queue_metadata =
create_queue_metadata(associated_merkle_tree, QueueType::NullifierQueue);

// Simulate a case where it is already rolled over.
queue_metadata.rollover_metadata.rolledover_slot = 10;
assert!(matches!(
queue_metadata.rollover_metadata.rollover(),
Err(MerkleTreeMetadataError::MerkleTreeAlreadyRolledOver)
));
}

#[test]
fn test_queue_type_from() {
assert_eq!(QueueType::NullifierQueue, QueueType::from(1));
assert_eq!(QueueType::AddressQueue, QueueType::from(2));
assert_eq!(QueueType::BatchedInput, QueueType::from(3));
assert_eq!(QueueType::BatchedAddress, QueueType::from(4));
assert_eq!(QueueType::BatchedOutput, QueueType::from(5));
}

#[should_panic = "Invalid queue type"]
#[test]
fn test_queue_type_from_invalid() {
let _ = QueueType::from(0);
}
}
84 changes: 81 additions & 3 deletions program-libs/merkle-tree-metadata/src/rollover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,19 @@ impl RolloverMetadata {
Ok(())
}
}

pub fn check_rollover_fee_sufficient(
rollover_fee: u64,
queue_rent: u64,
merkle_tree_rent: u64,
rollover_threshold: u64,
height: u32,
) -> Result<(), MerkleTreeMetadataError> {
if rollover_fee != queue_rent + merkle_tree_rent
&& (rollover_fee * rollover_threshold * (2u64.pow(height))) / 100
< queue_rent + merkle_tree_rent
if rollover_threshold == 0 && rollover_fee >= queue_rent + merkle_tree_rent {
return Ok(());
}
if (rollover_fee * rollover_threshold * (2u64.pow(height))) / 100
< queue_rent + merkle_tree_rent
{
msg!("rollover_fee: {}", rollover_fee);
msg!("rollover_threshold: {}", rollover_threshold);
Expand All @@ -113,6 +116,8 @@ pub fn check_rollover_fee_sufficient(

#[cfg(test)]
mod tests {
use light_utils::fee::compute_rollover_fee;

use super::*;

#[test]
Expand Down Expand Up @@ -147,4 +152,77 @@ mod tests {
Err(MerkleTreeMetadataError::MerkleTreeAlreadyRolledOver)
);
}

#[test]
fn test_check_rollover_fee_sufficient() {
let queue_rent = 1_000_000_000;
let merkle_tree_rent = 1_000_000_000;
let rollover_threshold = 95;
let tree_height = 20;
let total_rent = queue_rent + merkle_tree_rent;
let rollover_fee =
compute_rollover_fee(rollover_threshold, tree_height, total_rent).unwrap();
println!("rollover_fee: {}", rollover_fee);
assert!(check_rollover_fee_sufficient(
rollover_fee,
queue_rent,
merkle_tree_rent,
rollover_threshold,
tree_height
)
.is_ok());

{
let invalid_height = 19;
assert_eq!(
check_rollover_fee_sufficient(
rollover_fee,
queue_rent,
merkle_tree_rent,
rollover_threshold,
invalid_height
),
Err(MerkleTreeMetadataError::InsufficientRolloverFee)
);
}
{
let invalid_threshold = 90;
assert_eq!(
check_rollover_fee_sufficient(
rollover_fee,
queue_rent,
merkle_tree_rent,
invalid_threshold,
tree_height
),
Err(MerkleTreeMetadataError::InsufficientRolloverFee)
);
}
{
let invalid_queue_rent = queue_rent + 1_000_000_000;
assert_eq!(
check_rollover_fee_sufficient(
rollover_fee,
invalid_queue_rent,
merkle_tree_rent,
rollover_threshold,
tree_height
),
Err(MerkleTreeMetadataError::InsufficientRolloverFee)
);
}
{
let rollover_fee = rollover_fee - 1;
assert_eq!(
check_rollover_fee_sufficient(
rollover_fee,
queue_rent,
merkle_tree_rent,
rollover_threshold,
tree_height
),
Err(MerkleTreeMetadataError::InsufficientRolloverFee)
);
}
}
}
12 changes: 12 additions & 0 deletions program-libs/merkle-tree-metadata/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,15 @@ where
Some(value)
}
}

#[test]
fn test_if_equals_zero_u64() {
assert_eq!(if_equals_zero_u64(0), None);
assert_eq!(if_equals_zero_u64(1), Some(1));
}

#[test]
fn test_if_equals_none() {
assert_eq!(if_equals_none(0, 0), None);
assert_eq!(if_equals_none(1, 0), Some(1));
}

0 comments on commit 300edc6

Please sign in to comment.