From b18108392bc7dc5969ba56101f3ee283e428520d Mon Sep 17 00:00:00 2001 From: Jonas Hahn Date: Mon, 28 Oct 2024 13:57:44 +0100 Subject: [PATCH 1/6] Add skip preflight to CLI --- cargo-registry/src/client.rs | 10 ++++ cli/src/clap_app.rs | 7 +++ cli/src/feature.rs | 6 ++- cli/src/main.rs | 3 ++ cli/src/nonce.rs | 30 ++++++++++-- cli/src/program.rs | 34 +++++--------- cli/src/program_v4.rs | 22 +++++---- cli/src/stake.rs | 47 +++++++++++++++---- cli/src/validator_info.rs | 6 ++- cli/src/vote.rs | 36 +++++++++++--- cli/src/wallet.rs | 8 +++- ...nd_and_confirm_transactions_in_parallel.rs | 2 + ...nd_and_confirm_transactions_in_parallel.rs | 19 +++++++- 13 files changed, 176 insertions(+), 54 deletions(-) diff --git a/cargo-registry/src/client.rs b/cargo-registry/src/client.rs index 109b1a8b1975eb..3fad5e5fce961f 100644 --- a/cargo-registry/src/client.rs +++ b/cargo-registry/src/client.rs @@ -12,6 +12,7 @@ use { solana_cli_config::{Config, ConfigInput}, solana_cli_output::OutputFormat, solana_rpc_client::rpc_client::RpcClient, + solana_rpc_client_api::config::RpcSendTransactionConfig, solana_sdk::{ commitment_config, signature::{read_keypair_file, Keypair}, @@ -30,6 +31,7 @@ impl<'a> RPCCommandConfig<'a> { authority: &client.cli_signers[client.authority_signer_index], output_format: &OutputFormat::Display, use_quic: true, + rpc_send_transaction_config: client.rpc_transaction_config, }) } } @@ -42,6 +44,7 @@ pub(crate) struct Client { commitment: commitment_config::CommitmentConfig, cli_signers: Vec, authority_signer_index: SignerIndex, + rpc_transaction_config: RpcSendTransactionConfig, } impl Client { @@ -208,6 +211,8 @@ impl Client { let server_url = value_t!(matches, "server_url", String).unwrap_or(format!("http://0.0.0.0:{}", port)); + let skip_preflight = matches.is_present("skip_preflight"); + Ok(Client { rpc_client: Arc::new(RpcClient::new_with_timeouts_and_commitment( json_rpc_url.to_string(), @@ -221,6 +226,11 @@ impl Client { commitment, cli_signers: vec![payer_keypair, authority_keypair], authority_signer_index: 1, + rpc_transaction_config: RpcSendTransactionConfig { + skip_preflight, + preflight_commitment: Some(commitment.commitment), + ..RpcSendTransactionConfig::default() + }, }) } } diff --git a/cli/src/clap_app.rs b/cli/src/clap_app.rs index 3efe5818ad61fa..cea02f01b9f53a 100644 --- a/cli/src/clap_app.rs +++ b/cli/src/clap_app.rs @@ -14,6 +14,13 @@ pub fn get_clap_app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> A .about(about) .version(version) .setting(AppSettings::SubcommandRequiredElseHelp) + .arg( + Arg::with_name("skip_preflight") + .long("skip-preflight") + .global(true) + .takes_value(false) + .help("Skip the preflight check when sending transactions (default: false)"), + ) .arg({ let arg = Arg::with_name("config_file") .short("C") diff --git a/cli/src/feature.rs b/cli/src/feature.rs index 885cfe03dd6749..0e1fdfd12ab1a4 100644 --- a/cli/src/feature.rs +++ b/cli/src/feature.rs @@ -990,6 +990,10 @@ fn process_activate( FEATURE_NAMES.get(&feature_id).unwrap(), feature_id ); - let result = rpc_client.send_and_confirm_transaction_with_spinner(&transaction); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &transaction, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } diff --git a/cli/src/main.rs b/cli/src/main.rs index 91949eacaa074e..7f49bde7f23cc5 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -212,6 +212,8 @@ pub fn parse_args<'a>( !DEFAULT_TPU_ENABLE_UDP }; + let skip_preflight = matches.is_present("skip_preflight"); + let use_tpu_client = matches.is_present("use_tpu_client"); Ok(( @@ -227,6 +229,7 @@ pub fn parse_args<'a>( output_format, commitment, send_transaction_config: RpcSendTransactionConfig { + skip_preflight, preflight_commitment: Some(commitment.commitment), ..RpcSendTransactionConfig::default() }, diff --git a/cli/src/nonce.rs b/cli/src/nonce.rs index 67b1be0b6e124d..1a8ba54097b757 100644 --- a/cli/src/nonce.rs +++ b/cli/src/nonce.rs @@ -437,7 +437,11 @@ pub fn process_authorize_nonce_account( &tx.message, config.commitment, )?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } @@ -537,7 +541,11 @@ pub fn process_create_nonce_account( let mut tx = Transaction::new_unsigned(message); tx.try_sign(&config.signers, latest_blockhash)?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } @@ -597,7 +605,11 @@ pub fn process_new_nonce( &tx.message, config.commitment, )?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } @@ -667,7 +679,11 @@ pub fn process_withdraw_from_nonce_account( &tx.message, config.commitment, )?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } @@ -697,7 +713,11 @@ pub(crate) fn process_upgrade_nonce_account( &tx.message, config.commitment, )?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } diff --git a/cli/src/program.rs b/cli/src/program.rs index 59d0960d265da2..a72728f4307ddb 100644 --- a/cli/src/program.rs +++ b/cli/src/program.rs @@ -47,7 +47,7 @@ use { solana_rpc_client::rpc_client::RpcClient, solana_rpc_client_api::{ client_error::ErrorKind as ClientErrorKind, - config::{RpcAccountInfoConfig, RpcProgramAccountsConfig, RpcSendTransactionConfig}, + config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, filter::{Memcmp, RpcFilterType}, request::MAX_MULTIPLE_ACCOUNTS, }, @@ -1728,10 +1728,7 @@ fn process_set_authority( .send_and_confirm_transaction_with_spinner_and_config( &tx, config.commitment, - RpcSendTransactionConfig { - preflight_commitment: Some(config.commitment.commitment), - ..RpcSendTransactionConfig::default() - }, + config.send_transaction_config, ) .map_err(|e| format!("Setting authority failed: {e}"))?; @@ -1790,10 +1787,7 @@ fn process_set_authority_checked( .send_and_confirm_transaction_with_spinner_and_config( &tx, config.commitment, - RpcSendTransactionConfig { - preflight_commitment: Some(config.commitment.commitment), - ..RpcSendTransactionConfig::default() - }, + config.send_transaction_config, ) .map_err(|e| format!("Setting authority failed: {e}"))?; @@ -2132,10 +2126,7 @@ fn close( let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( &tx, config.commitment, - RpcSendTransactionConfig { - preflight_commitment: Some(config.commitment.commitment), - ..RpcSendTransactionConfig::default() - }, + config.send_transaction_config, ); if let Err(err) = result { if let ClientErrorKind::TransactionError(TransactionError::InstructionError( @@ -2358,10 +2349,7 @@ fn process_extend_program( let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( &tx, config.commitment, - RpcSendTransactionConfig { - preflight_commitment: Some(config.commitment.commitment), - ..RpcSendTransactionConfig::default() - }, + config.send_transaction_config, ); if let Err(err) = result { if let ClientErrorKind::TransactionError(TransactionError::InstructionError( @@ -2936,7 +2924,11 @@ fn send_deploy_messages( } else { initial_transaction.try_sign(&[fee_payer_signer], blockhash)?; } - let result = rpc_client.send_and_confirm_transaction_with_spinner(&initial_transaction); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &initial_transaction, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) .map_err(|err| format!("Account allocation failed: {err}"))?; } else { @@ -3011,6 +3003,7 @@ fn send_deploy_messages( SendAndConfirmConfig { resign_txs_count: Some(max_sign_attempts), with_spinner: true, + skip_preflight: config.send_transaction_config.skip_preflight, }, ) }, @@ -3046,10 +3039,7 @@ fn send_deploy_messages( .send_and_confirm_transaction_with_spinner_and_config( &final_tx, config.commitment, - RpcSendTransactionConfig { - preflight_commitment: Some(config.commitment.commitment), - ..RpcSendTransactionConfig::default() - }, + config.send_transaction_config, ) .map_err(|e| format!("Deploying program failed: {e}"))?, )); diff --git a/cli/src/program_v4.rs b/cli/src/program_v4.rs index dbe2bbf6f87c0b..9da11348ea37de 100644 --- a/cli/src/program_v4.rs +++ b/cli/src/program_v4.rs @@ -567,6 +567,7 @@ pub struct ProgramV4CommandConfig<'a> { pub authority: &'a dyn Signer, pub output_format: &'a OutputFormat, pub use_quic: bool, + pub rpc_send_transaction_config: RpcSendTransactionConfig, } impl<'a> ProgramV4CommandConfig<'a> { @@ -578,6 +579,7 @@ impl<'a> ProgramV4CommandConfig<'a> { authority: config.signers[*auth_signer_index], output_format: &config.output_format, use_quic: config.use_quic, + rpc_send_transaction_config: config.send_transaction_config, } } } @@ -1014,8 +1016,11 @@ fn send_messages( let mut initial_transaction = Transaction::new_unsigned(message.clone()); initial_transaction .try_sign(&[config.payer, initial_signer, config.authority], blockhash)?; - let result = - rpc_client.send_and_confirm_transaction_with_spinner(&initial_transaction); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &initial_transaction, + config.commitment, + config.rpc_send_transaction_config, + ); log_instruction_custom_error_ex::( result, config.output_format, @@ -1031,7 +1036,11 @@ fn send_messages( let mut initial_transaction = Transaction::new_unsigned(message.clone()); initial_transaction.try_sign(&[config.payer, config.authority], blockhash)?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&initial_transaction); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &initial_transaction, + config.commitment, + config.rpc_send_transaction_config, + ); log_instruction_custom_error_ex::( result, config.output_format, @@ -1082,6 +1091,7 @@ fn send_messages( SendAndConfirmConfig { resign_txs_count: Some(5), with_spinner: true, + skip_preflight: config.rpc_send_transaction_config.skip_preflight, }, ) } @@ -1107,11 +1117,7 @@ fn send_messages( .send_and_confirm_transaction_with_spinner_and_config( &final_tx, config.commitment, - RpcSendTransactionConfig { - skip_preflight: true, - preflight_commitment: Some(config.commitment.commitment), - ..RpcSendTransactionConfig::default() - }, + config.rpc_send_transaction_config, ) .map_err(|e| format!("Deploying program failed: {e}"))?; } diff --git a/cli/src/stake.rs b/cli/src/stake.rs index 9fefb818aee3a9..b08a29371da064 100644 --- a/cli/src/stake.rs +++ b/cli/src/stake.rs @@ -1530,7 +1530,11 @@ pub fn process_create_stake_account( ) } else { tx.try_sign(&config.signers, recent_blockhash)?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } } @@ -1671,9 +1675,16 @@ pub fn process_stake_authorize( config.commitment, )?; let result = if no_wait { - rpc_client.send_transaction(&tx) + rpc_client.send_transaction_with_config( + &tx, + config.send_transaction_config, + ) } else { - rpc_client.send_and_confirm_transaction_with_spinner(&tx) + rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ) }; log_instruction_custom_error::(result, config) } @@ -1821,7 +1832,11 @@ pub fn process_deactivate_stake_account( &tx.message, config.commitment, )?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } } @@ -1928,7 +1943,11 @@ pub fn process_withdraw_stake( &tx.message, config.commitment, )?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } } @@ -2120,7 +2139,11 @@ pub fn process_split_stake( &tx.message, config.commitment, )?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } } @@ -2337,7 +2360,11 @@ pub fn process_stake_set_lockup( &tx.message, config.commitment, )?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } } @@ -2820,7 +2847,11 @@ pub fn process_delegate_stake( &tx.message, config.commitment, )?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } } diff --git a/cli/src/validator_info.rs b/cli/src/validator_info.rs index 296c85d99f300a..1f8f8b7cb118e1 100644 --- a/cli/src/validator_info.rs +++ b/cli/src/validator_info.rs @@ -408,7 +408,11 @@ pub fn process_set_validator_info( )?; let mut tx = Transaction::new_unsigned(message); tx.try_sign(&signers, latest_blockhash)?; - let signature_str = rpc_client.send_and_confirm_transaction_with_spinner(&tx)?; + let signature_str = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + )?; println!("Success! Validator info published at: {info_pubkey:?}"); println!("{signature_str}"); diff --git a/cli/src/vote.rs b/cli/src/vote.rs index ab9a4897342b24..88a44cc6bb0c10 100644 --- a/cli/src/vote.rs +++ b/cli/src/vote.rs @@ -932,7 +932,11 @@ pub fn process_create_vote_account( ) } else { tx.try_sign(&config.signers, recent_blockhash)?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } } @@ -1071,7 +1075,11 @@ pub fn process_vote_authorize( &tx.message, config.commitment, )?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } } @@ -1155,7 +1163,11 @@ pub fn process_vote_update_validator( &tx.message, config.commitment, )?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } } @@ -1232,7 +1244,11 @@ pub fn process_vote_update_commission( &tx.message, config.commitment, )?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } } @@ -1440,7 +1456,11 @@ pub fn process_withdraw_from_vote_account( &tx.message, config.commitment, )?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } } @@ -1504,7 +1524,11 @@ pub fn process_close_vote_account( &tx.message, config.commitment, )?; - let result = rpc_client.send_and_confirm_transaction_with_spinner(&tx); + let result = rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ); log_instruction_custom_error::(result, config) } diff --git a/cli/src/wallet.rs b/cli/src/wallet.rs index 728a529af246c9..304e77fc7aa268 100644 --- a/cli/src/wallet.rs +++ b/cli/src/wallet.rs @@ -986,9 +986,13 @@ pub fn process_transfer( tx.try_sign(&config.signers, recent_blockhash)?; let result = if no_wait { - rpc_client.send_transaction(&tx) + rpc_client.send_transaction_with_config(&tx, config.send_transaction_config) } else { - rpc_client.send_and_confirm_transaction_with_spinner(&tx) + rpc_client.send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, + ) }; log_instruction_custom_error::(result, config) } diff --git a/client-test/tests/send_and_confirm_transactions_in_parallel.rs b/client-test/tests/send_and_confirm_transactions_in_parallel.rs index 0373d38eb51999..07c43ab716ea7d 100644 --- a/client-test/tests/send_and_confirm_transactions_in_parallel.rs +++ b/client-test/tests/send_and_confirm_transactions_in_parallel.rs @@ -59,6 +59,7 @@ fn test_send_and_confirm_transactions_in_parallel_without_tpu_client() { SendAndConfirmConfig { with_spinner: false, resign_txs_count: Some(5), + skip_preflight: false, }, ); assert!(txs_errors.is_ok()); @@ -117,6 +118,7 @@ fn test_send_and_confirm_transactions_in_parallel_with_tpu_client() { SendAndConfirmConfig { with_spinner: false, resign_txs_count: Some(5), + skip_preflight: false, }, ); assert!(txs_errors.is_ok()); diff --git a/client/src/send_and_confirm_transactions_in_parallel.rs b/client/src/send_and_confirm_transactions_in_parallel.rs index 571e3566a4782a..4c8e6bc4fcbbb6 100644 --- a/client/src/send_and_confirm_transactions_in_parallel.rs +++ b/client/src/send_and_confirm_transactions_in_parallel.rs @@ -10,12 +10,14 @@ use { solana_rpc_client::spinner::{self, SendTransactionProgress}, solana_rpc_client_api::{ client_error::ErrorKind, + config::RpcSendTransactionConfig, request::{RpcError, RpcResponseErrorData, MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS}, response::RpcSimulateTransactionResult, }, solana_sdk::{ hash::Hash, message::Message, + msg, signature::{Signature, SignerError}, signers::Signers, transaction::{Transaction, TransactionError}, @@ -58,6 +60,7 @@ struct BlockHashData { pub struct SendAndConfirmConfig { pub with_spinner: bool, pub resign_txs_count: Option, + pub skip_preflight: bool, } /// Sends and confirms transactions concurrently in a sync context @@ -195,6 +198,7 @@ async fn send_transaction_with_rpc_fallback( serialized_transaction: Vec, context: &SendingContext, index: usize, + skip_preflight: bool, ) -> Result<()> { let send_over_rpc = if let Some(tpu_client) = tpu_client { !tokio::time::timeout( @@ -206,8 +210,18 @@ async fn send_transaction_with_rpc_fallback( } else { true }; + //println!("skipPreflight: {}", skip_preflight); if send_over_rpc { - if let Err(e) = rpc_client.send_transaction(&transaction).await { + if let Err(e) = rpc_client + .send_transaction_with_config( + &transaction, + RpcSendTransactionConfig { + skip_preflight, + ..RpcSendTransactionConfig::default() + }, + ) + .await + { match &e.kind { ErrorKind::Io(_) | ErrorKind::Reqwest(_) => { // fall through on io error, we will retry the transaction @@ -255,6 +269,7 @@ async fn sign_all_messages_and_send( messages_with_index: Vec<(usize, Message)>, signers: &T, context: &SendingContext, + skip_preflight: bool, ) -> Result<()> { let current_transaction_count = messages_with_index.len(); let mut futures = vec![]; @@ -304,6 +319,7 @@ async fn sign_all_messages_and_send( serialized_transaction, context, *index, + skip_preflight, ) .await }); @@ -512,6 +528,7 @@ pub async fn send_and_confirm_transactions_in_parallel( messages_with_index, signers, &context, + config.skip_preflight, ) .await?; confirm_transactions_till_block_height_and_resend_unexpired_transaction_over_tpu( From 68a1b131f96d4f44fcae9011196756d09cd552c6 Mon Sep 17 00:00:00 2001 From: Jonas Hahn Date: Tue, 29 Oct 2024 00:17:02 +0100 Subject: [PATCH 2/6] Adjust tests for skip preflight The tests had skip_preflight set to true by default. But the value was not actually used. Now it is, so i adjusted the tests. --- cli/src/stake.rs | 5 +- cli/tests/program.rs | 94 +++++++++++++------ ...nd_and_confirm_transactions_in_parallel.rs | 3 +- 3 files changed, 67 insertions(+), 35 deletions(-) diff --git a/cli/src/stake.rs b/cli/src/stake.rs index b08a29371da064..20d6d8d1461c45 100644 --- a/cli/src/stake.rs +++ b/cli/src/stake.rs @@ -1675,10 +1675,7 @@ pub fn process_stake_authorize( config.commitment, )?; let result = if no_wait { - rpc_client.send_transaction_with_config( - &tx, - config.send_transaction_config, - ) + rpc_client.send_transaction_with_config(&tx, config.send_transaction_config) } else { rpc_client.send_and_confirm_transaction_with_spinner_and_config( &tx, diff --git a/cli/tests/program.rs b/cli/tests/program.rs index 4be0354b7430e6..fcf206e58d5573 100644 --- a/cli/tests/program.rs +++ b/cli/tests/program.rs @@ -11,6 +11,7 @@ use { test_utils::wait_n_slots, }, solana_cli_output::{parse_sign_only_reply_string, OutputFormat}, + solana_client::rpc_config::RpcSendTransactionConfig, solana_faucet::faucet::run_local_faucet, solana_feature_set::enable_alt_bn128_syscall, solana_rpc::rpc::JsonRpcConfig, @@ -379,9 +380,11 @@ fn test_cli_program_deploy_no_authority() { ); } -#[test_case(true; "Feature enabled")] -#[test_case(false; "Feature disabled")] -fn test_cli_program_deploy_feature(enable_feature: bool) { +#[test_case(true, true; "Feature enabled, skip preflight")] +#[test_case(true, false; "Feature enabled, don't skip preflight")] +#[test_case(false, true; "Feature disabled, skip preflight")] +#[test_case(false, false; "Feature disabled, don't skip preflight")] +fn test_cli_program_deploy_feature(enable_feature: bool, skip_preflight: bool) { solana_logger::setup(); let mut program_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); @@ -438,6 +441,7 @@ fn test_cli_program_deploy_feature(enable_feature: bool) { lamports: 100 * minimum_balance_for_programdata + minimum_balance_for_program, }; config.signers = vec![&keypair]; + config.send_transaction_config.skip_preflight = skip_preflight; process_command(&config).unwrap(); config.signers = vec![&keypair, &upgrade_authority]; @@ -465,10 +469,10 @@ fn test_cli_program_deploy_feature(enable_feature: bool) { assert!(res.is_ok()); } else { expect_command_failure( - &config, - "Program contains a syscall from a deactivated feature", - "ELF error: ELF error: Unresolved symbol (sol_alt_bn128_group_op) at instruction #49 (ELF file offset 0x188)" - ); + &config, + "Program contains a syscall from a deactivated feature", + "ELF error: ELF error: Unresolved symbol (sol_alt_bn128_group_op) at instruction #49 (ELF file offset 0x188)" + ); // If we bypass the verification, there should be no error config.command = CliCommand::Program(ProgramCliCommand::Deploy { @@ -491,11 +495,19 @@ fn test_cli_program_deploy_feature(enable_feature: bool) { // When we skip verification, we fail at a later stage let response = process_command(&config); - assert!(response - .err() - .unwrap() - .to_string() - .contains("Deploying program failed: RPC response error -32002:")); + if skip_preflight { + assert!(response + .err() + .unwrap() + .to_string() + .contains("Deploying program failed")); + } else { + assert!(response + .err() + .unwrap() + .to_string() + .contains("Deploying program failed: RPC response error -32002:")); + } } } @@ -1069,8 +1081,9 @@ fn test_cli_program_deploy_with_authority() { assert_eq!("none", authority_pubkey_str); } -#[test] -fn test_cli_program_upgrade_auto_extend() { +#[test_case(true; "Skip preflight")] +#[test_case(false; "Dont skip preflight")] +fn test_cli_program_upgrade_auto_extend(skip_preflight: bool) { solana_logger::setup(); let mut noop_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); @@ -1148,6 +1161,7 @@ fn test_cli_program_upgrade_auto_extend() { skip_feature_verification: true, }); config.output_format = OutputFormat::JsonCompact; + config.send_transaction_config.skip_preflight = skip_preflight; process_command(&config).unwrap(); // Attempt to upgrade the program with a larger program, but with the @@ -1170,18 +1184,26 @@ fn test_cli_program_upgrade_auto_extend() { use_rpc: false, skip_feature_verification: true, }); - expect_command_failure( - &config, - "Can not upgrade a program when ELF does not fit into the allocated data account", - "Deploying program failed: \ - RPC response error -32002: \ - Transaction simulation failed: \ - Error processing Instruction 0: \ - account data too small for instruction; 3 log messages:\n \ - Program BPFLoaderUpgradeab1e11111111111111111111111 invoke [1]\n \ - ProgramData account not large enough\n \ - Program BPFLoaderUpgradeab1e11111111111111111111111 failed: account data too small for instruction\n", - ); + if skip_preflight { + expect_command_failure( + &config, + "Cannot upgrade a program when ELF does not fit into the allocated data account", + "Deploying program failed: Error processing Instruction 0: account data too small for instruction", + ); + } else { + expect_command_failure( + &config, + "Can not upgrade a program when ELF does not fit into the allocated data account", + "Deploying program failed: \ + RPC response error -32002: \ + Transaction simulation failed: \ + Error processing Instruction 0: \ + account data too small for instruction; 3 log messages:\n \ + Program BPFLoaderUpgradeab1e11111111111111111111111 invoke [1]\n \ + ProgramData account not large enough\n \ + Program BPFLoaderUpgradeab1e11111111111111111111111 failed: account data too small for instruction\n", + ); + } // Attempt to upgrade the program with a larger program, this time without // the --no-auto-extend flag. This should automatically extend the program data. @@ -1347,8 +1369,9 @@ fn test_cli_program_close_program() { assert_eq!(programdata_lamports, recipient_account.lamports); } -#[test] -fn test_cli_program_extend_program() { +#[test_case(true; "Skip Preflight")] +#[test_case(false; "Dont skip Preflight")] +fn test_cli_program_extend_program_skip_preflight(skip_preflight: bool) { solana_logger::setup(); let mut noop_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); @@ -1397,6 +1420,11 @@ fn test_cli_program_extend_program() { pubkey: None, lamports: 100 * minimum_balance_for_programdata + minimum_balance_for_program, }; + config.send_transaction_config = RpcSendTransactionConfig { + skip_preflight: skip_preflight, + preflight_commitment: Some(CommitmentConfig::processed().commitment), + ..RpcSendTransactionConfig::default() + }; process_command(&config).unwrap(); // Deploy an upgradeable program @@ -1470,7 +1498,14 @@ fn test_cli_program_extend_program() { use_rpc: false, skip_feature_verification: true, }); - expect_command_failure( + if skip_preflight { + expect_command_failure( + &config, + "Program upgrade must fail, as the buffer is 1 byte too short", + "Deploying program failed: Error processing Instruction 0: account data too small for instruction", + ); + } else { + expect_command_failure( &config, "Program upgrade must fail, as the buffer is 1 byte too short", "Deploying program failed: \ @@ -1482,6 +1517,7 @@ fn test_cli_program_extend_program() { ProgramData account not large enough\n \ Program BPFLoaderUpgradeab1e11111111111111111111111 failed: account data too small for instruction\n", ); + } // Wait one slot to avoid "Program was deployed in this block already" error wait_n_slots(&rpc_client, 1); diff --git a/client/src/send_and_confirm_transactions_in_parallel.rs b/client/src/send_and_confirm_transactions_in_parallel.rs index 4c8e6bc4fcbbb6..d2d3a25ae842db 100644 --- a/client/src/send_and_confirm_transactions_in_parallel.rs +++ b/client/src/send_and_confirm_transactions_in_parallel.rs @@ -17,7 +17,6 @@ use { solana_sdk::{ hash::Hash, message::Message, - msg, signature::{Signature, SignerError}, signers::Signers, transaction::{Transaction, TransactionError}, @@ -210,13 +209,13 @@ async fn send_transaction_with_rpc_fallback( } else { true }; - //println!("skipPreflight: {}", skip_preflight); if send_over_rpc { if let Err(e) = rpc_client .send_transaction_with_config( &transaction, RpcSendTransactionConfig { skip_preflight, + preflight_commitment: Some(rpc_client.commitment().commitment), ..RpcSendTransactionConfig::default() }, ) From 9b802c5d3338041126cf879a01dae090470495e4 Mon Sep 17 00:00:00 2001 From: Jonas Hahn Date: Tue, 29 Oct 2024 15:20:44 +0100 Subject: [PATCH 3/6] Add skip preflight to transfer + tests --- cli/tests/transfer.rs | 12 ++++++++---- rpc-client/src/nonblocking/rpc_client.rs | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/cli/tests/transfer.rs b/cli/tests/transfer.rs index b1a750972543e1..378f758717c54f 100644 --- a/cli/tests/transfer.rs +++ b/cli/tests/transfer.rs @@ -26,8 +26,9 @@ use { test_case::test_case, }; -#[test] -fn test_transfer() { +#[test_case(true; "Skip Preflight")] +#[test_case(false; "Don`t skip Preflight")] +fn test_transfer(skip_preflight: bool) { solana_logger::setup(); let fee_one_sig = FeeStructure::default().get_max_fee(1, 0); let fee_two_sig = FeeStructure::default().get_max_fee(2, 0); @@ -50,6 +51,7 @@ fn test_transfer() { let mut config = CliConfig::recent_for_tests(); config.json_rpc_url = test_validator.rpc_url(); config.signers = vec![&default_signer]; + config.send_transaction_config.skip_preflight = skip_preflight; let sender_pubkey = config.signers[0].pubkey(); let recipient_pubkey = Pubkey::from([1u8; 32]); @@ -556,8 +558,9 @@ fn test_transfer_all(compute_unit_price: Option) { check_balance!(500_000 - fee, &rpc_client, &recipient_pubkey); } -#[test] -fn test_transfer_unfunded_recipient() { +#[test_case(true; "Skip Preflight")] +#[test_case(false; "Don`t skip Preflight")] +fn test_transfer_unfunded_recipient(skip_preflight: bool) { solana_logger::setup(); let mint_keypair = Keypair::new(); let mint_pubkey = mint_keypair.pubkey(); @@ -577,6 +580,7 @@ fn test_transfer_unfunded_recipient() { let mut config = CliConfig::recent_for_tests(); config.json_rpc_url = test_validator.rpc_url(); config.signers = vec![&default_signer]; + config.send_transaction_config.skip_preflight = skip_preflight; let sender_pubkey = config.signers[0].pubkey(); let recipient_pubkey = Pubkey::from([1u8; 32]); diff --git a/rpc-client/src/nonblocking/rpc_client.rs b/rpc-client/src/nonblocking/rpc_client.rs index b72b4a5d74a9c5..7f684d87d22165 100644 --- a/rpc-client/src/nonblocking/rpc_client.rs +++ b/rpc-client/src/nonblocking/rpc_client.rs @@ -868,6 +868,7 @@ impl RpcClient { }; let config = RpcSendTransactionConfig { encoding: Some(encoding), + skip_preflight: config.skip_preflight, preflight_commitment: Some(preflight_commitment.commitment), ..config }; From ff321023b15ea9d6d00d35f68f06d54ec32c1f79 Mon Sep 17 00:00:00 2001 From: Jonas Hahn Date: Tue, 5 Nov 2024 19:55:32 +0100 Subject: [PATCH 4/6] Non breaking in parallel + remove test cases --- cargo-registry/src/client.rs | 7 ++ cli/src/clap_app.rs | 2 +- cli/src/program.rs | 14 ++-- cli/src/program_v4.rs | 9 ++- cli/tests/program.rs | 19 ++--- cli/tests/transfer.rs | 7 +- ...nd_and_confirm_transactions_in_parallel.rs | 27 +++++-- ...nd_and_confirm_transactions_in_parallel.rs | 73 ++++++++++++++++--- rpc-client/src/nonblocking/rpc_client.rs | 1 - 9 files changed, 113 insertions(+), 46 deletions(-) diff --git a/cargo-registry/src/client.rs b/cargo-registry/src/client.rs index 3fad5e5fce961f..faad91479f3dbc 100644 --- a/cargo-registry/src/client.rs +++ b/cargo-registry/src/client.rs @@ -67,6 +67,13 @@ impl Client { App::new(name) .about(about) .version(version) + .arg( + Arg::with_name("skip_preflight") + .long("skip-preflight") + .global(true) + .takes_value(false) + .help("Skip the preflight check when sending transactions"), + ) .arg( Arg::with_name("config_file") .short("C") diff --git a/cli/src/clap_app.rs b/cli/src/clap_app.rs index cea02f01b9f53a..3f62ba48abb323 100644 --- a/cli/src/clap_app.rs +++ b/cli/src/clap_app.rs @@ -19,7 +19,7 @@ pub fn get_clap_app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> A .long("skip-preflight") .global(true) .takes_value(false) - .help("Skip the preflight check when sending transactions (default: false)"), + .help("Skip the preflight check when sending transactions"), ) .arg({ let arg = Arg::with_name("config_file") diff --git a/cli/src/program.rs b/cli/src/program.rs index a72728f4307ddb..878b26c6520f10 100644 --- a/cli/src/program.rs +++ b/cli/src/program.rs @@ -35,7 +35,8 @@ use { solana_client::{ connection_cache::ConnectionCache, send_and_confirm_transactions_in_parallel::{ - send_and_confirm_transactions_in_parallel_blocking, SendAndConfirmConfig, + send_and_confirm_transactions_in_parallel_blocking_v2, + SendAndConfirmConfigV2, }, tpu_client::{TpuClient, TpuClientConfig}, }, @@ -1575,7 +1576,10 @@ fn process_program_upgrade( let signers = &[fee_payer_signer, upgrade_authority_signer]; tx.try_sign(signers, blockhash)?; let final_tx_sig = rpc_client - .send_and_confirm_transaction_with_spinner(&tx) + .send_and_confirm_transaction_with_spinner_and_config(&tx, + config.commitment, + config.send_transaction_config + ) .map_err(|e| format!("Upgrading program failed: {e}"))?; let program_id = CliProgramId { program_id: program_id.to_string(), @@ -2995,15 +2999,15 @@ fn send_deploy_messages( .expect("Should return a valid tpu client") ); - send_and_confirm_transactions_in_parallel_blocking( + send_and_confirm_transactions_in_parallel_blocking_v2( rpc_client.clone(), tpu_client, &write_messages, &[fee_payer_signer, write_signer], - SendAndConfirmConfig { + SendAndConfirmConfigV2 { resign_txs_count: Some(max_sign_attempts), with_spinner: true, - skip_preflight: config.send_transaction_config.skip_preflight, + rpc_send_transaction_config: config.send_transaction_config, }, ) }, diff --git a/cli/src/program_v4.rs b/cli/src/program_v4.rs index 9da11348ea37de..63c427bcef7ba1 100644 --- a/cli/src/program_v4.rs +++ b/cli/src/program_v4.rs @@ -20,7 +20,8 @@ use { solana_client::{ connection_cache::ConnectionCache, send_and_confirm_transactions_in_parallel::{ - send_and_confirm_transactions_in_parallel_blocking, SendAndConfirmConfig, + send_and_confirm_transactions_in_parallel_blocking_v2, + SendAndConfirmConfigV2, }, tpu_client::{TpuClient, TpuClientConfig}, }, @@ -1083,15 +1084,15 @@ fn send_messages( .block_on(tpu_client_fut) .expect("Should return a valid tpu client"); - send_and_confirm_transactions_in_parallel_blocking( + send_and_confirm_transactions_in_parallel_blocking_v2( rpc_client.clone(), Some(tpu_client), write_messages, &[config.payer, config.authority], - SendAndConfirmConfig { + SendAndConfirmConfigV2 { resign_txs_count: Some(5), with_spinner: true, - skip_preflight: config.rpc_send_transaction_config.skip_preflight, + rpc_send_transaction_config: config.rpc_send_transaction_config, }, ) } diff --git a/cli/tests/program.rs b/cli/tests/program.rs index fcf206e58d5573..b2ed10700c6567 100644 --- a/cli/tests/program.rs +++ b/cli/tests/program.rs @@ -569,6 +569,7 @@ fn test_cli_program_upgrade_with_feature(enable_feature: bool) { let mut config = CliConfig::recent_for_tests(); config.json_rpc_url = test_validator.rpc_url(); + config.send_transaction_config.skip_preflight = false; let online_signer = Keypair::new(); let offline_signer = Keypair::new(); @@ -1369,9 +1370,8 @@ fn test_cli_program_close_program() { assert_eq!(programdata_lamports, recipient_account.lamports); } -#[test_case(true; "Skip Preflight")] -#[test_case(false; "Dont skip Preflight")] -fn test_cli_program_extend_program_skip_preflight(skip_preflight: bool) { +#[test] +fn test_cli_program_extend_program() { solana_logger::setup(); let mut noop_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); @@ -1421,7 +1421,7 @@ fn test_cli_program_extend_program_skip_preflight(skip_preflight: bool) { lamports: 100 * minimum_balance_for_programdata + minimum_balance_for_program, }; config.send_transaction_config = RpcSendTransactionConfig { - skip_preflight: skip_preflight, + skip_preflight: false, preflight_commitment: Some(CommitmentConfig::processed().commitment), ..RpcSendTransactionConfig::default() }; @@ -1498,14 +1498,8 @@ fn test_cli_program_extend_program_skip_preflight(skip_preflight: bool) { use_rpc: false, skip_feature_verification: true, }); - if skip_preflight { - expect_command_failure( - &config, - "Program upgrade must fail, as the buffer is 1 byte too short", - "Deploying program failed: Error processing Instruction 0: account data too small for instruction", - ); - } else { - expect_command_failure( + + expect_command_failure( &config, "Program upgrade must fail, as the buffer is 1 byte too short", "Deploying program failed: \ @@ -1517,7 +1511,6 @@ fn test_cli_program_extend_program_skip_preflight(skip_preflight: bool) { ProgramData account not large enough\n \ Program BPFLoaderUpgradeab1e11111111111111111111111 failed: account data too small for instruction\n", ); - } // Wait one slot to avoid "Program was deployed in this block already" error wait_n_slots(&rpc_client, 1); diff --git a/cli/tests/transfer.rs b/cli/tests/transfer.rs index 378f758717c54f..dead746ae3e6c0 100644 --- a/cli/tests/transfer.rs +++ b/cli/tests/transfer.rs @@ -558,9 +558,8 @@ fn test_transfer_all(compute_unit_price: Option) { check_balance!(500_000 - fee, &rpc_client, &recipient_pubkey); } -#[test_case(true; "Skip Preflight")] -#[test_case(false; "Don`t skip Preflight")] -fn test_transfer_unfunded_recipient(skip_preflight: bool) { +#[test] +fn test_transfer_unfunded_recipient() { solana_logger::setup(); let mint_keypair = Keypair::new(); let mint_pubkey = mint_keypair.pubkey(); @@ -580,7 +579,7 @@ fn test_transfer_unfunded_recipient(skip_preflight: bool) { let mut config = CliConfig::recent_for_tests(); config.json_rpc_url = test_validator.rpc_url(); config.signers = vec![&default_signer]; - config.send_transaction_config.skip_preflight = skip_preflight; + config.send_transaction_config.skip_preflight = false; let sender_pubkey = config.signers[0].pubkey(); let recipient_pubkey = Pubkey::from([1u8; 32]); diff --git a/client-test/tests/send_and_confirm_transactions_in_parallel.rs b/client-test/tests/send_and_confirm_transactions_in_parallel.rs index 07c43ab716ea7d..f083f1f2737554 100644 --- a/client-test/tests/send_and_confirm_transactions_in_parallel.rs +++ b/client-test/tests/send_and_confirm_transactions_in_parallel.rs @@ -1,8 +1,9 @@ use { solana_client::{ nonblocking::tpu_client::TpuClient, + rpc_config::RpcSendTransactionConfig, send_and_confirm_transactions_in_parallel::{ - send_and_confirm_transactions_in_parallel_blocking, SendAndConfirmConfig, + send_and_confirm_transactions_in_parallel_blocking_v2, SendAndConfirmConfigV2, }, }, solana_rpc_client::rpc_client::RpcClient, @@ -51,15 +52,21 @@ fn test_send_and_confirm_transactions_in_parallel_without_tpu_client() { let original_alice_balance = rpc_client.get_balance(&alice.pubkey()).unwrap(); let (messages, sum) = create_messages(alice_pubkey, bob_pubkey); - let txs_errors = send_and_confirm_transactions_in_parallel_blocking( + let txs_errors = send_and_confirm_transactions_in_parallel_blocking_v2( rpc_client.clone(), None, &messages, &[&alice], - SendAndConfirmConfig { + SendAndConfirmConfigV2 { with_spinner: false, resign_txs_count: Some(5), - skip_preflight: false, + rpc_send_transaction_config: RpcSendTransactionConfig { + skip_preflight: false, + preflight_commitment: Some(CommitmentConfig::confirmed().commitment), + encoding: None, + max_retries: None, + min_context_slot: None, + }, }, ); assert!(txs_errors.is_ok()); @@ -110,15 +117,21 @@ fn test_send_and_confirm_transactions_in_parallel_with_tpu_client() { ); let tpu_client = rpc_client.runtime().block_on(tpu_client_fut).unwrap(); - let txs_errors = send_and_confirm_transactions_in_parallel_blocking( + let txs_errors = send_and_confirm_transactions_in_parallel_blocking_v2( rpc_client.clone(), Some(tpu_client), &messages, &[&alice], - SendAndConfirmConfig { + SendAndConfirmConfigV2 { with_spinner: false, resign_txs_count: Some(5), - skip_preflight: false, + rpc_send_transaction_config: RpcSendTransactionConfig { + skip_preflight: false, + preflight_commitment: Some(CommitmentConfig::confirmed().commitment), + encoding: None, + max_retries: None, + min_context_slot: None, + }, }, ); assert!(txs_errors.is_ok()); diff --git a/client/src/send_and_confirm_transactions_in_parallel.rs b/client/src/send_and_confirm_transactions_in_parallel.rs index d2d3a25ae842db..61003b84c315d0 100644 --- a/client/src/send_and_confirm_transactions_in_parallel.rs +++ b/client/src/send_and_confirm_transactions_in_parallel.rs @@ -55,14 +55,45 @@ struct BlockHashData { pub last_valid_block_height: u64, } +// Deprecated struct to maintain backward compatibility +#[deprecated(note = "Use SendAndConfirmConfigV2 with send_and_confirm_transactions_in_parallel_v2")] #[derive(Clone, Debug, Copy)] pub struct SendAndConfirmConfig { pub with_spinner: bool, pub resign_txs_count: Option, - pub skip_preflight: bool, } -/// Sends and confirms transactions concurrently in a sync context +// New struct with RpcSendTransactionConfig for non-breaking change +#[derive(Clone, Debug, Copy)] +pub struct SendAndConfirmConfigV2 { + pub with_spinner: bool, + pub resign_txs_count: Option, + pub rpc_send_transaction_config: RpcSendTransactionConfig, +} + +#[deprecated(note = "Use send_and_confirm_transactions_in_parallel_v2")] +pub async fn send_and_confirm_transactions_in_parallel( + rpc_client: Arc, + tpu_client: Option, + messages: &[Message], + signers: &T, + config: SendAndConfirmConfig, +) -> Result>> { + let config_v2 = SendAndConfirmConfigV2 { + with_spinner: config.with_spinner, + resign_txs_count: config.resign_txs_count, + rpc_send_transaction_config: RpcSendTransactionConfig { + skip_preflight: false, + ..RpcSendTransactionConfig::default() + }, + }; + send_and_confirm_transactions_in_parallel_v2( + rpc_client, tpu_client, messages, signers, config_v2, + ) + .await +} + +#[deprecated(note = "Use send_and_confirm_transactions_in_parallel_blocking_v2")] pub fn send_and_confirm_transactions_in_parallel_blocking( rpc_client: Arc, tpu_client: Option, @@ -70,7 +101,28 @@ pub fn send_and_confirm_transactions_in_parallel_blocking( signers: &T, config: SendAndConfirmConfig, ) -> Result>> { - let fut = send_and_confirm_transactions_in_parallel( + let config_v2 = SendAndConfirmConfigV2 { + with_spinner: config.with_spinner, + resign_txs_count: config.resign_txs_count, + rpc_send_transaction_config: RpcSendTransactionConfig { + skip_preflight: false, + ..RpcSendTransactionConfig::default() + }, + }; + send_and_confirm_transactions_in_parallel_blocking_v2( + rpc_client, tpu_client, messages, signers, config_v2, + ) +} + +/// Sends and confirms transactions concurrently in a sync context +pub fn send_and_confirm_transactions_in_parallel_blocking_v2( + rpc_client: Arc, + tpu_client: Option, + messages: &[Message], + signers: &T, + config: SendAndConfirmConfigV2, +) -> Result>> { + let fut = send_and_confirm_transactions_in_parallel_v2( rpc_client.get_inner_client().clone(), tpu_client, messages, @@ -197,7 +249,7 @@ async fn send_transaction_with_rpc_fallback( serialized_transaction: Vec, context: &SendingContext, index: usize, - skip_preflight: bool, + rpc_send_transaction_config: RpcSendTransactionConfig, ) -> Result<()> { let send_over_rpc = if let Some(tpu_client) = tpu_client { !tokio::time::timeout( @@ -214,9 +266,8 @@ async fn send_transaction_with_rpc_fallback( .send_transaction_with_config( &transaction, RpcSendTransactionConfig { - skip_preflight, preflight_commitment: Some(rpc_client.commitment().commitment), - ..RpcSendTransactionConfig::default() + ..rpc_send_transaction_config }, ) .await @@ -268,7 +319,7 @@ async fn sign_all_messages_and_send( messages_with_index: Vec<(usize, Message)>, signers: &T, context: &SendingContext, - skip_preflight: bool, + rpc_send_transaction_config: RpcSendTransactionConfig, ) -> Result<()> { let current_transaction_count = messages_with_index.len(); let mut futures = vec![]; @@ -318,7 +369,7 @@ async fn sign_all_messages_and_send( serialized_transaction, context, *index, - skip_preflight, + rpc_send_transaction_config, ) .await }); @@ -433,12 +484,12 @@ async fn send_staggered_transactions( /// The sending and confirmation of transactions is done in parallel tasks /// The method signs transactions just before sending so that blockhash does not /// expire. -pub async fn send_and_confirm_transactions_in_parallel( +pub async fn send_and_confirm_transactions_in_parallel_v2( rpc_client: Arc, tpu_client: Option, messages: &[Message], signers: &T, - config: SendAndConfirmConfig, + config: SendAndConfirmConfigV2, ) -> Result>> { // get current blockhash and corresponding last valid block height let (blockhash, last_valid_block_height) = rpc_client @@ -527,7 +578,7 @@ pub async fn send_and_confirm_transactions_in_parallel( messages_with_index, signers, &context, - config.skip_preflight, + config.rpc_send_transaction_config, ) .await?; confirm_transactions_till_block_height_and_resend_unexpired_transaction_over_tpu( diff --git a/rpc-client/src/nonblocking/rpc_client.rs b/rpc-client/src/nonblocking/rpc_client.rs index 7f684d87d22165..b72b4a5d74a9c5 100644 --- a/rpc-client/src/nonblocking/rpc_client.rs +++ b/rpc-client/src/nonblocking/rpc_client.rs @@ -868,7 +868,6 @@ impl RpcClient { }; let config = RpcSendTransactionConfig { encoding: Some(encoding), - skip_preflight: config.skip_preflight, preflight_commitment: Some(preflight_commitment.commitment), ..config }; From 9d6d3334e6bacad3c07df427520c99cf449ace44 Mon Sep 17 00:00:00 2001 From: Jonas Hahn Date: Wed, 6 Nov 2024 11:52:19 +0100 Subject: [PATCH 5/6] Add deprecated since + fmt and lint --- cli/src/program.rs | 10 +++++----- cli/src/program_v4.rs | 3 +-- ...nd_and_confirm_transactions_in_parallel.rs | 20 ++++++++++++++----- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/cli/src/program.rs b/cli/src/program.rs index 878b26c6520f10..bed71f96470474 100644 --- a/cli/src/program.rs +++ b/cli/src/program.rs @@ -35,8 +35,7 @@ use { solana_client::{ connection_cache::ConnectionCache, send_and_confirm_transactions_in_parallel::{ - send_and_confirm_transactions_in_parallel_blocking_v2, - SendAndConfirmConfigV2, + send_and_confirm_transactions_in_parallel_blocking_v2, SendAndConfirmConfigV2, }, tpu_client::{TpuClient, TpuClientConfig}, }, @@ -1576,9 +1575,10 @@ fn process_program_upgrade( let signers = &[fee_payer_signer, upgrade_authority_signer]; tx.try_sign(signers, blockhash)?; let final_tx_sig = rpc_client - .send_and_confirm_transaction_with_spinner_and_config(&tx, - config.commitment, - config.send_transaction_config + .send_and_confirm_transaction_with_spinner_and_config( + &tx, + config.commitment, + config.send_transaction_config, ) .map_err(|e| format!("Upgrading program failed: {e}"))?; let program_id = CliProgramId { diff --git a/cli/src/program_v4.rs b/cli/src/program_v4.rs index 63c427bcef7ba1..dea0b8d2be8226 100644 --- a/cli/src/program_v4.rs +++ b/cli/src/program_v4.rs @@ -20,8 +20,7 @@ use { solana_client::{ connection_cache::ConnectionCache, send_and_confirm_transactions_in_parallel::{ - send_and_confirm_transactions_in_parallel_blocking_v2, - SendAndConfirmConfigV2, + send_and_confirm_transactions_in_parallel_blocking_v2, SendAndConfirmConfigV2, }, tpu_client::{TpuClient, TpuClientConfig}, }, diff --git a/client/src/send_and_confirm_transactions_in_parallel.rs b/client/src/send_and_confirm_transactions_in_parallel.rs index 61003b84c315d0..ade60954782497 100644 --- a/client/src/send_and_confirm_transactions_in_parallel.rs +++ b/client/src/send_and_confirm_transactions_in_parallel.rs @@ -56,7 +56,11 @@ struct BlockHashData { } // Deprecated struct to maintain backward compatibility -#[deprecated(note = "Use SendAndConfirmConfigV2 with send_and_confirm_transactions_in_parallel_v2")] +#[allow(deprecated)] +#[deprecated( + since = "2.2.0", + note = "Use SendAndConfirmConfigV2 with send_and_confirm_transactions_in_parallel_v2" +)] #[derive(Clone, Debug, Copy)] pub struct SendAndConfirmConfig { pub with_spinner: bool, @@ -71,7 +75,11 @@ pub struct SendAndConfirmConfigV2 { pub rpc_send_transaction_config: RpcSendTransactionConfig, } -#[deprecated(note = "Use send_and_confirm_transactions_in_parallel_v2")] +#[allow(deprecated)] +#[deprecated( + since = "2.2.0", + note = "Use send_and_confirm_transactions_in_parallel_v2" +)] pub async fn send_and_confirm_transactions_in_parallel( rpc_client: Arc, tpu_client: Option, @@ -83,7 +91,6 @@ pub async fn send_and_confirm_transactions_in_parallel( with_spinner: config.with_spinner, resign_txs_count: config.resign_txs_count, rpc_send_transaction_config: RpcSendTransactionConfig { - skip_preflight: false, ..RpcSendTransactionConfig::default() }, }; @@ -93,7 +100,11 @@ pub async fn send_and_confirm_transactions_in_parallel( .await } -#[deprecated(note = "Use send_and_confirm_transactions_in_parallel_blocking_v2")] +#[allow(deprecated)] +#[deprecated( + since = "2.2.0", + note = "Use send_and_confirm_transactions_in_parallel_blocking_v2" +)] pub fn send_and_confirm_transactions_in_parallel_blocking( rpc_client: Arc, tpu_client: Option, @@ -105,7 +116,6 @@ pub fn send_and_confirm_transactions_in_parallel_blocking( with_spinner: config.with_spinner, resign_txs_count: config.resign_txs_count, rpc_send_transaction_config: RpcSendTransactionConfig { - skip_preflight: false, ..RpcSendTransactionConfig::default() }, }; From 4bfca2f0de15f72a5cd1f27d588036f3b782d570 Mon Sep 17 00:00:00 2001 From: Jonas Hahn Date: Wed, 6 Nov 2024 13:05:34 +0100 Subject: [PATCH 6/6] Update CHANGELOG.md --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 916d801e4ae443..5b9ed2919071b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,10 +13,14 @@ Release channels have their own copy of this changelog: * [stable - v1.18](https://github.com/solana-labs/solana/blob/v1.18/CHANGELOG.md) +## [2.2.0] - Unreleased +* Changes + * CLI: + * Add global `--skip-preflight` option for skipping preflight checks on all transactions sent through RPC. This flag, along with `--use-rpc`, can improve success rate with program deployments using the public RPC nodes. ## [2.1.0] - Unreleased * Breaking: * SDK: - * `cargo-build-sbf` and `cargo-build-bpf` have been deprecated for two years and have now been definitely removed. + * `cargo-build-bpf` and `cargo-test-bpf` have been deprecated for two years and have now been definitely removed. Use `cargo-build-sbf` and `cargo-test-sbf` instead. * Stake: * removed the unreleased `redelegate` instruction processor and CLI commands (#2213)