Procházet zdrojové kódy

thin-client: Remove deprecated module (#7115)

Faycel Kouteib před 3 měsíci
rodič
revize
1017b9aa8b

+ 0 - 30
Cargo.lock

@@ -7673,7 +7673,6 @@ dependencies = [
  "solana-signature",
  "solana-signature",
  "solana-signer",
  "solana-signer",
  "solana-streamer",
  "solana-streamer",
- "solana-thin-client",
  "solana-time-utils",
  "solana-time-utils",
  "solana-tpu-client",
  "solana-tpu-client",
  "solana-transaction",
  "solana-transaction",
@@ -9097,7 +9096,6 @@ dependencies = [
  "solana-streamer",
  "solana-streamer",
  "solana-system-interface",
  "solana-system-interface",
  "solana-system-transaction",
  "solana-system-transaction",
- "solana-thin-client",
  "solana-time-utils",
  "solana-time-utils",
  "solana-tpu-client",
  "solana-tpu-client",
  "solana-transaction",
  "solana-transaction",
@@ -11130,34 +11128,6 @@ dependencies = [
  "tokio",
  "tokio",
 ]
 ]
 
 
-[[package]]
-name = "solana-thin-client"
-version = "3.0.0"
-dependencies = [
- "bincode",
- "log",
- "rayon",
- "solana-account",
- "solana-client-traits",
- "solana-clock",
- "solana-commitment-config",
- "solana-connection-cache",
- "solana-epoch-info",
- "solana-hash",
- "solana-instruction",
- "solana-keypair",
- "solana-logger",
- "solana-message",
- "solana-pubkey",
- "solana-rpc-client",
- "solana-rpc-client-api",
- "solana-signature",
- "solana-signer",
- "solana-system-interface",
- "solana-transaction",
- "solana-transaction-error",
-]
-
 [[package]]
 [[package]]
 name = "solana-time-utils"
 name = "solana-time-utils"
 version = "2.2.1"
 version = "2.2.1"

+ 0 - 2
Cargo.toml

@@ -110,7 +110,6 @@ members = [
     "syscalls",
     "syscalls",
     "syscalls/gen-syscall-list",
     "syscalls/gen-syscall-list",
     "test-validator",
     "test-validator",
-    "thin-client",
     "thread-manager",
     "thread-manager",
     "timings",
     "timings",
     "tls-utils",
     "tls-utils",
@@ -533,7 +532,6 @@ solana-system-transaction = "2.2.1"
 solana-sysvar = "2.2.2"
 solana-sysvar = "2.2.2"
 solana-sysvar-id = "2.2.1"
 solana-sysvar-id = "2.2.1"
 solana-test-validator = { path = "test-validator", version = "=3.0.0" }
 solana-test-validator = { path = "test-validator", version = "=3.0.0" }
-solana-thin-client = { path = "thin-client", version = "=3.0.0" }
 solana-time-utils = "2.2.1"
 solana-time-utils = "2.2.1"
 solana-timings = { path = "timings", version = "=3.0.0" }
 solana-timings = { path = "timings", version = "=3.0.0" }
 solana-tls-utils = { path = "tls-utils", version = "=3.0.0" }
 solana-tls-utils = { path = "tls-utils", version = "=3.0.0" }

+ 0 - 65
bench-tps/src/cli.rs

@@ -159,41 +159,6 @@ pub fn build_args<'a>(version: &'_ str) -> App<'a, '_> {
                 .validator(is_url)
                 .validator(is_url)
                 .help("WebSocket URL for the solana cluster"),
                 .help("WebSocket URL for the solana cluster"),
         )
         )
-        .arg(
-            Arg::with_name("rpc_addr")
-                .long("rpc-addr")
-                .value_name("HOST:PORT")
-                .takes_value(true)
-                .conflicts_with("rpc_client")
-                .requires("tpu_addr")
-                .hidden(hidden_unless_forced())
-                .help("Specify custom rpc_addr to create thin_client. \
-                    Note: ThinClient is deprecated. Argument will not be used. \
-                    Use tpc_client or rpc_client instead"),
-        )
-        .arg(
-            Arg::with_name("tpu_addr")
-                .long("tpu-addr")
-                .value_name("HOST:PORT")
-                .conflicts_with("rpc_client")
-                .takes_value(true)
-                .requires("rpc_addr")
-                .hidden(hidden_unless_forced())
-                .help("Specify custom tpu_addr to create thin_client. \
-                    Note: ThinClient is deprecated. Argument will not be used. \
-                    Use tpc_client or rpc_client instead"),
-        )
-        .arg(
-            Arg::with_name("entrypoint")
-                .short("n")
-                .long("entrypoint")
-                .value_name("HOST:PORT")
-                .takes_value(true)
-                .hidden(hidden_unless_forced())
-                .help("Rendezvous with the cluster at this entry point; defaults to 127.0.0.1:8001. \
-                    Note: ThinClient is deprecated. Argument will not be used. \
-                    Use tpc_client or rpc_client instead"),
-        )
         .arg(
         .arg(
             Arg::with_name("faucet")
             Arg::with_name("faucet")
                 .short("d")
                 .short("d")
@@ -221,17 +186,6 @@ pub fn build_args<'a>(version: &'_ str) -> App<'a, '_> {
                 .takes_value(true)
                 .takes_value(true)
                 .help("File containing a client authority (keypair) to fund participating accounts"),
                 .help("File containing a client authority (keypair) to fund participating accounts"),
         )
         )
-        .arg(
-            Arg::with_name("num-nodes")
-                .short("N")
-                .long("num-nodes")
-                .value_name("NUM")
-                .takes_value(true)
-                .hidden(hidden_unless_forced())
-                .help("Wait for NUM nodes to converge. \
-                    Note: ThinClient is deprecated. Argument will not be used. \
-                    Use tpc_client or rpc_client instead"),
-        )
         .arg(
         .arg(
             Arg::with_name("threads")
             Arg::with_name("threads")
                 .short("t")
                 .short("t")
@@ -252,25 +206,6 @@ pub fn build_args<'a>(version: &'_ str) -> App<'a, '_> {
                 .long("sustained")
                 .long("sustained")
                 .help("Use sustained performance mode vs. peak mode. This overlaps the tx generation with transfers."),
                 .help("Use sustained performance mode vs. peak mode. This overlaps the tx generation with transfers."),
         )
         )
-        .arg(
-            Arg::with_name("no-multi-client")
-                .long("no-multi-client")
-                .hidden(hidden_unless_forced())
-                .help("Disable multi-client support, only transact with the entrypoint. \
-                    Note: ThinClient is deprecated. Flag will not be used. \
-                    Use tpc_client or rpc_client instead"),
-        )
-        .arg(
-            Arg::with_name("target_node")
-                .long("target-node")
-                .requires("no-multi-client")
-                .takes_value(true)
-                .value_name("PUBKEY")
-                .hidden(hidden_unless_forced())
-                .help("Specify an exact node to send transactions to. \
-                    Note: ThinClient is deprecated. Argument will not be used. \
-                    Use tpc_client or rpc_client instead"),
-        )
         .arg(
         .arg(
             Arg::with_name("tx_count")
             Arg::with_name("tx_count")
                 .long("tx-count")
                 .long("tx-count")

+ 0 - 1
client/Cargo.toml

@@ -43,7 +43,6 @@ solana-rpc-client-nonce-utils = { workspace = true }
 solana-signature = { workspace = true }
 solana-signature = { workspace = true }
 solana-signer = { workspace = true }
 solana-signer = { workspace = true }
 solana-streamer = { workspace = true }
 solana-streamer = { workspace = true }
-solana-thin-client = { workspace = true }
 solana-time-utils = { workspace = true }
 solana-time-utils = { workspace = true }
 solana-tpu-client = { workspace = true, features = ["default"] }
 solana-tpu-client = { workspace = true, features = ["default"] }
 solana-transaction = { workspace = true }
 solana-transaction = { workspace = true }

+ 0 - 1
client/src/lib.rs

@@ -3,7 +3,6 @@
 pub mod connection_cache;
 pub mod connection_cache;
 pub mod nonblocking;
 pub mod nonblocking;
 pub mod send_and_confirm_transactions_in_parallel;
 pub mod send_and_confirm_transactions_in_parallel;
-pub mod thin_client;
 pub mod tpu_client;
 pub mod tpu_client;
 pub mod transaction_executor;
 pub mod transaction_executor;
 
 

+ 0 - 274
client/src/thin_client.rs

@@ -1,274 +0,0 @@
-//! The `thin_client` module is a client-side object that interfaces with
-//! a server-side TPU.  Client code should use this object instead of writing
-//! messages to the network directly. The binary encoding of its messages are
-//! unstable and may change in future releases.
-#[allow(deprecated)]
-use {
-    crate::connection_cache::{dispatch, ConnectionCache},
-    solana_account::Account,
-    solana_client_traits::{AsyncClient, Client, SyncClient},
-    solana_commitment_config::CommitmentConfig,
-    solana_epoch_info::EpochInfo,
-    solana_hash::Hash,
-    solana_instruction::Instruction,
-    solana_keypair::Keypair,
-    solana_message::Message,
-    solana_pubkey::Pubkey,
-    solana_quic_client::{QuicConfig, QuicConnectionManager, QuicPool},
-    solana_rpc_client::rpc_client::RpcClient,
-    solana_rpc_client_api::config::RpcProgramAccountsConfig,
-    solana_signature::Signature,
-    solana_signer::signers::Signers,
-    solana_thin_client::thin_client::ThinClient as BackendThinClient,
-    solana_transaction::{versioned::VersionedTransaction, Transaction},
-    solana_transaction_error::{TransactionResult, TransportResult},
-    solana_udp_client::{UdpConfig, UdpConnectionManager, UdpPool},
-    std::{net::SocketAddr, sync::Arc, time::Duration},
-};
-
-/// A thin wrapper over thin-client/ThinClient to ease
-/// construction of the ThinClient for code dealing both with udp and quic.
-/// For the scenario only using udp or quic, use thin-client/ThinClient directly.
-#[allow(deprecated)]
-pub enum ThinClient {
-    Quic(BackendThinClient<QuicPool, QuicConnectionManager, QuicConfig>),
-    Udp(BackendThinClient<UdpPool, UdpConnectionManager, UdpConfig>),
-}
-
-#[allow(deprecated)]
-impl ThinClient {
-    /// Create a new ThinClient that will interface with the Rpc at `rpc_addr` using TCP
-    /// and the Tpu at `tpu_addr` over `transactions_socket` using Quic or UDP
-    /// (currently hardcoded to UDP)
-    pub fn new(
-        rpc_addr: SocketAddr,
-        tpu_addr: SocketAddr,
-        connection_cache: Arc<ConnectionCache>,
-    ) -> Self {
-        match &*connection_cache {
-            ConnectionCache::Quic(connection_cache) => {
-                let thin_client =
-                    BackendThinClient::new(rpc_addr, tpu_addr, connection_cache.clone());
-                ThinClient::Quic(thin_client)
-            }
-            ConnectionCache::Udp(connection_cache) => {
-                let thin_client =
-                    BackendThinClient::new(rpc_addr, tpu_addr, connection_cache.clone());
-                ThinClient::Udp(thin_client)
-            }
-        }
-    }
-
-    pub fn new_socket_with_timeout(
-        rpc_addr: SocketAddr,
-        tpu_addr: SocketAddr,
-        timeout: Duration,
-        connection_cache: Arc<ConnectionCache>,
-    ) -> Self {
-        match &*connection_cache {
-            ConnectionCache::Quic(connection_cache) => {
-                let thin_client = BackendThinClient::new_socket_with_timeout(
-                    rpc_addr,
-                    tpu_addr,
-                    timeout,
-                    connection_cache.clone(),
-                );
-                ThinClient::Quic(thin_client)
-            }
-            ConnectionCache::Udp(connection_cache) => {
-                let thin_client = BackendThinClient::new_socket_with_timeout(
-                    rpc_addr,
-                    tpu_addr,
-                    timeout,
-                    connection_cache.clone(),
-                );
-                ThinClient::Udp(thin_client)
-            }
-        }
-    }
-
-    pub fn new_from_addrs(
-        rpc_addrs: Vec<SocketAddr>,
-        tpu_addrs: Vec<SocketAddr>,
-        connection_cache: Arc<ConnectionCache>,
-    ) -> Self {
-        match &*connection_cache {
-            ConnectionCache::Quic(connection_cache) => {
-                let thin_client = BackendThinClient::new_from_addrs(
-                    rpc_addrs,
-                    tpu_addrs,
-                    connection_cache.clone(),
-                );
-                ThinClient::Quic(thin_client)
-            }
-            ConnectionCache::Udp(connection_cache) => {
-                let thin_client = BackendThinClient::new_from_addrs(
-                    rpc_addrs,
-                    tpu_addrs,
-                    connection_cache.clone(),
-                );
-                ThinClient::Udp(thin_client)
-            }
-        }
-    }
-
-    dispatch!(pub fn rpc_client(&self) -> &RpcClient);
-
-    dispatch!(pub fn retry_transfer_until_confirmed(&self, keypair: &Keypair, transaction: &mut Transaction, tries: usize, min_confirmed_blocks: usize) -> TransportResult<Signature>);
-
-    dispatch!(pub fn retry_transfer(
-        &self,
-        keypair: &Keypair,
-        transaction: &mut Transaction,
-        tries: usize
-    ) -> TransportResult<Signature>);
-
-    dispatch!(pub fn send_and_confirm_transaction<T: Signers + ?Sized>(
-        &self,
-        keypairs: &T,
-        transaction: &mut Transaction,
-        tries: usize,
-        pending_confirmations: usize
-    ) -> TransportResult<Signature>);
-
-    dispatch!(pub fn poll_get_balance(&self, pubkey: &Pubkey) -> TransportResult<u64>);
-
-    dispatch!(pub fn poll_get_balance_with_commitment(
-        &self,
-        pubkey: &Pubkey,
-        commitment_config: CommitmentConfig
-    ) -> TransportResult<u64>);
-
-    dispatch!(pub fn wait_for_balance(&self, pubkey: &Pubkey, expected_balance: Option<u64>) -> Option<u64>);
-
-    dispatch!(pub fn get_program_accounts_with_config(
-        &self,
-        pubkey: &Pubkey,
-        config: RpcProgramAccountsConfig
-    ) -> TransportResult<Vec<(Pubkey, Account)>>);
-
-    dispatch!(pub fn wait_for_balance_with_commitment(
-        &self,
-        pubkey: &Pubkey,
-        expected_balance: Option<u64>,
-        commitment_config: CommitmentConfig
-    ) -> Option<u64>);
-
-    dispatch!(pub fn poll_for_signature_with_commitment(
-        &self,
-        signature: &Signature,
-        commitment_config: CommitmentConfig
-    ) -> TransportResult<()>);
-
-    dispatch!(pub fn get_num_blocks_since_signature_confirmation(
-        &mut self,
-        sig: &Signature
-    ) -> TransportResult<usize>);
-}
-
-impl Client for ThinClient {
-    dispatch!(fn tpu_addr(&self) -> String);
-}
-
-impl SyncClient for ThinClient {
-    dispatch!(fn send_and_confirm_message<T: Signers + ?Sized>(
-        &self,
-        keypairs: &T,
-        message: Message
-    ) -> TransportResult<Signature>);
-
-    dispatch!(fn send_and_confirm_instruction(
-        &self,
-        keypair: &Keypair,
-        instruction: Instruction
-    ) -> TransportResult<Signature>);
-
-    dispatch!(fn transfer_and_confirm(
-        &self,
-        lamports: u64,
-        keypair: &Keypair,
-        pubkey: &Pubkey
-    ) -> TransportResult<Signature>);
-
-    dispatch!(fn get_account_data(&self, pubkey: &Pubkey) -> TransportResult<Option<Vec<u8>>>);
-
-    dispatch!(fn get_account(&self, pubkey: &Pubkey) -> TransportResult<Option<Account>>);
-
-    dispatch!(fn get_account_with_commitment(
-        &self,
-        pubkey: &Pubkey,
-        commitment_config: CommitmentConfig
-    ) -> TransportResult<Option<Account>>);
-
-    dispatch!(fn get_balance(&self, pubkey: &Pubkey) -> TransportResult<u64>);
-
-    dispatch!(fn get_balance_with_commitment(
-        &self,
-        pubkey: &Pubkey,
-        commitment_config: CommitmentConfig
-    ) -> TransportResult<u64>);
-
-    dispatch!(fn get_minimum_balance_for_rent_exemption(&self, data_len: usize) -> TransportResult<u64>);
-
-    dispatch!(fn get_signature_status(
-        &self,
-        signature: &Signature
-    ) -> TransportResult<Option<TransactionResult<()>>>);
-
-    dispatch!(fn get_signature_status_with_commitment(
-        &self,
-        signature: &Signature,
-        commitment_config: CommitmentConfig
-    ) -> TransportResult<Option<TransactionResult<()>>>);
-
-    dispatch!(fn get_slot(&self) -> TransportResult<u64>);
-
-    dispatch!(fn get_slot_with_commitment(
-        &self,
-        commitment_config: CommitmentConfig
-    ) -> TransportResult<u64>);
-
-    dispatch!(fn get_epoch_info(&self) -> TransportResult<EpochInfo>);
-
-    dispatch!(fn get_transaction_count(&self) -> TransportResult<u64>);
-
-    dispatch!(fn get_transaction_count_with_commitment(
-        &self,
-        commitment_config: CommitmentConfig
-    ) -> TransportResult<u64>);
-
-    dispatch!(fn poll_for_signature_confirmation(
-        &self,
-        signature: &Signature,
-        min_confirmed_blocks: usize
-    ) -> TransportResult<usize>);
-
-    dispatch!(fn poll_for_signature(&self, signature: &Signature) -> TransportResult<()>);
-
-    dispatch!(fn get_latest_blockhash(&self) -> TransportResult<Hash>);
-
-    dispatch!(fn get_latest_blockhash_with_commitment(
-        &self,
-        commitment_config: CommitmentConfig
-    ) -> TransportResult<(Hash, u64)>);
-
-    dispatch!(fn is_blockhash_valid(
-        &self,
-        blockhash: &Hash,
-        commitment_config: CommitmentConfig
-    ) -> TransportResult<bool>);
-
-    dispatch!(fn get_fee_for_message(&self, message: &Message) -> TransportResult<u64>);
-}
-
-impl AsyncClient for ThinClient {
-    dispatch!(fn async_send_versioned_transaction(
-        &self,
-        transaction: VersionedTransaction
-    ) -> TransportResult<Signature>);
-
-    dispatch!(fn async_send_versioned_transaction_batch(
-        &self,
-        batch: Vec<VersionedTransaction>
-    ) -> TransportResult<()>);
-}

+ 0 - 4
docs/src/implemented-proposals/testing-programs.md

@@ -34,10 +34,6 @@ trait SyncClient {
 
 
 Users send transactions and asynchronously and synchronously await results.
 Users send transactions and asynchronously and synchronously await results.
 
 
-### ThinClient for Clusters
-
-The highest level implementation, ThinClient, targets a Solana cluster, which may be a deployed testnet or a local cluster running on a development machine.
-
 ### TpuClient for the TPU
 ### TpuClient for the TPU
 
 
 The next level is the TPU implementation, which is not yet implemented. At the TPU level, the application sends transactions over Rust channels, where there can be no surprises from network queues or dropped packets. The TPU implements all "normal" transaction errors. It does signature verification, may report account-in-use errors, and otherwise results in the ledger, complete with proof of history hashes.
 The next level is the TPU implementation, which is not yet implemented. At the TPU level, the application sends transactions over Rust channels, where there can be no surprises from network queues or dropped packets. The TPU implements all "normal" transaction errors. It does signature verification, may report account-in-use errors, and otherwise results in the ledger, complete with proof of history hashes.

+ 0 - 54
docs/src/proposals/rust-clients.md

@@ -1,54 +0,0 @@
----
-title: Rust Clients
----
-
-## Problem
-
-High-level tests, such as bench-tps, are written in terms of the `Client`
-trait. When we execute these tests as part of the test suite, we use the
-low-level `BankClient` implementation. When we need to run the same test
-against a cluster, we use the `ThinClient` implementation. The problem with
-that approach is that it means the trait will continually expand to include new
-utility functions and all implementations of it need to add the new
-functionality. By separating the user-facing object from the trait that abstracts
-the network interface, we can expand the user-facing object to include all sorts
-of useful functionality, such as the "spinner" from RpcClient, without concern
-for needing to extend the trait and its implementations.
-
-## Proposed Solution
-
-Instead of implementing the `Client` trait, `ThinClient` should be constructed
-with an implementation of it. That way, all utility functions currently in the
-`Client` trait can move into `ThinClient`. `ThinClient` could then move into
-`solana-sdk` since all its network dependencies would be in the implementation
-of `Client`. We would then add a new implementation of `Client`, called
-`ClusterClient`, and that would live in the `solana-client` crate, where
-`ThinClient` currently resides.
-
-After this reorg, any code needing a client would be written in terms of
-`ThinClient`. In unit tests, the functionality would be invoked with
-`ThinClient<BankClient>`, whereas `main()` functions, benchmarks and
-integration tests would invoke it with `ThinClient<ClusterClient>`.
-
-If higher-level components require more functionality than what could be
-implemented by `BankClient`, it should be implemented by a second object
-that implements a second trait, following the same pattern described here.
-
-### Error Handling
-
-The `Client` should use the existing `TransportError` enum for errors, except
-that the `Custom(String)` field should be changed to `Custom(Box<dyn Error>)`.
-
-### Implementation Strategy
-
-1. Add new object to `solana-sdk`, `RpcClientTng`, where the `Tng` suffix is
-   temporary and stands for "The Next Generation"
-2. Initialize `RpcClientTng` with a `SyncClient` implementation.
-3. Add new object to `solana-sdk`, `ThinClientTng`; initialize it with
-   `RpcClientTng` and an `AsyncClient` implementation
-4. Move all unit-tests from `BankClient` to `ThinClientTng<BankClient>`
-5. Add `ClusterClient`
-6. Move `ThinClient` users to `ThinClientTng<ClusterClient>`
-7. Delete `ThinClient` and rename `ThinClientTng` to `ThinClient`
-8. Move `RpcClient` users to new `ThinClient<ClusterClient>`
-9. Delete `RpcClient` and rename `RpcClientTng` to `RpcClient`

+ 0 - 1
local-cluster/Cargo.toml

@@ -56,7 +56,6 @@ solana-stake-program = { workspace = true }
 solana-streamer = { workspace = true }
 solana-streamer = { workspace = true }
 solana-system-interface = { workspace = true }
 solana-system-interface = { workspace = true }
 solana-system-transaction = { workspace = true }
 solana-system-transaction = { workspace = true }
-solana-thin-client = { workspace = true }
 solana-time-utils = { workspace = true }
 solana-time-utils = { workspace = true }
 solana-tpu-client = { workspace = true }
 solana-tpu-client = { workspace = true }
 solana-transaction = { workspace = true }
 solana-transaction = { workspace = true }

+ 0 - 28
programs/sbf/Cargo.lock

@@ -5929,7 +5929,6 @@ dependencies = [
  "solana-signature",
  "solana-signature",
  "solana-signer",
  "solana-signer",
  "solana-streamer",
  "solana-streamer",
- "solana-thin-client",
  "solana-time-utils",
  "solana-time-utils",
  "solana-tpu-client",
  "solana-tpu-client",
  "solana-transaction",
  "solana-transaction",
@@ -9351,33 +9350,6 @@ dependencies = [
  "tokio",
  "tokio",
 ]
 ]
 
 
-[[package]]
-name = "solana-thin-client"
-version = "3.0.0"
-dependencies = [
- "bincode",
- "log",
- "rayon",
- "solana-account",
- "solana-client-traits",
- "solana-clock",
- "solana-commitment-config",
- "solana-connection-cache",
- "solana-epoch-info",
- "solana-hash",
- "solana-instruction",
- "solana-keypair",
- "solana-message",
- "solana-pubkey",
- "solana-rpc-client",
- "solana-rpc-client-api",
- "solana-signature",
- "solana-signer",
- "solana-system-interface",
- "solana-transaction",
- "solana-transaction-error",
-]
-
 [[package]]
 [[package]]
 name = "solana-time-utils"
 name = "solana-time-utils"
 version = "2.2.1"
 version = "2.2.1"

+ 0 - 2
scripts/patch-crates.sh

@@ -64,7 +64,6 @@ update_solana_dependencies() {
     solana-svm-rent-calculator
     solana-svm-rent-calculator
     solana-svm-transaction
     solana-svm-transaction
     solana-test-validator
     solana-test-validator
-    solana-thin-client
     solana-tpu-client
     solana-tpu-client
     solana-transaction-status
     solana-transaction-status
     solana-transaction-status-client-types
     solana-transaction-status-client-types
@@ -152,7 +151,6 @@ patch_crates_io_solana_no_header() {
   crates_map+=("solana-svm-rent-collector svm-rent-collector")
   crates_map+=("solana-svm-rent-collector svm-rent-collector")
   crates_map+=("solana-svm-transaction svm-transaction")
   crates_map+=("solana-svm-transaction svm-transaction")
   crates_map+=("solana-test-validator test-validator")
   crates_map+=("solana-test-validator test-validator")
-  crates_map+=("solana-thin-client thin-client")
   crates_map+=("solana-tpu-client tpu-client")
   crates_map+=("solana-tpu-client tpu-client")
   crates_map+=("solana-transaction-status transaction-status")
   crates_map+=("solana-transaction-status transaction-status")
   crates_map+=("solana-transaction-status-client-types transaction-status-client-types")
   crates_map+=("solana-transaction-status-client-types transaction-status-client-types")

+ 0 - 28
svm/examples/Cargo.lock

@@ -5764,7 +5764,6 @@ dependencies = [
  "solana-signature",
  "solana-signature",
  "solana-signer",
  "solana-signer",
  "solana-streamer",
  "solana-streamer",
- "solana-thin-client",
  "solana-time-utils",
  "solana-time-utils",
  "solana-tpu-client",
  "solana-tpu-client",
  "solana-transaction",
  "solana-transaction",
@@ -8439,33 +8438,6 @@ dependencies = [
  "tokio",
  "tokio",
 ]
 ]
 
 
-[[package]]
-name = "solana-thin-client"
-version = "3.0.0"
-dependencies = [
- "bincode",
- "log",
- "rayon",
- "solana-account",
- "solana-client-traits",
- "solana-clock",
- "solana-commitment-config",
- "solana-connection-cache",
- "solana-epoch-info",
- "solana-hash",
- "solana-instruction",
- "solana-keypair",
- "solana-message",
- "solana-pubkey",
- "solana-rpc-client",
- "solana-rpc-client-api",
- "solana-signature",
- "solana-signer",
- "solana-system-interface",
- "solana-transaction",
- "solana-transaction-error",
-]
-
 [[package]]
 [[package]]
 name = "solana-time-utils"
 name = "solana-time-utils"
 version = "2.2.1"
 version = "2.2.1"

+ 0 - 39
thin-client/Cargo.toml

@@ -1,39 +0,0 @@
-[package]
-name = "solana-thin-client"
-description = "Solana Thin Client"
-documentation = "https://docs.rs/solana-thin-client"
-version = { workspace = true }
-authors = { workspace = true }
-repository = { workspace = true }
-homepage = { workspace = true }
-license = { workspace = true }
-edition = { workspace = true }
-
-[package.metadata.docs.rs]
-targets = ["x86_64-unknown-linux-gnu"]
-
-[dependencies]
-bincode = { workspace = true }
-log = { workspace = true }
-rayon = { workspace = true }
-solana-account = { workspace = true }
-solana-client-traits = { workspace = true }
-solana-clock = { workspace = true }
-solana-commitment-config = { workspace = true }
-solana-connection-cache = { workspace = true }
-solana-epoch-info = { workspace = true }
-solana-hash = { workspace = true }
-solana-instruction = { workspace = true }
-solana-keypair = { workspace = true }
-solana-message = { workspace = true }
-solana-pubkey = { workspace = true }
-solana-rpc-client = { workspace = true }
-solana-rpc-client-api = { workspace = true }
-solana-signature = { workspace = true }
-solana-signer = { workspace = true }
-solana-system-interface = { workspace = true, features = ["bincode"] }
-solana-transaction = { workspace = true }
-solana-transaction-error = { workspace = true }
-
-[dev-dependencies]
-solana-logger = { workspace = true }

+ 0 - 4
thin-client/README.md

@@ -1,4 +0,0 @@
-# thin-client
-This crate for `thin-client` is deprecated as of v2.0.0. It will receive no bugfixes or updates.
-
-Please use `tpu-client` or `rpc-client`.

+ 0 - 3
thin-client/src/lib.rs

@@ -1,3 +0,0 @@
-#![allow(clippy::arithmetic_side_effects)]
-
-pub mod thin_client;

+ 0 - 620
thin-client/src/thin_client.rs

@@ -1,620 +0,0 @@
-//! The `thin_client` module is a client-side object that interfaces with
-//! a server-side TPU.  Client code should use this object instead of writing
-//! messages to the network directly. The binary encoding of its messages are
-//! unstable and may change in future releases.
-
-use {
-    log::*,
-    rayon::iter::{IntoParallelIterator, ParallelIterator},
-    solana_account::Account,
-    solana_client_traits::{AsyncClient, Client, SyncClient},
-    solana_clock::MAX_PROCESSING_AGE,
-    solana_commitment_config::CommitmentConfig,
-    solana_connection_cache::{
-        client_connection::ClientConnection,
-        connection_cache::{
-            ConnectionCache, ConnectionManager, ConnectionPool, NewConnectionConfig,
-        },
-    },
-    solana_epoch_info::EpochInfo,
-    solana_hash::Hash,
-    solana_instruction::Instruction,
-    solana_keypair::Keypair,
-    solana_message::Message,
-    solana_pubkey::Pubkey,
-    solana_rpc_client::rpc_client::RpcClient,
-    solana_rpc_client_api::config::RpcProgramAccountsConfig,
-    solana_signature::Signature,
-    solana_signer::{signers::Signers, Signer},
-    solana_system_interface::instruction::transfer,
-    solana_transaction::{versioned::VersionedTransaction, Transaction},
-    solana_transaction_error::{TransactionResult, TransportResult},
-    std::{
-        io,
-        net::SocketAddr,
-        sync::{
-            atomic::{AtomicBool, AtomicUsize, Ordering},
-            Arc, RwLock,
-        },
-        time::{Duration, Instant},
-    },
-};
-
-struct ClientOptimizer {
-    cur_index: AtomicUsize,
-    experiment_index: AtomicUsize,
-    experiment_done: AtomicBool,
-    times: RwLock<Vec<u64>>,
-    num_clients: usize,
-}
-
-impl ClientOptimizer {
-    fn new(num_clients: usize) -> Self {
-        Self {
-            cur_index: AtomicUsize::new(0),
-            experiment_index: AtomicUsize::new(0),
-            experiment_done: AtomicBool::new(false),
-            times: RwLock::new(vec![u64::MAX; num_clients]),
-            num_clients,
-        }
-    }
-
-    fn experiment(&self) -> usize {
-        if self.experiment_index.load(Ordering::Relaxed) < self.num_clients {
-            let old = self.experiment_index.fetch_add(1, Ordering::Relaxed);
-            if old < self.num_clients {
-                old
-            } else {
-                self.best()
-            }
-        } else {
-            self.best()
-        }
-    }
-
-    fn report(&self, index: usize, time_ms: u64) {
-        if self.num_clients > 1
-            && (!self.experiment_done.load(Ordering::Relaxed) || time_ms == u64::MAX)
-        {
-            trace!(
-                "report {} with {} exp: {}",
-                index,
-                time_ms,
-                self.experiment_index.load(Ordering::Relaxed)
-            );
-
-            self.times.write().unwrap()[index] = time_ms;
-
-            if index == (self.num_clients - 1) || time_ms == u64::MAX {
-                let times = self.times.read().unwrap();
-                let (min_time, min_index) = min_index(&times);
-                trace!("done experimenting min: {min_index} time: {min_time} times: {times:?}");
-
-                // Only 1 thread should grab the num_clients-1 index, so this should be ok.
-                self.cur_index.store(min_index, Ordering::Relaxed);
-                self.experiment_done.store(true, Ordering::Relaxed);
-            }
-        }
-    }
-
-    fn best(&self) -> usize {
-        self.cur_index.load(Ordering::Relaxed)
-    }
-}
-
-/// An object for querying and sending transactions to the network.
-#[deprecated(since = "2.0.0", note = "Use [RpcClient] or [TpuClient] instead.")]
-pub struct ThinClient<
-    P, // ConnectionPool
-    M, // ConnectionManager
-    C, // NewConnectionConfig
-> {
-    rpc_clients: Vec<RpcClient>,
-    tpu_addrs: Vec<SocketAddr>,
-    optimizer: ClientOptimizer,
-    connection_cache: Arc<ConnectionCache<P, M, C>>,
-}
-
-#[allow(deprecated)]
-impl<P, M, C> ThinClient<P, M, C>
-where
-    P: ConnectionPool<NewConnectionConfig = C>,
-    M: ConnectionManager<ConnectionPool = P, NewConnectionConfig = C>,
-    C: NewConnectionConfig,
-{
-    /// Create a new ThinClient that will interface with the Rpc at `rpc_addr` using TCP
-    /// and the Tpu at `tpu_addr` over `transactions_socket` using Quic or UDP
-    /// (currently hardcoded to UDP)
-    pub fn new(
-        rpc_addr: SocketAddr,
-        tpu_addr: SocketAddr,
-        connection_cache: Arc<ConnectionCache<P, M, C>>,
-    ) -> Self {
-        Self::new_from_client(RpcClient::new_socket(rpc_addr), tpu_addr, connection_cache)
-    }
-
-    pub fn new_socket_with_timeout(
-        rpc_addr: SocketAddr,
-        tpu_addr: SocketAddr,
-        timeout: Duration,
-        connection_cache: Arc<ConnectionCache<P, M, C>>,
-    ) -> Self {
-        let rpc_client = RpcClient::new_socket_with_timeout(rpc_addr, timeout);
-        Self::new_from_client(rpc_client, tpu_addr, connection_cache)
-    }
-
-    fn new_from_client(
-        rpc_client: RpcClient,
-        tpu_addr: SocketAddr,
-        connection_cache: Arc<ConnectionCache<P, M, C>>,
-    ) -> Self {
-        Self {
-            rpc_clients: vec![rpc_client],
-            tpu_addrs: vec![tpu_addr],
-            optimizer: ClientOptimizer::new(0),
-            connection_cache,
-        }
-    }
-
-    pub fn new_from_addrs(
-        rpc_addrs: Vec<SocketAddr>,
-        tpu_addrs: Vec<SocketAddr>,
-        connection_cache: Arc<ConnectionCache<P, M, C>>,
-    ) -> Self {
-        assert!(!rpc_addrs.is_empty());
-        assert_eq!(rpc_addrs.len(), tpu_addrs.len());
-
-        let rpc_clients: Vec<_> = rpc_addrs.into_iter().map(RpcClient::new_socket).collect();
-        let optimizer = ClientOptimizer::new(rpc_clients.len());
-        Self {
-            rpc_clients,
-            tpu_addrs,
-            optimizer,
-            connection_cache,
-        }
-    }
-
-    fn tpu_addr(&self) -> &SocketAddr {
-        &self.tpu_addrs[self.optimizer.best()]
-    }
-
-    pub fn rpc_client(&self) -> &RpcClient {
-        &self.rpc_clients[self.optimizer.best()]
-    }
-
-    /// Retry a sending a signed Transaction to the server for processing.
-    pub fn retry_transfer_until_confirmed(
-        &self,
-        keypair: &Keypair,
-        transaction: &mut Transaction,
-        tries: usize,
-        min_confirmed_blocks: usize,
-    ) -> TransportResult<Signature> {
-        self.send_and_confirm_transaction(&[keypair], transaction, tries, min_confirmed_blocks)
-    }
-
-    /// Retry sending a signed Transaction with one signing Keypair to the server for processing.
-    pub fn retry_transfer(
-        &self,
-        keypair: &Keypair,
-        transaction: &mut Transaction,
-        tries: usize,
-    ) -> TransportResult<Signature> {
-        self.send_and_confirm_transaction(&[keypair], transaction, tries, 0)
-    }
-
-    pub fn send_and_confirm_transaction<T: Signers + ?Sized>(
-        &self,
-        keypairs: &T,
-        transaction: &mut Transaction,
-        tries: usize,
-        pending_confirmations: usize,
-    ) -> TransportResult<Signature> {
-        for x in 0..tries {
-            let now = Instant::now();
-            let mut num_confirmed = 0;
-            let mut wait_time = MAX_PROCESSING_AGE;
-            // resend the same transaction until the transaction has no chance of succeeding
-            let wire_transaction =
-                bincode::serialize(&transaction).expect("transaction serialization failed");
-            while now.elapsed().as_secs() < wait_time as u64 {
-                if num_confirmed == 0 {
-                    let conn = self.connection_cache.get_connection(self.tpu_addr());
-                    // Send the transaction if there has been no confirmation (e.g. the first time)
-                    #[allow(clippy::needless_borrow)]
-                    conn.send_data(&wire_transaction)?;
-                }
-
-                if let Ok(confirmed_blocks) = self.poll_for_signature_confirmation(
-                    &transaction.signatures[0],
-                    pending_confirmations,
-                ) {
-                    num_confirmed = confirmed_blocks;
-                    if confirmed_blocks >= pending_confirmations {
-                        return Ok(transaction.signatures[0]);
-                    }
-                    // Since network has seen the transaction, wait longer to receive
-                    // all pending confirmations. Resending the transaction could result into
-                    // extra transaction fees
-                    wait_time = wait_time.max(
-                        MAX_PROCESSING_AGE * pending_confirmations.saturating_sub(num_confirmed),
-                    );
-                }
-            }
-            info!("{} tries failed transfer to {}", x, self.tpu_addr());
-            let blockhash = self.get_latest_blockhash()?;
-            transaction.sign(keypairs, blockhash);
-        }
-        Err(io::Error::other(format!("retry_transfer failed in {tries} retries")).into())
-    }
-
-    pub fn poll_get_balance(&self, pubkey: &Pubkey) -> TransportResult<u64> {
-        self.poll_get_balance_with_commitment(pubkey, CommitmentConfig::default())
-    }
-
-    pub fn poll_get_balance_with_commitment(
-        &self,
-        pubkey: &Pubkey,
-        commitment_config: CommitmentConfig,
-    ) -> TransportResult<u64> {
-        self.rpc_client()
-            .poll_get_balance_with_commitment(pubkey, commitment_config)
-            .map_err(|e| e.into())
-    }
-
-    pub fn wait_for_balance(&self, pubkey: &Pubkey, expected_balance: Option<u64>) -> Option<u64> {
-        self.rpc_client().wait_for_balance_with_commitment(
-            pubkey,
-            expected_balance,
-            CommitmentConfig::default(),
-        )
-    }
-
-    pub fn get_program_accounts_with_config(
-        &self,
-        pubkey: &Pubkey,
-        config: RpcProgramAccountsConfig,
-    ) -> TransportResult<Vec<(Pubkey, Account)>> {
-        self.rpc_client()
-            .get_program_accounts_with_config(pubkey, config)
-            .map_err(|e| e.into())
-    }
-
-    pub fn wait_for_balance_with_commitment(
-        &self,
-        pubkey: &Pubkey,
-        expected_balance: Option<u64>,
-        commitment_config: CommitmentConfig,
-    ) -> Option<u64> {
-        self.rpc_client().wait_for_balance_with_commitment(
-            pubkey,
-            expected_balance,
-            commitment_config,
-        )
-    }
-
-    pub fn poll_for_signature_with_commitment(
-        &self,
-        signature: &Signature,
-        commitment_config: CommitmentConfig,
-    ) -> TransportResult<()> {
-        self.rpc_client()
-            .poll_for_signature_with_commitment(signature, commitment_config)
-            .map_err(|e| e.into())
-    }
-
-    pub fn get_num_blocks_since_signature_confirmation(
-        &mut self,
-        sig: &Signature,
-    ) -> TransportResult<usize> {
-        self.rpc_client()
-            .get_num_blocks_since_signature_confirmation(sig)
-            .map_err(|e| e.into())
-    }
-}
-
-#[allow(deprecated)]
-impl<P, M, C> Client for ThinClient<P, M, C>
-where
-    P: ConnectionPool<NewConnectionConfig = C>,
-    M: ConnectionManager<ConnectionPool = P, NewConnectionConfig = C>,
-    C: NewConnectionConfig,
-{
-    fn tpu_addr(&self) -> String {
-        self.tpu_addr().to_string()
-    }
-}
-
-#[allow(deprecated)]
-impl<P, M, C> SyncClient for ThinClient<P, M, C>
-where
-    P: ConnectionPool<NewConnectionConfig = C>,
-    M: ConnectionManager<ConnectionPool = P, NewConnectionConfig = C>,
-    C: NewConnectionConfig,
-{
-    fn send_and_confirm_message<T: Signers + ?Sized>(
-        &self,
-        keypairs: &T,
-        message: Message,
-    ) -> TransportResult<Signature> {
-        let blockhash = self.get_latest_blockhash()?;
-        let mut transaction = Transaction::new(keypairs, message, blockhash);
-        let signature = self.send_and_confirm_transaction(keypairs, &mut transaction, 5, 0)?;
-        Ok(signature)
-    }
-
-    fn send_and_confirm_instruction(
-        &self,
-        keypair: &Keypair,
-        instruction: Instruction,
-    ) -> TransportResult<Signature> {
-        let message = Message::new(&[instruction], Some(&keypair.pubkey()));
-        self.send_and_confirm_message(&[keypair], message)
-    }
-
-    fn transfer_and_confirm(
-        &self,
-        lamports: u64,
-        keypair: &Keypair,
-        pubkey: &Pubkey,
-    ) -> TransportResult<Signature> {
-        let transfer_instruction = transfer(&keypair.pubkey(), pubkey, lamports);
-        self.send_and_confirm_instruction(keypair, transfer_instruction)
-    }
-
-    fn get_account_data(&self, pubkey: &Pubkey) -> TransportResult<Option<Vec<u8>>> {
-        Ok(self.rpc_client().get_account_data(pubkey).ok())
-    }
-
-    fn get_account(&self, pubkey: &Pubkey) -> TransportResult<Option<Account>> {
-        let account = self.rpc_client().get_account(pubkey);
-        match account {
-            Ok(value) => Ok(Some(value)),
-            Err(_) => Ok(None),
-        }
-    }
-
-    fn get_account_with_commitment(
-        &self,
-        pubkey: &Pubkey,
-        commitment_config: CommitmentConfig,
-    ) -> TransportResult<Option<Account>> {
-        self.rpc_client()
-            .get_account_with_commitment(pubkey, commitment_config)
-            .map_err(|e| e.into())
-            .map(|r| r.value)
-    }
-
-    fn get_balance(&self, pubkey: &Pubkey) -> TransportResult<u64> {
-        self.rpc_client().get_balance(pubkey).map_err(|e| e.into())
-    }
-
-    fn get_balance_with_commitment(
-        &self,
-        pubkey: &Pubkey,
-        commitment_config: CommitmentConfig,
-    ) -> TransportResult<u64> {
-        self.rpc_client()
-            .get_balance_with_commitment(pubkey, commitment_config)
-            .map_err(|e| e.into())
-            .map(|r| r.value)
-    }
-
-    fn get_minimum_balance_for_rent_exemption(&self, data_len: usize) -> TransportResult<u64> {
-        self.rpc_client()
-            .get_minimum_balance_for_rent_exemption(data_len)
-            .map_err(|e| e.into())
-    }
-
-    fn get_signature_status(
-        &self,
-        signature: &Signature,
-    ) -> TransportResult<Option<TransactionResult<()>>> {
-        let status = self
-            .rpc_client()
-            .get_signature_status(signature)
-            .map_err(|err| {
-                io::Error::other(format!("send_transaction failed with error {err:?}"))
-            })?;
-        Ok(status)
-    }
-
-    fn get_signature_status_with_commitment(
-        &self,
-        signature: &Signature,
-        commitment_config: CommitmentConfig,
-    ) -> TransportResult<Option<TransactionResult<()>>> {
-        let status = self
-            .rpc_client()
-            .get_signature_status_with_commitment(signature, commitment_config)
-            .map_err(|err| {
-                io::Error::other(format!("send_transaction failed with error {err:?}"))
-            })?;
-        Ok(status)
-    }
-
-    fn get_slot(&self) -> TransportResult<u64> {
-        self.get_slot_with_commitment(CommitmentConfig::default())
-    }
-
-    fn get_slot_with_commitment(
-        &self,
-        commitment_config: CommitmentConfig,
-    ) -> TransportResult<u64> {
-        let slot = self
-            .rpc_client()
-            .get_slot_with_commitment(commitment_config)
-            .map_err(|err| {
-                io::Error::other(format!("send_transaction failed with error {err:?}"))
-            })?;
-        Ok(slot)
-    }
-
-    fn get_epoch_info(&self) -> TransportResult<EpochInfo> {
-        self.rpc_client().get_epoch_info().map_err(|e| e.into())
-    }
-
-    fn get_transaction_count(&self) -> TransportResult<u64> {
-        let index = self.optimizer.experiment();
-        let now = Instant::now();
-        match self.rpc_client().get_transaction_count() {
-            Ok(transaction_count) => {
-                self.optimizer
-                    .report(index, now.elapsed().as_millis() as u64);
-                Ok(transaction_count)
-            }
-            Err(e) => {
-                self.optimizer.report(index, u64::MAX);
-                Err(e.into())
-            }
-        }
-    }
-
-    fn get_transaction_count_with_commitment(
-        &self,
-        commitment_config: CommitmentConfig,
-    ) -> TransportResult<u64> {
-        let index = self.optimizer.experiment();
-        let now = Instant::now();
-        match self
-            .rpc_client()
-            .get_transaction_count_with_commitment(commitment_config)
-        {
-            Ok(transaction_count) => {
-                self.optimizer
-                    .report(index, now.elapsed().as_millis() as u64);
-                Ok(transaction_count)
-            }
-            Err(e) => {
-                self.optimizer.report(index, u64::MAX);
-                Err(e.into())
-            }
-        }
-    }
-
-    /// Poll the server until the signature has been confirmed by at least `min_confirmed_blocks`
-    fn poll_for_signature_confirmation(
-        &self,
-        signature: &Signature,
-        min_confirmed_blocks: usize,
-    ) -> TransportResult<usize> {
-        self.rpc_client()
-            .poll_for_signature_confirmation(signature, min_confirmed_blocks)
-            .map_err(|e| e.into())
-    }
-
-    fn poll_for_signature(&self, signature: &Signature) -> TransportResult<()> {
-        self.rpc_client()
-            .poll_for_signature(signature)
-            .map_err(|e| e.into())
-    }
-
-    fn get_latest_blockhash(&self) -> TransportResult<Hash> {
-        let (blockhash, _) =
-            self.get_latest_blockhash_with_commitment(CommitmentConfig::default())?;
-        Ok(blockhash)
-    }
-
-    fn get_latest_blockhash_with_commitment(
-        &self,
-        commitment_config: CommitmentConfig,
-    ) -> TransportResult<(Hash, u64)> {
-        let index = self.optimizer.experiment();
-        let now = Instant::now();
-        match self.rpc_clients[index].get_latest_blockhash_with_commitment(commitment_config) {
-            Ok((blockhash, last_valid_block_height)) => {
-                self.optimizer
-                    .report(index, now.elapsed().as_millis() as u64);
-                Ok((blockhash, last_valid_block_height))
-            }
-            Err(e) => {
-                self.optimizer.report(index, u64::MAX);
-                Err(e.into())
-            }
-        }
-    }
-
-    fn is_blockhash_valid(
-        &self,
-        blockhash: &Hash,
-        commitment_config: CommitmentConfig,
-    ) -> TransportResult<bool> {
-        self.rpc_client()
-            .is_blockhash_valid(blockhash, commitment_config)
-            .map_err(|e| e.into())
-    }
-
-    fn get_fee_for_message(&self, message: &Message) -> TransportResult<u64> {
-        self.rpc_client()
-            .get_fee_for_message(message)
-            .map_err(|e| e.into())
-    }
-}
-
-#[allow(deprecated)]
-impl<P, M, C> AsyncClient for ThinClient<P, M, C>
-where
-    P: ConnectionPool<NewConnectionConfig = C>,
-    M: ConnectionManager<ConnectionPool = P, NewConnectionConfig = C>,
-    C: NewConnectionConfig,
-{
-    fn async_send_versioned_transaction(
-        &self,
-        transaction: VersionedTransaction,
-    ) -> TransportResult<Signature> {
-        let conn = self.connection_cache.get_connection(self.tpu_addr());
-        let wire_transaction =
-            bincode::serialize(&transaction).expect("serialize Transaction in send_batch");
-        conn.send_data(&wire_transaction)?;
-        Ok(transaction.signatures[0])
-    }
-
-    fn async_send_versioned_transaction_batch(
-        &self,
-        batch: Vec<VersionedTransaction>,
-    ) -> TransportResult<()> {
-        let conn = self.connection_cache.get_connection(self.tpu_addr());
-        let buffers = batch
-            .into_par_iter()
-            .map(|tx| bincode::serialize(&tx).expect("serialize Transaction in send_batch"))
-            .collect::<Vec<_>>();
-        conn.send_data_batch(&buffers)?;
-        Ok(())
-    }
-}
-
-fn min_index(array: &[u64]) -> (u64, usize) {
-    let mut min_time = u64::MAX;
-    let mut min_index = 0;
-    for (i, time) in array.iter().enumerate() {
-        if *time < min_time {
-            min_time = *time;
-            min_index = i;
-        }
-    }
-    (min_time, min_index)
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn test_client_optimizer() {
-        solana_logger::setup();
-
-        const NUM_CLIENTS: usize = 5;
-        let optimizer = ClientOptimizer::new(NUM_CLIENTS);
-        (0..NUM_CLIENTS).into_par_iter().for_each(|_| {
-            let index = optimizer.experiment();
-            optimizer.report(index, (NUM_CLIENTS - index) as u64);
-        });
-
-        let index = optimizer.experiment();
-        optimizer.report(index, 50);
-        assert_eq!(optimizer.best(), NUM_CLIENTS - 1);
-
-        optimizer.report(optimizer.best(), u64::MAX);
-        assert_eq!(optimizer.best(), NUM_CLIENTS - 2);
-    }
-}