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