diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index de864e87..0d01d023 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -22,7 +22,7 @@ jobs: uses: baptiste0928/cargo-install@v3 with: crate: cargo-audit - version: "0.21.1" + version: "0.22.0" - run: cargo audit --ignore RUSTSEC-2022-0093 --ignore RUSTSEC-2024-0344 --ignore RUSTSEC-2024-0421 --ignore RUSTSEC-2025-0022 --ignore RUSTSEC-2025-0009 --ignore RUSTSEC-2025-0004 --ignore RUSTSEC-2024-0357 --ignore RUSTSEC-2024-0336 --ignore RUSTSEC-2025-0055 lint: diff --git a/Cargo.lock b/Cargo.lock index 03ecca12..2e964ff2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11157,11 +11157,14 @@ dependencies = [ "sha2 0.10.9", "solana-account-decoder 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "solana-client 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-connection-cache 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "solana-metrics 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "solana-program", + "solana-quic-client 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "solana-remote-wallet 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "solana-sdk", "solana-system-interface", + "solana-tpu-client 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "spl-pod", "spl-stake-pool", "squads-multisig", diff --git a/Cargo.toml b/Cargo.toml index bafba0ce..38222202 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,7 @@ solana-account-decoder = "=2.3.3" solana-bincode = "=2.2.1" solana-clap-utils = "=1.8.26" solana-client = "=2.3.3" +solana-connection-cache = "2.3.3" solana-gossip = { git = "https://github.com/gzalz/agave", branch = "gzalz/v2.3.3" } solana-metrics = "=2.3.3" solana-native-token = "=2.2.2" @@ -40,12 +41,14 @@ solana-packet = "=2.2.1" solana-program = "=2.3.0" solana-program-test = "=2.3.3" solana-pubkey = "=2.4.0" +solana-quic-client = "2.3.3" solana-remote-wallet = "=2.3.3" solana-rpc-client = "=2.3.3" solana-rpc-client-api = "=2.3.3" solana-sdk = "=2.3.1" solana-streamer = { git = "https://github.com/gzalz/agave", branch = "gzalz/v2.3.3" } solana-system-interface = "1.0.0" +solana-tpu-client = "=2.3.3" solana-transaction-status = "=2.3.3" solana-version = "=2.3.3" spl-associated-token-account = { version = "7.0.0", features = ["no-entrypoint"] } diff --git a/utils/steward-cli/Cargo.toml b/utils/steward-cli/Cargo.toml index f05ca53a..7efe9a61 100644 --- a/utils/steward-cli/Cargo.toml +++ b/utils/steward-cli/Cargo.toml @@ -23,11 +23,14 @@ serde_json = { workspace = true } sha2 = "0.10.8" solana-account-decoder = { workspace = true } solana-client = { workspace = true } +solana-connection-cache = { workspace = true } solana-metrics = { workspace = true } solana-program = { workspace = true } +solana-quic-client = { workspace = true } solana-remote-wallet = { workspace = true } solana-sdk = { workspace = true } solana-system-interface = { workspace = true } +solana-tpu-client = { workspace = true } spl-pod = { workspace = true } spl-stake-pool = { features = ["no-entrypoint"], workspace = true } squads-multisig = { workspace = true } diff --git a/utils/steward-cli/src/commands/command_args.rs b/utils/steward-cli/src/commands/command_args.rs index f9577436..ce2f2af9 100644 --- a/utils/steward-cli/src/commands/command_args.rs +++ b/utils/steward-cli/src/commands/command_args.rs @@ -37,6 +37,10 @@ pub struct Args { )] pub json_rpc_url: String, + /// WebSocket URL for the cluster + #[arg(short, long, env, default_value = "wss://api.mainnet-beta.solana.com")] + pub ws_url: String, + /// Steward program ID #[arg( long, diff --git a/utils/steward-cli/src/commands/cranks/idle.rs b/utils/steward-cli/src/commands/cranks/idle.rs index f478072e..6b5058dc 100644 --- a/utils/steward-cli/src/commands/cranks/idle.rs +++ b/utils/steward-cli/src/commands/cranks/idle.rs @@ -1,14 +1,17 @@ use std::sync::Arc; use anchor_lang::{InstructionData, ToAccountMetas}; -use anyhow::Result; +use anyhow::{anyhow, Result}; use jito_steward::StewardStateEnum; -use solana_client::nonblocking::rpc_client::RpcClient; +use solana_client::{nonblocking::rpc_client::RpcClient, tpu_client::TpuClientConfig}; +use solana_connection_cache::connection_cache::NewConnectionConfig; use solana_program::instruction::Instruction; +use solana_quic_client::{QuicConfig, QuicConnectionManager, QuicPool}; use solana_sdk::{ pubkey::Pubkey, signature::read_keypair_file, signer::Signer, transaction::Transaction, }; +use solana_tpu_client::nonblocking::tpu_client::TpuClient; use crate::commands::command_args::CrankIdle; use stakenet_sdk::utils::{ @@ -16,30 +19,34 @@ use stakenet_sdk::utils::{ transactions::{configure_instruction, print_base58_tx}, }; +type QuicTpuClient = TpuClient; + pub async fn command_crank_idle( args: CrankIdle, - client: &Arc, + rpc_client: &Arc, + ws_url: &str, program_id: Pubkey, ) -> Result<()> { let args = args.permissionless_parameters; // Creates config account - let payer = - read_keypair_file(args.payer_keypair_path).expect("Failed reading keypair file ( Payer )"); + let payer = read_keypair_file(args.payer_keypair_path) + .map_err(|e| anyhow!("Failed reading keypair file ( Payer ): {e}"))?; let steward_config = args.steward_config; - let steward_accounts = get_all_steward_accounts(client, &program_id, &steward_config).await?; + let steward_accounts = + get_all_steward_accounts(rpc_client, &program_id, &steward_config).await?; - match steward_accounts.state_account.state.state_tag { - StewardStateEnum::Idle => { /* Continue */ } - _ => { - println!( - "State account is not in Idle state: {}", - steward_accounts.state_account.state.state_tag - ); - return Ok(()); - } + if !matches!( + steward_accounts.state_account.state.state_tag, + StewardStateEnum::Idle + ) { + println!( + "State account is not in Idle state: {}", + steward_accounts.state_account.state.state_tag + ); + return Ok(()); } let ix = Instruction { @@ -53,7 +60,7 @@ pub async fn command_crank_idle( data: jito_steward::instruction::Idle {}.data(), }; - let blockhash = client.get_latest_blockhash().await?; + let blockhash = rpc_client.get_latest_blockhash().await?; let configured_ix = configure_instruction( &[ix], @@ -72,11 +79,31 @@ pub async fn command_crank_idle( if args.transaction_parameters.print_tx { print_base58_tx(&configured_ix) } else { - let signature = client - .send_and_confirm_transaction_with_spinner(&transaction) + let quic_config = QuicConfig::new()?; + let connection_manager = QuicConnectionManager::new_with_connection_config(quic_config); + let tpu_config = TpuClientConfig::default(); + + let tpu_client: QuicTpuClient = TpuClient::new( + "tpu-client", + rpc_client.clone(), + ws_url, + tpu_config, + connection_manager, + ) + .await?; + + let errors = tpu_client + .send_and_confirm_messages_with_spinner(&[transaction.message], &[&payer]) .await?; - println!("Signature: {}", signature); + let mut has_error = false; + for error in errors.into_iter().flatten() { + println!("Error: {error:?}"); + has_error = true; + } + if !has_error { + println!("Transaction confirmed!"); + } } Ok(()) diff --git a/utils/steward-cli/src/main.rs b/utils/steward-cli/src/main.rs index 9eb1bc8b..c208ee5a 100644 --- a/utils/steward-cli/src/main.rs +++ b/utils/steward-cli/src/main.rs @@ -261,7 +261,9 @@ async fn main() -> Result<()> { Commands::ComputeDirectedStakeMeta(args) => { command_crank_compute_directed_stake_meta(args, &client, steward_program_id).await } - Commands::CrankIdle(args) => command_crank_idle(args, &client, steward_program_id).await, + Commands::CrankIdle(command_args) => { + command_crank_idle(command_args, &client, &args.ws_url, steward_program_id).await + } Commands::CrankComputeInstantUnstake(args) => { command_crank_compute_instant_unstake(args, &client, steward_program_id).await }