light_program_test/program_test/
test_rpc.rs1use async_trait::async_trait;
2use light_client::rpc::{LightClient, Rpc, RpcError};
3use light_compressible::rent::SLOTS_PER_EPOCH;
4use solana_account::Account;
5use solana_sdk::{
6 clock::{Clock, Slot},
7 pubkey::Pubkey,
8};
9#[cfg(feature = "devenv")]
10use {
11 borsh::BorshDeserialize,
12 light_client::fee::{assert_transaction_params, TransactionParams},
13 light_event::event::{BatchPublicTransactionEvent, PublicTransactionEvent},
14 solana_sdk::{
15 instruction::Instruction,
16 signature::{Keypair, Signature},
17 },
18 std::{fmt::Debug, marker::Send},
19};
20
21use crate::{compressible::CompressibleAccountStore, program_test::LightProgramTest};
22
23#[async_trait]
24pub trait TestRpc: Rpc + Sized {
25 #[cfg(feature = "devenv")]
26 async fn create_and_send_transaction_with_batched_event(
27 &mut self,
28 instructions: &[Instruction],
29 payer: &Pubkey,
30 signers: &[&Keypair],
31 transaction_params: Option<light_client::fee::TransactionParams>,
32 ) -> Result<Option<(Vec<BatchPublicTransactionEvent>, Signature, Slot)>, RpcError> {
33 let pre_balance = self.get_balance(payer).await?;
34
35 let event = <Self as Rpc>::create_and_send_transaction_with_batched_event(
36 self,
37 instructions,
38 payer,
39 signers,
40 )
41 .await?;
42
43 light_client::fee::assert_transaction_params(
44 self,
45 payer,
46 signers,
47 pre_balance,
48 transaction_params,
49 )
50 .await?;
51
52 Ok(event)
53 }
54
55 #[cfg(feature = "devenv")]
56 async fn create_and_send_transaction_with_event<T>(
57 &mut self,
58 instructions: &[Instruction],
59 payer: &Pubkey,
60 signers: &[&Keypair],
61 transaction_params: Option<TransactionParams>,
62 ) -> Result<Option<(T, Signature, Slot)>, RpcError>
63 where
64 T: BorshDeserialize + Send + Debug,
65 {
66 let pre_balance = self.get_balance(payer).await?;
67
68 let result = <Self as Rpc>::create_and_send_transaction_with_event::<T>(
69 self,
70 instructions,
71 payer,
72 signers,
73 )
74 .await?;
75 assert_transaction_params(self, payer, signers, pre_balance, transaction_params).await?;
76
77 Ok(result)
78 }
79
80 #[cfg(feature = "devenv")]
81 async fn create_and_send_transaction_with_public_event(
82 &mut self,
83 instructions: &[Instruction],
84 payer: &Pubkey,
85 signers: &[&Keypair],
86 transaction_params: Option<TransactionParams>,
87 ) -> Result<Option<(PublicTransactionEvent, Signature, Slot)>, RpcError> {
88 let pre_balance = self.get_balance(payer).await?;
89
90 let res = <Self as Rpc>::create_and_send_transaction_with_batched_event(
91 self,
92 instructions,
93 payer,
94 signers,
95 )
96 .await?;
97 assert_transaction_params(self, payer, signers, pre_balance, transaction_params).await?;
98
99 let event = res.map(|e| (e.0[0].event.clone(), e.1, e.2));
100
101 Ok(event)
102 }
103
104 fn set_account(&mut self, address: Pubkey, account: Account);
105 fn warp_to_slot(&mut self, slot: Slot) -> Result<(), RpcError>;
106
107 async fn warp_slot_forward(&mut self, slot: Slot) -> Result<(), RpcError>;
110
111 async fn warp_epoch_forward(&mut self, epochs: u64) -> Result<(), RpcError> {
114 let slots_to_warp = epochs * SLOTS_PER_EPOCH;
115 self.warp_slot_forward(slots_to_warp).await
116 }
117}
118
119#[async_trait]
121impl TestRpc for LightClient {
122 fn set_account(&mut self, _address: Pubkey, _account: Account) {
123 unimplemented!()
124 }
125
126 fn warp_to_slot(&mut self, _slot: Slot) -> Result<(), RpcError> {
127 unimplemented!()
128 }
129
130 async fn warp_slot_forward(&mut self, _slot: Slot) -> Result<(), RpcError> {
131 unimplemented!()
132 }
133}
134
135#[async_trait]
136impl TestRpc for LightProgramTest {
137 fn set_account(&mut self, address: Pubkey, account: Account) {
138 self.context
139 .set_account(address, account)
140 .expect("Setting account failed.");
141 }
142
143 fn warp_to_slot(&mut self, slot: Slot) -> Result<(), RpcError> {
144 self.context.warp_to_slot(slot);
145 Ok(())
146 }
147
148 async fn warp_slot_forward(&mut self, slot: Slot) -> Result<(), RpcError> {
151 let mut current_slot = self.context.get_sysvar::<Clock>().slot;
152 current_slot += slot;
153 self.context.warp_to_slot(current_slot);
154 let mut store = CompressibleAccountStore::new();
155 crate::compressible::claim_and_compress(self, &mut store).await?;
156 for program_id in self.auto_mine_cold_state_programs.clone() {
157 crate::compressible::auto_compress_program_pdas(self, program_id).await?;
158 }
159 Ok(())
160 }
161}