Skip to content

Commit b0b9528

Browse files
committed
batch compress test works
1 parent a737111 commit b0b9528

File tree

15 files changed

+657
-527
lines changed

15 files changed

+657
-527
lines changed

program-tests/sdk-token-test/src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ declare_id!("5p1t1GAaKtK1FKCh5Hd2Gu8JCu3eREhJm4Q2qYfTEPYK");
2020
#[program]
2121
pub mod sdk_token_test {
2222

23+
use light_compressed_token_sdk::account_infos::BatchCompressAccountInfos;
24+
2325
use super::*;
2426

2527
pub fn compress_tokens<'info>(
@@ -145,12 +147,10 @@ pub mod sdk_token_test {
145147
pub fn batch_compress_tokens<'info>(
146148
ctx: Context<'_, '_, '_, 'info, Generic<'info>>,
147149
recipients: Vec<Recipient>,
148-
_output_tree_index: u8,
149-
_mint: Pubkey,
150150
token_pool_index: u8,
151151
token_pool_bump: u8,
152152
) -> Result<()> {
153-
let light_cpi_accounts = TransferAccountInfos::new_compress(
153+
let light_cpi_accounts = BatchCompressAccountInfos::new(
154154
ctx.accounts.signer.as_ref(),
155155
ctx.accounts.signer.as_ref(),
156156
ctx.remaining_accounts,
@@ -174,8 +174,8 @@ pub mod sdk_token_test {
174174
authority: *ctx.accounts.signer.key,
175175
token_pool_pda: *light_cpi_accounts.token_pool_pda().unwrap().key,
176176
sender_token_account: *light_cpi_accounts.sender_token_account().unwrap().key,
177-
token_program: *light_cpi_accounts.spl_token_program().unwrap().key,
178-
merkle_tree: *light_cpi_accounts.tree_accounts().unwrap()[0].key,
177+
token_program: *light_cpi_accounts.token_program().unwrap().key,
178+
merkle_tree: *light_cpi_accounts.merkle_tree().unwrap().key,
179179
recipients: sdk_recipients,
180180
lamports: None,
181181
token_pool_index,

program-tests/sdk-token-test/tests/test.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use light_compressed_token_sdk::{
1111
get_transfer_instruction_account_metas, TokenAccountsMetaConfig,
1212
},
1313
},
14-
token_pool::get_token_pool_pda,
14+
token_pool::{find_token_pool_pda_with_index, get_token_pool_pda},
1515
TokenAccountMeta, SPL_TOKEN_PROGRAM_ID,
1616
};
1717
use light_program_test::{Indexer, LightProgramTest, ProgramTestConfig, Rpc};
@@ -580,38 +580,32 @@ async fn batch_compress_spl_tokens(
580580
token_account: Pubkey,
581581
) -> Result<Signature, RpcError> {
582582
let mut remaining_accounts = PackedAccounts::default();
583-
let token_pool_pda = get_token_pool_pda(&mint);
583+
remaining_accounts.add_pre_accounts_signer_mut(payer.pubkey());
584+
let token_pool_index = 0;
585+
let (token_pool_pda, token_pool_bump) = find_token_pool_pda_with_index(&mint, token_pool_index);
584586
println!("token_pool_pda {:?}", token_pool_pda);
585587
// Use batch compress account metas
586588
let config = BatchCompressMetaConfig::new_client(
587589
token_pool_pda,
588590
token_account,
589591
SPL_TOKEN_PROGRAM_ID.into(),
590-
rpc.get_random_state_tree_info().unwrap().tree,
592+
rpc.get_random_state_tree_info().unwrap().queue,
591593
false, // with_lamports
592594
);
593-
594-
remaining_accounts.add_pre_accounts_signer_mut(payer.pubkey());
595595
let metas = get_batch_compress_instruction_account_metas(config);
596+
println!("metas {:?}", metas);
596597
remaining_accounts.add_pre_accounts_metas(metas.as_slice());
597598

598-
let output_tree_index = rpc
599-
.get_random_state_tree_info()
600-
.unwrap()
601-
.pack_output_tree_index(&mut remaining_accounts)
602-
.unwrap();
603-
604-
let (remaining_accounts, _, _) = remaining_accounts.to_account_metas();
599+
let (accounts, _, _) = remaining_accounts.to_account_metas();
600+
println!("accounts {:?}", accounts);
605601

606602
let instruction = Instruction {
607603
program_id: sdk_token_test::ID,
608-
accounts: [remaining_accounts].concat(),
604+
accounts,
609605
data: sdk_token_test::instruction::BatchCompressTokens {
610606
recipients,
611-
_output_tree_index: output_tree_index,
612-
_mint: mint,
613-
token_pool_index: 0, // Default pool index
614-
token_pool_bump: 255, // Default bump
607+
token_pool_index,
608+
token_pool_bump,
615609
}
616610
.data(),
617611
};

sdk-libs/compressed-token-sdk/src/instructions/batch_compress/account_metas.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ pub fn get_batch_compress_instruction_account_metas(
7878
// Base accounts: cpi_authority_pda + token_pool_pda + token_program + light_system_program +
7979
// registered_program_pda + noop_program + account_compression_authority +
8080
// account_compression_program + merkle_tree +
81-
// self_program + system_program
82-
let base_capacity = 10;
81+
// self_program + system_program + sender_token_account
82+
let base_capacity = 11;
8383

8484
// Direct invoke accounts: fee_payer + authority + mint_placeholder + sol_pool_pda_or_placeholder
8585
let fee_payer_capacity = if config.fee_payer.is_some() { 4 } else { 0 };
@@ -113,7 +113,8 @@ pub fn get_batch_compress_instruction_account_metas(
113113
false,
114114
));
115115
}
116-
116+
println!("config {:?}", config);
117+
println!("default_pubkeys {:?}", default_pubkeys);
117118
// token_pool_pda (mut)
118119
metas.push(AccountMeta::new(config.token_pool_pda, false));
119120

@@ -175,5 +176,8 @@ pub fn get_batch_compress_instruction_account_metas(
175176
));
176177
}
177178

179+
// sender_token_account (mut) - last account
180+
metas.push(AccountMeta::new(config.sender_token_account, false));
181+
178182
metas
179183
}

