light_compressed_account/instruction_data/
traits.rs1use 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 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}