light_program_test/program_test/
test_rpc.rs

1use 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_compressed_account::indexer_event::event::{
10        BatchPublicTransactionEvent, PublicTransactionEvent,
11    },
12    solana_sdk::{
13        instruction::Instruction,
14        signature::{Keypair, Signature},
15    },
16    std::{fmt::Debug, marker::Send},
17};
18
19use crate::program_test::LightProgramTest;
20
21#[async_trait]
22pub trait TestRpc: Rpc + Sized {
23    #[cfg(feature = "devenv")]
24    async fn create_and_send_transaction_with_batched_event(
25        &mut self,
26        instructions: &[Instruction],
27        payer: &Pubkey,
28        signers: &[&Keypair],
29        transaction_params: Option<light_client::fee::TransactionParams>,
30    ) -> Result<Option<(Vec<BatchPublicTransactionEvent>, Signature, Slot)>, RpcError> {
31        let pre_balance = self.get_balance(payer).await?;
32
33        let event = <Self as Rpc>::create_and_send_transaction_with_batched_event(
34            self,
35            instructions,
36            payer,
37            signers,
38        )
39        .await?;
40
41        light_client::fee::assert_transaction_params(
42            self,
43            payer,
44            signers,
45            pre_balance,
46            transaction_params,
47        )
48        .await?;
49
50        Ok(event)
51    }
52
53    #[cfg(feature = "devenv")]
54    async fn create_and_send_transaction_with_event<T>(
55        &mut self,
56        instructions: &[Instruction],
57        payer: &Pubkey,
58        signers: &[&Keypair],
59        transaction_params: Option<TransactionParams>,
60    ) -> Result<Option<(T, Signature, Slot)>, RpcError>
61    where
62        T: BorshDeserialize + Send + Debug,
63    {
64        let pre_balance = self.get_balance(payer).await?;
65
66        let result = <Self as Rpc>::create_and_send_transaction_with_event::<T>(
67            self,
68            instructions,
69            payer,
70            signers,
71        )
72        .await?;
73        assert_transaction_params(self, payer, signers, pre_balance, transaction_params).await?;
74
75        Ok(result)
76    }
77
78    #[cfg(feature = "devenv")]
79    async fn create_and_send_transaction_with_public_event(
80        &mut self,
81        instructions: &[Instruction],
82        payer: &Pubkey,
83        signers: &[&Keypair],
84        transaction_params: Option<TransactionParams>,
85    ) -> Result<Option<(PublicTransactionEvent, Signature, Slot)>, RpcError> {
86        let pre_balance = self.get_balance(payer).await?;
87
88        let res = <Self as Rpc>::create_and_send_transaction_with_batched_event(
89            self,
90            instructions,
91            payer,
92            signers,
93        )
94        .await?;
95        assert_transaction_params(self, payer, signers, pre_balance, transaction_params).await?;
96
97        let event = res.map(|e| (e.0[0].event.clone(), e.1, e.2));
98
99        Ok(event)
100    }
101
102    fn set_account(&mut self, address: Pubkey, account: Account);
103    fn warp_to_slot(&mut self, slot: Slot) -> Result<(), RpcError>;
104}
105
106// Implementation required for E2ETestEnv.
107#[async_trait]
108impl TestRpc for LightClient {
109    fn set_account(&mut self, _address: Pubkey, _account: Account) {
110        unimplemented!()
111    }
112
113    fn warp_to_slot(&mut self, _slot: Slot) -> Result<(), RpcError> {
114        unimplemented!()
115    }
116}
117
118#[async_trait]
119impl TestRpc for LightProgramTest {
120    fn set_account(&mut self, address: Pubkey, account: Account) {
121        self.context
122            .set_account(address, account)
123            .expect("Setting account failed.");
124    }
125
126    fn warp_to_slot(&mut self, slot: Slot) -> Result<(), RpcError> {
127        self.context.warp_to_slot(slot);
128        Ok(())
129    }
130}