sdk-libs/compressed-token-sdk/src/instructions/batch_compress/instruction.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::{AnchorDeserialize, AnchorSerialize};
2+
use light_compressed_token_types::BATCH_COMPRESS;
23
use solana_instruction::Instruction;
34
use solana_pubkey::Pubkey;
45

@@ -49,10 +50,18 @@ pub fn create_batch_compress_instruction(inputs: BatchCompressInputs) -> Result<
4950
};
5051

5152
// Serialize instruction data
52-
let serialized_data = instruction_data
53+
let data_vec = instruction_data
5354
.try_to_vec()
5455
.map_err(|_| TokenSdkError::SerializationError)?;
55-
56+
let mut data = Vec::with_capacity(data_vec.len() + 8 + 4);
57+
data.extend_from_slice(BATCH_COMPRESS.as_slice());
58+
data.extend_from_slice(
59+
u32::try_from(data_vec.len())
60+
.unwrap()
61+
.to_le_bytes()
62+
.as_slice(),
63+
);
64+
data.extend(&data_vec);
5665
// Create account meta config for batch_compress (uses MintToInstruction accounts)
5766
let meta_config = BatchCompressMetaConfig {
5867
fee_payer: Some(inputs.fee_payer),
@@ -70,6 +79,6 @@ pub fn create_batch_compress_instruction(inputs: BatchCompressInputs) -> Result<
7079
Ok(Instruction {
7180
program_id: Pubkey::new_from_array(light_compressed_token_types::PROGRAM_ID),
7281
accounts: account_metas,
73-
data: serialized_data,
82+
data,
7483
})
7584
}
Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
use light_compressed_token_types::account_infos::{
2-
TransferAccountInfos as TransferAccountInfosTypes, TransferAccountInfosIndex,
3-
};
1+
use light_compressed_token_types::account_infos::TransferAccountInfos as TransferAccountInfosTypes;
42
use solana_account_info::AccountInfo;
53

64
pub mod account_metas;
75
pub mod instruction;
86

