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    #[inline(never)]
27    fn data(&self) -> Result<crate::Vec<u8>, CompressedAccountError> {
28        let inputs = AnchorSerialize::try_to_vec(self)
29            .map_err(|_| CompressedAccountError::InvalidArgument)?;
30        let mut data = crate::Vec::with_capacity(8 + inputs.len());
31        data.extend_from_slice(self.discriminator());
32
33        data.extend_from_slice(inputs.as_slice());
34        Ok(data)
35    }
36
37    #[profile]
38    fn data_array<const N: usize>(&self) -> Result<ArrayVec<[u8; N]>, CompressedAccountError> {
39        let mut data = ArrayVec::new();
40        // Add discriminator
41        data.extend_from_slice(self.discriminator());
42        self.serialize(&mut data.as_mut_slice())
43            .map_err(|_e| CompressedAccountError::InputTooLarge(data.len().saturating_sub(N)))?;
44
45        Ok(data)
46    }
47}
48
49pub trait InstructionData<'a> {
50    fn owner(&self) -> Pubkey;
51    fn new_addresses(&self) -> &[impl NewAddress<'a>];
52    fn input_accounts(&self) -> &[impl InputAccount<'a>];
53    fn output_accounts(&self) -> &[impl OutputAccount<'a>];
54    fn read_only_accounts(&self) -> Option<&[ZPackedReadOnlyCompressedAccount]>;
55    fn read_only_addresses(&self) -> Option<&[ZPackedReadOnlyAddress]>;
56    fn is_compress(&self) -> bool;
57    fn compress_or_decompress_lamports(&self) -> Option<u64>;
58    fn proof(&self) -> Option<Ref<&'a [u8], CompressedProof>>;
59    fn cpi_context(&self) -> Option<CompressedCpiContext>;
60    fn bump(&self) -> Option<u8>;
61    fn account_option_config(&self) -> Result<AccountOptions, CompressedAccountError>;
62    fn with_transaction_hash(&self) -> bool;
63}
64
65pub trait NewAddress<'a>
66where
67    Self: Debug,
68{
69    fn seed(&self) -> [u8; 32];
70    fn address_queue_index(&self) -> u8;
71    fn address_merkle_tree_account_index(&self) -> u8;
72    fn address_merkle_tree_root_index(&self) -> u16;
73    fn assigned_compressed_account_index(&self) -> Option<usize>;
74    fn owner(&self) -> Option<&[u8; 32]> {
75        None
76    }
77}
78
79pub trait InputAccount<'a>
80where
81    Self: Debug,
82{
83    fn owner(&self) -> &crate::pubkey::Pubkey;
84    fn lamports(&self) -> u64;
85    fn address(&self) -> Option<[u8; 32]>;
86    fn merkle_context(&self) -> ZPackedMerkleContext;
87    fn has_data(&self) -> bool;
88    fn data(&self) -> Option<CompressedAccountData>;
89    fn skip(&self) -> bool;
90    fn hash_with_hashed_values(
91        &self,
92        owner_hashed: &[u8; 32],
93        merkle_tree_hashed: &[u8; 32],
94        leaf_index: &u32,
95        is_batched: bool,
96    ) -> Result<[u8; 32], CompressedAccountError>;
97
98    fn root_index(&self) -> u16;
99}
100
101pub trait OutputAccount<'a>
102where
103    Self: Debug,
104{
105    fn lamports(&self) -> u64;
106    fn address(&self) -> Option<[u8; 32]>;
107    fn has_data(&self) -> bool;
108    fn skip(&self) -> bool;
109    fn data(&self) -> Option<CompressedAccountData>;
110    fn owner(&self) -> Pubkey;
111    fn merkle_tree_index(&self) -> u8;
112    fn hash_with_hashed_values(
113        &self,
114        owner_hashed: &[u8; 32],
115        merkle_tree_hashed: &[u8; 32],
116        leaf_index: &u32,
117        is_batched: bool,
118    ) -> Result<[u8; 32], CompressedAccountError>;
119}
120
121#[derive(Debug, Clone, Copy, PartialEq, Eq)]
122pub struct AccountOptions {
123    pub sol_pool_pda: bool,
124    pub decompression_recipient: bool,
125    pub cpi_context_account: bool,
126    pub write_to_cpi_context: bool,
127}