account_compression/state/
queue.rs1use crate::InsertIntoQueues;
2use crate::{errors::AccountCompressionErrorCode, AccessMetadata, RolloverMetadata};
3use crate::{
4 utils::check_signer_is_registered_or_authority::{GroupAccess, GroupAccounts},
5 RegisteredProgram,
6};
7use aligned_sized::aligned_sized;
8use anchor_lang::prelude::*;
9use light_hash_set::{zero_copy::HashSetZeroCopy, HashSet};
10use std::mem;
11
12#[account(zero_copy)]
13#[derive(AnchorDeserialize, Debug, PartialEq)]
14pub struct QueueMetadata {
15 pub access_metadata: AccessMetadata,
16 pub rollover_metadata: RolloverMetadata,
17
18 pub associated_merkle_tree: Pubkey,
20 pub next_queue: Pubkey,
22 pub queue_type: u64,
23}
24
25#[derive(AnchorDeserialize, AnchorSerialize, Debug, PartialEq, Clone, Copy)]
26#[repr(u8)]
27pub enum QueueType {
28 NullifierQueue = 1,
29 AddressQueue = 2,
30}
31
32pub fn check_queue_type(queue_type: &u64, expected_queue_type: &QueueType) -> Result<()> {
33 if *queue_type != (*expected_queue_type) as u64 {
34 err!(AccountCompressionErrorCode::InvalidQueueType)
35 } else {
36 Ok(())
37 }
38}
39impl QueueMetadata {
40 pub fn init(
41 &mut self,
42 access_metadata: AccessMetadata,
43 rollover_metadata: RolloverMetadata,
44 associated_merkle_tree: Pubkey,
45 queue_type: QueueType,
46 ) {
47 self.access_metadata = access_metadata;
48 self.rollover_metadata = rollover_metadata;
49 self.associated_merkle_tree = associated_merkle_tree;
50 self.queue_type = queue_type as u64;
51 }
52
53 pub fn rollover(
54 &mut self,
55 old_associated_merkle_tree: Pubkey,
56 next_queue: Pubkey,
57 ) -> Result<()> {
58 if self.associated_merkle_tree != old_associated_merkle_tree {
59 return err!(AccountCompressionErrorCode::MerkleTreeAndQueueNotAssociated);
60 }
61
62 self.rollover_metadata.rollover()?;
63 self.next_queue = next_queue;
64
65 Ok(())
66 }
67}
68
69#[account(zero_copy)]
70#[derive(AnchorDeserialize, Debug, PartialEq)]
71#[aligned_sized(anchor)]
72pub struct QueueAccount {
73 pub metadata: QueueMetadata,
74}
75
76impl QueueAccount {
77 pub fn init(
78 &mut self,
79 access_metadata: AccessMetadata,
80 rollover_meta_data: RolloverMetadata,
81 associated_merkle_tree: Pubkey,
82 queue_type: QueueType,
83 ) {
84 self.metadata.init(
85 access_metadata,
86 rollover_meta_data,
87 associated_merkle_tree,
88 queue_type,
89 )
90 }
91}
92
93impl GroupAccess for QueueAccount {
94 fn get_owner(&self) -> &Pubkey {
95 &self.metadata.access_metadata.owner
96 }
97
98 fn get_program_owner(&self) -> &Pubkey {
99 &self.metadata.access_metadata.program_owner
100 }
101}
102
103impl<'info> GroupAccounts<'info> for InsertIntoQueues<'info> {
104 fn get_authority(&self) -> &Signer<'info> {
105 &self.authority
106 }
107 fn get_registered_program_pda(&self) -> &Option<Account<'info, RegisteredProgram>> {
108 &self.registered_program_pda
109 }
110}
111
112impl QueueAccount {
113 pub fn size(capacity: usize) -> Result<usize> {
114 Ok(8 + mem::size_of::<Self>() + HashSet::size_in_account(capacity))
115 }
116}
117
118pub unsafe fn queue_from_bytes_copy(data: &mut [u8]) -> Result<HashSet> {
125 let data = &mut data[8 + mem::size_of::<QueueAccount>()..];
126 let queue = HashSet::from_bytes_copy(data).map_err(ProgramError::from)?;
127 Ok(queue)
128}
129
130pub unsafe fn queue_from_bytes_zero_copy_mut(data: &mut [u8]) -> Result<HashSetZeroCopy> {
137 let data = &mut data[8 + mem::size_of::<QueueAccount>()..];
138 let queue = HashSetZeroCopy::from_bytes_zero_copy_mut(data).map_err(ProgramError::from)?;
139 Ok(queue)
140}
141pub unsafe fn queue_from_bytes_zero_copy_init(
148 data: &mut [u8],
149 capacity: usize,
150 sequence_threshold: usize,
151) -> Result<HashSetZeroCopy> {
152 let data = &mut data[8 + mem::size_of::<QueueAccount>()..];
153 let queue = HashSetZeroCopy::from_bytes_zero_copy_init(data, capacity, sequence_threshold)
154 .map_err(ProgramError::from)?;
155 Ok(queue)
156}