9-
pub type TransferAccountInfos<'a, 'b> =
10-
TransferAccountInfosTypes<'a, AccountInfo<'b>, TransferAccountInfosIndex>;
7+
pub type TransferAccountInfos<'a, 'b> = TransferAccountInfosTypes<'a, AccountInfo<'b>>;
Lines changed: 152 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
use crate::account_infos::generic_struct::AccountInfoIndexGetter;
1+
use light_account_checks::AccountInfoTrait;
2+
3+
use crate::{
4+
account_infos::MintToAccountInfosConfig,
5+
error::{LightTokenSdkTypeError, Result},
6+
};
27

38
#[repr(usize)]
49
pub enum BatchCompressAccountInfosIndex {
5-
FeePayer,
6-
Authority,
10+
// FeePayer,
11+
// Authority,
712
CpiAuthorityPda,
8-
Mint,
913
TokenPoolPda,
1014
TokenProgram,
1115
LightSystemProgram,
@@ -16,59 +20,173 @@ pub enum BatchCompressAccountInfosIndex {
1620
MerkleTree,
1721
SelfProgram,
1822
SystemProgram,
23+
SolPoolPda,
24+
SenderTokenAccount,
25+
}
26+
27+
pub struct BatchCompressAccountInfos<'a, T: AccountInfoTrait + Clone> {
28+
fee_payer: &'a T,
29+
authority: &'a T,
30+
accounts: &'a [T],
31+
config: MintToAccountInfosConfig,
1932
}
2033

21-
impl AccountInfoIndexGetter for BatchCompressAccountInfosIndex {
22-
const SYSTEM_ACCOUNTS_LEN: usize = 14;
23-
24-
fn cpi_authority_index() -> usize {
25-
BatchCompressAccountInfosIndex::CpiAuthorityPda as usize
34+
impl<'a, T: AccountInfoTrait + Clone> BatchCompressAccountInfos<'a, T> {
35+
pub fn new(fee_payer: &'a T, authority: &'a T, accounts: &'a [T]) -> Self {
36+
Self {
37+
fee_payer,
38+
authority,
39+
accounts,
40+
config: MintToAccountInfosConfig::new_batch_compress(),
41+
}
2642
}
2743

28-
fn light_system_program_index() -> usize {
29-
BatchCompressAccountInfosIndex::LightSystemProgram as usize
44+
pub fn new_with_config(
45+
fee_payer: &'a T,
46+
authority: &'a T,
47+
accounts: &'a [T],
48+
config: MintToAccountInfosConfig,
49+
) -> Self {
50+
Self {
51+
fee_payer,
52+
authority,
53+
accounts,
54+
config,
55+
}
3056
}
3157

32-
fn registered_program_pda_index() -> usize {
33-
BatchCompressAccountInfosIndex::RegisteredProgramPda as usize
58+
pub fn fee_payer(&self) -> &'a T {
59+
self.fee_payer
3460
}
3561

36-
fn noop_program_index() -> usize {
37-
BatchCompressAccountInfosIndex::NoopProgram as usize
62+
pub fn authority(&self) -> &'a T {
63+
self.authority
3864
}
3965

40-
fn account_compression_authority_index() -> usize {
41-
BatchCompressAccountInfosIndex::AccountCompressionAuthority as usize
66+
pub fn cpi_authority_pda(&self) -> Result<&'a T> {
67+
let index = BatchCompressAccountInfosIndex::CpiAuthorityPda as usize;
68+
self.accounts
69+
.get(index)
70+
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
4271
}
4372

44-
fn account_compression_program_index() -> usize {
45-
BatchCompressAccountInfosIndex::AccountCompressionProgram as usize
73+
pub fn token_pool_pda(&self) -> Result<&'a T> {
74+
let index = BatchCompressAccountInfosIndex::TokenPoolPda as usize;
75+
self.accounts
76+
.get(index)
77+
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
4678
}
4779

48-
fn ctoken_program_index() -> usize {
49-
BatchCompressAccountInfosIndex::SelfProgram as usize
80+
pub fn token_program(&self) -> Result<&'a T> {
81+
let index = BatchCompressAccountInfosIndex::TokenProgram as usize;
82+
self.accounts
83+
.get(index)
84+
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
5085
}
5186

52-
fn token_pool_pda_index() -> usize {
53-
BatchCompressAccountInfosIndex::TokenPoolPda as usize
87+
pub fn light_system_program(&self) -> Result<&'a T> {
88+
let index = BatchCompressAccountInfosIndex::LightSystemProgram as usize;
89+
self.accounts
90+
.get(index)
91+
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
5492
}
5593

56-
fn decompression_recipient_index() -> usize {
57-
// BatchCompress doesn't use decompression recipient
58-
0
94+
pub fn registered_program_pda(&self) -> Result<&'a T> {
95+
let index = BatchCompressAccountInfosIndex::RegisteredProgramPda as usize;
96+
self.accounts
97+
.get(index)
98+
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
5999
}
60100

61-
fn spl_token_program_index() -> usize {
62-
BatchCompressAccountInfosIndex::TokenProgram as usize
101+
pub fn noop_program(&self) -> Result<&'a T> {
102+
let index = BatchCompressAccountInfosIndex::NoopProgram as usize;
103+
self.accounts
104+
.get(index)
105+
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
63106
}
64107

65-
fn system_program_index() -> usize {
66-
BatchCompressAccountInfosIndex::SystemProgram as usize
108+
pub fn account_compression_authority(&self) -> Result<&'a T> {
109+
let index = BatchCompressAccountInfosIndex::AccountCompressionAuthority as usize;
110+
self.accounts
111+
.get(index)
112+
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
67113
}
68114

69-
fn cpi_context_index() -> usize {
70-
// BatchCompress doesn't use cpi context
71-
0
115+
pub fn account_compression_program(&self) -> Result<&'a T> {
116+
let index = BatchCompressAccountInfosIndex::AccountCompressionProgram as usize;
117+
self.accounts
118+
.get(index)
119+
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
120+
}
121+
122+
pub fn merkle_tree(&self) -> Result<&'a T> {
123+
let index = BatchCompressAccountInfosIndex::MerkleTree as usize;
124+
self.accounts
125+
.get(index)
126+
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
127+
}
128+
129+
pub fn self_program(&self) -> Result<&'a T> {
130+
let index = BatchCompressAccountInfosIndex::SelfProgram as usize;
131+
self.accounts
132+
.get(index)
133+
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
134+
}
135+
136+
pub fn system_program(&self) -> Result<&'a T> {
137+
let index = BatchCompressAccountInfosIndex::SystemProgram as usize;
138+
self.accounts
139+
.get(index)
140+
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
141+
}
142+
143+
pub fn sol_pool_pda(&self) -> Result<&'a T> {
144+
if !self.config.has_sol_pool_pda {
145+
return Err(LightTokenSdkTypeError::SolPoolPdaUndefined);
146+
}
147+
let index = BatchCompressAccountInfosIndex::SolPoolPda as usize;
148+
self.accounts
149+
.get(index)
150+
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
72151
}
73-
}
74152

