account_compression/processor/
initialize_address_queue.rs

1use anchor_lang::prelude::*;
2use light_utils::fee::compute_rollover_fee;
3
4use crate::{
5    state::{queue_from_bytes_zero_copy_init, QueueAccount},
6    AccessMetadata, QueueType, RolloverMetadata,
7};
8
9pub fn process_initialize_address_queue<'info>(
10    queue_account_info: &AccountInfo<'info>,
11    queue_loader: &AccountLoader<'info, QueueAccount>,
12    index: u64,
13    owner: Pubkey,
14    program_owner: Option<Pubkey>,
15    forester: Option<Pubkey>,
16    associated_merkle_tree: Pubkey,
17    capacity: u16,
18    sequence_threshold: u64,
19    network_fee: u64,
20    rollover_threshold: Option<u64>,
21    close_threshold: Option<u64>,
22    height: u32,
23    merkle_tree_rent: u64,
24) -> Result<()> {
25    {
26        let mut address_queue = queue_loader.load_init()?;
27
28        // Since the user doesn't interact with the address Merkle tree
29        // directly, we need to charge a `rollover_fee` both for the queue and
30        // Merkle tree.
31        let queue_rent = queue_account_info.lamports();
32        let rollover_fee = if let Some(rollover_threshold) = rollover_threshold {
33            let rollover_fee = compute_rollover_fee(rollover_threshold, height, merkle_tree_rent)
34                .map_err(ProgramError::from)?
35                + compute_rollover_fee(rollover_threshold, height, queue_rent)
36                    .map_err(ProgramError::from)?;
37            check_rollover_fee_sufficient(
38                rollover_fee,
39                queue_rent,
40                merkle_tree_rent,
41                rollover_threshold,
42                height,
43            )?;
44            msg!("address queue rollover_fee: {}", rollover_fee);
45            rollover_fee
46        } else {
47            0
48        };
49
50        address_queue.init(
51            AccessMetadata::new(owner, program_owner, forester),
52            RolloverMetadata::new(
53                index,
54                rollover_fee,
55                rollover_threshold,
56                network_fee,
57                close_threshold,
58                None,
59            ),
60            associated_merkle_tree,
61            QueueType::AddressQueue,
62        );
63
64        drop(address_queue);
65    }
66
67    unsafe {
68        queue_from_bytes_zero_copy_init(
69            &mut queue_account_info.try_borrow_mut_data()?,
70            capacity as usize,
71            sequence_threshold as usize,
72        )
73        .map_err(ProgramError::from)?;
74    }
75
76    Ok(())
77}
78
79pub fn check_rollover_fee_sufficient(
80    rollover_fee: u64,
81    queue_rent: u64,
82    merkle_tree_rent: u64,
83    rollover_threshold: u64,
84    height: u32,
85) -> Result<()> {
86    if rollover_fee != queue_rent + merkle_tree_rent
87        && (rollover_fee * rollover_threshold * (2u64.pow(height))) / 100
88            < queue_rent + merkle_tree_rent
89    {
90        msg!("rollover_fee: {}", rollover_fee);
91        msg!("rollover_threshold: {}", rollover_threshold);
92        msg!("height: {}", height);
93        msg!("merkle_tree_rent: {}", merkle_tree_rent);
94        msg!("queue_rent: {}", queue_rent);
95        msg!(
96            "((rollover_fee * rollover_threshold * (2u64.pow(height))) / 100): {} < {} rent",
97            ((rollover_fee * rollover_threshold * (2u64.pow(height))) / 100),
98            queue_rent + merkle_tree_rent
99        );
100        return err!(crate::errors::AccountCompressionErrorCode::InsufficientRolloverFee);
101    }
102    Ok(())
103}