light_compressed_account/instruction_data/
traits.rs

1use core::fmt::Debug;
2
3#[cfg(all(feature = "std", feature = "anchor"))]
4use anchor_lang::AnchorSerialize;
5#[allow(unused_imports)]
6#[cfg(not(all(feature = "std", feature = "anchor")))]
7use borsh::BorshSerialize as AnchorSerialize;
8use light_program_profiler::profile;
9use tinyvec::ArrayVec;
10use zerocopy::Ref;
11
12use super::{
13    compressed_proof::CompressedProof,
14    cpi_context::CompressedCpiContext,
15    zero_copy::{ZPackedMerkleContext, ZPackedReadOnlyAddress, ZPackedReadOnlyCompressedAccount},
16};
17use crate::{compressed_account::CompressedAccountData, pubkey::Pubkey, CompressedAccountError};
18
19pub trait InstructionDiscriminator {
20    fn discriminator(&self) -> &'static [u8];
21}
22
23pub trait LightInstructionData: InstructionDiscriminator + AnchorSerialize {
24    #[cfg(feature = "alloc")]
25    #[profile]
26    fn data(&self) -> Result<crate::Vec<u8>, CompressedAccountError> {
27        let inputs = AnchorSerialize::try_to_vec(self)
28            .map_err(|_| CompressedAccountError::InvalidArgument)?;
29        let mut data = crate::Vec::with_capacity(8 + inputs.len());
30        data.extend_from_slice(self.discriminator());
31        data.extend_from_slice(inputs.as_slice());
32        Ok(data)
33    }
34
35    #[profile]
36    fn data_array<const N: usize>(&self) -> Result<ArrayVec<[u8; N]>, CompressedAccountError> {
37        let mut data = ArrayVec::new();
38        // Add discriminator
39        data.extend_from_slice(self.discriminator());
40        self.serialize(&mut data.as_mut_slice())
41            .map_err(|_e| CompressedAccountError::InputTooLarge(data.len().saturating_sub(N)))?;
42
43        Ok(data)
44    }
45}
46
47pub trait InstructionData<'a> {
48    fn owner(&self) -> Pubkey;
49    fn new_addresses(&self) -> &[impl NewAddress<'a>];
50    fn input_accounts(&self) -> &[impl InputAccount<'a>];
51    fn output_accounts(&self) -> &[impl OutputAccount<'a>];
52    fn read_only_accounts(&self) -> Option<&[ZPackedReadOnlyCompressedAccount]>;
53    fn read_only_addresses(&self) -> Option<&[ZPackedReadOnlyAddress]>;
54    fn is_compress(&self) -> bool;
55    fn compress_or_decompress_lamports(&self) -> Option<u64>;
56    fn proof(&self) -> Option<Ref<&'a [u8], CompressedProof>>;
57    fn cpi_context(&self) -> Option<CompressedCpiContext>;
58    fn bump(&self) -> Option<u8>;
59    fn account_option_config(&self) -> Result<AccountOptions, CompressedAccountError>;
60    fn with_transaction_hash(&self) -> bool;
61}
62
63pub trait NewAddress<'a>
64where
65    Self: Debug,
66{
67    fn seed(&self) -> [u8; 32];
68    fn address_queue_index(&self) -> u8;
69    fn address_merkle_tree_account_index(&self) -> u8;
70    fn address_merkle_tree_root_index(&self) -> u16;
71    fn assigned_compressed_account_index(&self) -> Option<usize>;
72    fn owner(&self) -> Option<&[u8; 32]> {
73        None
74    }
75}
76
77pub trait InputAccount<'a>
78where
79    Self: Debug,
80{
81    fn owner(&self) -> &crate::pubkey::Pubkey;
82    fn lamports(&self) -> u64;
83    fn address(&self) -> Option<[u8; 32]>;
84    fn merkle_context(&self) -> ZPackedMerkleContext;
85    fn has_data(&self) -> bool;
86    fn data(&self) -> Option<CompressedAccountData>;
87    fn skip(&self) -> bool;
88    fn hash_with_hashed_values(
89        &self,
90        owner_hashed: &[u8; 32],
91        merkle_tree_hashed: &[u8; 32],
92        leaf_index: &u32,
93        is_batched: bool,
94    ) -> Result<[u8; 32], CompressedAccountError>;
95
96    fn root_index(&self) -> u16;
97}
98
99pub trait OutputAccount<'a>
100where
101    Self: Debug,
102{
103    fn lamports(&self) -> u64;
104    fn address(&self) -> Option<[u8; 32]>;
105    fn has_data(&self) -> bool;
106    fn skip(&self) -> bool;
107    fn data(&self) -> Option<CompressedAccountData>;
108    fn owner(&self) -> Pubkey;
109    fn merkle_tree_index(&self) -> u8;
110    fn hash_with_hashed_values(
111        &self,
112        owner_hashed: &[u8; 32],
113        merkle_tree_hashed: &[u8; 32],
114        leaf_index: &u32,
115        is_batched: bool,
116    ) -> Result<[u8; 32], CompressedAccountError>;
117}
118
119#[derive(Debug, Clone, Copy, PartialEq, Eq)]
120pub struct AccountOptions {
121    pub sol_pool_pda: bool,
122    pub decompression_recipient: bool,
123    pub cpi_context_account: bool,
124    pub write_to_cpi_context: bool,
125}