solana_client/
thin_client.rs

1//! The `thin_client` module is a client-side object that interfaces with
2//! a server-side TPU.  Client code should use this object instead of writing
3//! messages to the network directly. The binary encoding of its messages are
4//! unstable and may change in future releases.
5#[allow(deprecated)]
6use {
7    crate::connection_cache::{dispatch, ConnectionCache},
8    solana_account::Account,
9    solana_client_traits::{AsyncClient, Client, SyncClient},
10    solana_commitment_config::CommitmentConfig,
11    solana_epoch_info::EpochInfo,
12    solana_hash::Hash,
13    solana_instruction::Instruction,
14    solana_keypair::Keypair,
15    solana_message::Message,
16    solana_pubkey::Pubkey,
17    solana_quic_client::{QuicConfig, QuicConnectionManager, QuicPool},
18    solana_rpc_client::rpc_client::RpcClient,
19    solana_rpc_client_api::config::RpcProgramAccountsConfig,
20    solana_signature::Signature,
21    solana_signer::signers::Signers,
22    solana_thin_client::thin_client::ThinClient as BackendThinClient,
23    solana_transaction::{versioned::VersionedTransaction, Transaction},
24    solana_transaction_error::{TransactionResult, TransportResult},
25    solana_udp_client::{UdpConfig, UdpConnectionManager, UdpPool},
26    std::{net::SocketAddr, sync::Arc, time::Duration},
27};
28
29/// A thin wrapper over thin-client/ThinClient to ease
30/// construction of the ThinClient for code dealing both with udp and quic.
31/// For the scenario only using udp or quic, use thin-client/ThinClient directly.
32#[allow(deprecated)]
33pub enum ThinClient {
34    Quic(BackendThinClient<QuicPool, QuicConnectionManager, QuicConfig>),
35    Udp(BackendThinClient<UdpPool, UdpConnectionManager, UdpConfig>),
36}
37
38#[allow(deprecated)]
39impl ThinClient {
40    /// Create a new ThinClient that will interface with the Rpc at `rpc_addr` using TCP
41    /// and the Tpu at `tpu_addr` over `transactions_socket` using Quic or UDP
42    /// (currently hardcoded to UDP)
43    pub fn new(
44        rpc_addr: SocketAddr,
45        tpu_addr: SocketAddr,
46        connection_cache: Arc<ConnectionCache>,
47    ) -> Self {
48        match &*connection_cache {
49            ConnectionCache::Quic(connection_cache) => {
50                let thin_client =
51                    BackendThinClient::new(rpc_addr, tpu_addr, connection_cache.clone());
52                ThinClient::Quic(thin_client)
53            }
54            ConnectionCache::Udp(connection_cache) => {
55                let thin_client =
56                    BackendThinClient::new(rpc_addr, tpu_addr, connection_cache.clone());
57                ThinClient::Udp(thin_client)
58            }
59        }
60    }
61
62    pub fn new_socket_with_timeout(
63        rpc_addr: SocketAddr,
64        tpu_addr: SocketAddr,
65        timeout: Duration,
66        connection_cache: Arc<ConnectionCache>,
67    ) -> Self {
68        match &*connection_cache {
69            ConnectionCache::Quic(connection_cache) => {
70                let thin_client = BackendThinClient::new_socket_with_timeout(
71                    rpc_addr,
72                    tpu_addr,
73                    timeout,
74                    connection_cache.clone(),
75                );
76                ThinClient::Quic(thin_client)
77            }
78            ConnectionCache::Udp(connection_cache) => {
79                let thin_client = BackendThinClient::new_socket_with_timeout(
80                    rpc_addr,
81                    tpu_addr,
82                    timeout,
83                    connection_cache.clone(),
84                );
85                ThinClient::Udp(thin_client)
86            }
87        }
88    }
89
90    pub fn new_from_addrs(
91        rpc_addrs: Vec<SocketAddr>,
92        tpu_addrs: Vec<SocketAddr>,
93        connection_cache: Arc<ConnectionCache>,
94    ) -> Self {
95        match &*connection_cache {
96            ConnectionCache::Quic(connection_cache) => {
97                let thin_client = BackendThinClient::new_from_addrs(
98                    rpc_addrs,
99                    tpu_addrs,
100                    connection_cache.clone(),
101                );
102                ThinClient::Quic(thin_client)
103            }
104            ConnectionCache::Udp(connection_cache) => {
105                let thin_client = BackendThinClient::new_from_addrs(
106                    rpc_addrs,
107                    tpu_addrs,
108                    connection_cache.clone(),
109                );
110                ThinClient::Udp(thin_client)
111            }
112        }
113    }
114
115    dispatch!(pub fn rpc_client(&self) -> &RpcClient);
116
117    dispatch!(pub fn retry_transfer_until_confirmed(&self, keypair: &Keypair, transaction: &mut Transaction, tries: usize, min_confirmed_blocks: usize) -> TransportResult<Signature>);
118
119    dispatch!(pub fn retry_transfer(
120        &self,
121        keypair: &Keypair,
122        transaction: &mut Transaction,
123        tries: usize
124    ) -> TransportResult<Signature>);
125
126    dispatch!(pub fn send_and_confirm_transaction<T: Signers + ?Sized>(
127        &self,
128        keypairs: &T,
129        transaction: &mut Transaction,
130        tries: usize,
131        pending_confirmations: usize
132    ) -> TransportResult<Signature>);
133
134    dispatch!(pub fn poll_get_balance(&self, pubkey: &Pubkey) -> TransportResult<u64>);
135
136    dispatch!(pub fn poll_get_balance_with_commitment(
137        &self,
138        pubkey: &Pubkey,
139        commitment_config: CommitmentConfig
140    ) -> TransportResult<u64>);
141
142    dispatch!(pub fn wait_for_balance(&self, pubkey: &Pubkey, expected_balance: Option<u64>) -> Option<u64>);
143
144    dispatch!(pub fn get_program_accounts_with_config(
145        &self,
146        pubkey: &Pubkey,
147        config: RpcProgramAccountsConfig
148    ) -> TransportResult<Vec<(Pubkey, Account)>>);
149
150    dispatch!(pub fn wait_for_balance_with_commitment(
151        &self,
152        pubkey: &Pubkey,
153        expected_balance: Option<u64>,
154        commitment_config: CommitmentConfig
155    ) -> Option<u64>);
156
157    dispatch!(pub fn poll_for_signature_with_commitment(
158        &self,
159        signature: &Signature,
160        commitment_config: CommitmentConfig
161    ) -> TransportResult<()>);
162
163    dispatch!(pub fn get_num_blocks_since_signature_confirmation(
164        &mut self,
165        sig: &Signature
166    ) -> TransportResult<usize>);
167}
168
169impl Client for ThinClient {
170    dispatch!(fn tpu_addr(&self) -> String);
171}
172
173impl SyncClient for ThinClient {
174    dispatch!(fn send_and_confirm_message<T: Signers + ?Sized>(
175        &self,
176        keypairs: &T,
177        message: Message
178    ) -> TransportResult<Signature>);
179
180    dispatch!(fn send_and_confirm_instruction(
181        &self,
182        keypair: &Keypair,
183        instruction: Instruction
184    ) -> TransportResult<Signature>);
185
186    dispatch!(fn transfer_and_confirm(
187        &self,
188        lamports: u64,
189        keypair: &Keypair,
190        pubkey: &Pubkey
191    ) -> TransportResult<Signature>);
192
193    dispatch!(fn get_account_data(&self, pubkey: &Pubkey) -> TransportResult<Option<Vec<u8>>>);
194
195    dispatch!(fn get_account(&self, pubkey: &Pubkey) -> TransportResult<Option<Account>>);
196
197    dispatch!(fn get_account_with_commitment(
198        &self,
199        pubkey: &Pubkey,
200        commitment_config: CommitmentConfig
201    ) -> TransportResult<Option<Account>>);
202
203    dispatch!(fn get_balance(&self, pubkey: &Pubkey) -> TransportResult<u64>);
204
205    dispatch!(fn get_balance_with_commitment(
206        &self,
207        pubkey: &Pubkey,
208        commitment_config: CommitmentConfig
209    ) -> TransportResult<u64>);
210
211    dispatch!(fn get_minimum_balance_for_rent_exemption(&self, data_len: usize) -> TransportResult<u64>);
212
213    dispatch!(fn get_signature_status(
214        &self,
215        signature: &Signature
216    ) -> TransportResult<Option<TransactionResult<()>>>);
217
218    dispatch!(fn get_signature_status_with_commitment(
219        &self,
220        signature: &Signature,
221        commitment_config: CommitmentConfig
222    ) -> TransportResult<Option<TransactionResult<()>>>);
223
224    dispatch!(fn get_slot(&self) -> TransportResult<u64>);
225
226    dispatch!(fn get_slot_with_commitment(
227        &self,
228        commitment_config: CommitmentConfig
229    ) -> TransportResult<u64>);
230
231    dispatch!(fn get_epoch_info(&self) -> TransportResult<EpochInfo>);
232
233    dispatch!(fn get_transaction_count(&self) -> TransportResult<u64>);
234
235    dispatch!(fn get_transaction_count_with_commitment(
236        &self,
237        commitment_config: CommitmentConfig
238    ) -> TransportResult<u64>);
239
240    dispatch!(fn poll_for_signature_confirmation(
241        &self,
242        signature: &Signature,
243        min_confirmed_blocks: usize
244    ) -> TransportResult<usize>);
245
246    dispatch!(fn poll_for_signature(&self, signature: &Signature) -> TransportResult<()>);
247
248    dispatch!(fn get_latest_blockhash(&self) -> TransportResult<Hash>);
249
250    dispatch!(fn get_latest_blockhash_with_commitment(
251        &self,
252        commitment_config: CommitmentConfig
253    ) -> TransportResult<(Hash, u64)>);
254
255    dispatch!(fn is_blockhash_valid(
256        &self,
257        blockhash: &Hash,
258        commitment_config: CommitmentConfig
259    ) -> TransportResult<bool>);
260
261    dispatch!(fn get_fee_for_message(&self, message: &Message) -> TransportResult<u64>);
262}
263
264impl AsyncClient for ThinClient {
265    dispatch!(fn async_send_versioned_transaction(
266        &self,
267        transaction: VersionedTransaction
268    ) -> TransportResult<Signature>);
269
270    dispatch!(fn async_send_versioned_transaction_batch(
271        &self,
272        batch: Vec<VersionedTransaction>
273    ) -> TransportResult<()>);
274}