153+
pub fn sender_token_account(&self) -> Result<&'a T> {
154+
let mut index = BatchCompressAccountInfosIndex::SenderTokenAccount as usize;
155+
if !self.config.has_sol_pool_pda {
156+
index -= 1;
157+
}
158+
self.accounts
159+
.get(index)
160+
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
161+
}
162+
163+
pub fn get_account_info(&self, index: usize) -> Result<&'a T> {
164+
self.accounts
165+
.get(index)
166+
.ok_or(LightTokenSdkTypeError::CpiAccountsIndexOutOfBounds(index))
167+
}
168+
pub fn to_account_infos(&self) -> Vec<T> {
169+
[
170+
vec![self.fee_payer.clone()],
171+
vec![self.authority.clone()],
172+
self.accounts.to_vec(),
173+
]
174+
.concat()
175+
}
176+
177+
pub fn account_infos(&self) -> &'a [T] {
178+
self.accounts
179+
}
180+
181+
pub fn config(&self) -> &MintToAccountInfosConfig {
182+
&self.config
183+
}
184+
185+
pub fn system_accounts_len(&self) -> usize {
186+
let mut len = 13; // Base accounts from the enum (including sender_token_account)
187+
if !self.config.has_sol_pool_pda {
188+
len -= 1; // Remove sol_pool_pda if it's None
189+
}
190+
len
191+
}
192+
}

0 commit comments

Comments
 (0)