light_program_test/program_test/
test_rpc.rs1use async_trait::async_trait;
2use light_client::rpc::{LightClient, Rpc, RpcError};
3use solana_account::Account;
4use solana_sdk::{clock::Slot, pubkey::Pubkey};
5#[cfg(feature = "devenv")]
6use {
7 borsh::BorshDeserialize,
8 light_client::fee::{assert_transaction_params, TransactionParams},
9 light_compressible::rent::SLOTS_PER_EPOCH,
10 light_event::event::{BatchPublicTransactionEvent, PublicTransactionEvent},
11 solana_sdk::{
12 clock::Clock,
13 instruction::Instruction,
14 signature::{Keypair, Signature},
15 },
16 std::{fmt::Debug, marker::Send},
17};
18
19#[cfg(feature = "devenv")]
20use crate::compressible::CompressibleAccountStore;
21use crate::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 #[cfg(feature = "devenv")]
110 async fn warp_slot_forward(&mut self, slot: Slot) -> Result<(), RpcError>;
111
112 #[cfg(feature = "devenv")]
115 async fn warp_epoch_forward(&mut self, epochs: u64) -> Result<(), RpcError> {
116 let slots_to_warp = epochs * SLOTS_PER_EPOCH;
117 self.warp_slot_forward(slots_to_warp).await
118 }
119}
120
121#[async_trait]
123impl TestRpc for LightClient {
124 fn set_account(&mut self, _address: Pubkey, _account: Account) {
125 unimplemented!()
126 }
127
128 fn warp_to_slot(&mut self, _slot: Slot) -> Result<(), RpcError> {
129 unimplemented!()
130 }
131
132 #[cfg(feature = "devenv")]
133 async fn warp_slot_forward(&mut self, _slot: Slot) -> Result<(), RpcError> {
134 unimplemented!()
135 }
136}
137
138#[async_trait]
139impl TestRpc for LightProgramTest {
140 fn set_account(&mut self, address: Pubkey, account: Account) {
141 self.context
142 .set_account(address, account)
143 .expect("Setting account failed.");
144 }
145
146 fn warp_to_slot(&mut self, slot: Slot) -> Result<(), RpcError> {
147 self.context.warp_to_slot(slot);
148 Ok(())
149 }
150
151 #[cfg(feature = "devenv")]
154 async fn warp_slot_forward(&mut self, slot: Slot) -> Result<(), RpcError> {
155 let mut current_slot = self.context.get_sysvar::<Clock>().slot;
156 current_slot += slot;
157 self.context.warp_to_slot(current_slot);
158 let mut store = CompressibleAccountStore::new();
159 crate::compressible::claim_and_compress(self, &mut store).await?;
160 Ok(())
161 }
162}