rpc-client: Encapsulate `set_message_for_confirmed_transactions` (#32941)

This commit is contained in:
Jon Cinque 2023-08-23 11:46:17 +02:00 committed by GitHub
parent 96138b919a
commit e1972f07fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 83 deletions

View File

@ -6,7 +6,7 @@ use {
bincode::serialize,
dashmap::DashMap,
solana_quic_client::{QuicConfig, QuicConnectionManager, QuicPool},
solana_rpc_client::spinner,
solana_rpc_client::spinner::{self, SendTransactionProgress},
solana_rpc_client_api::{
client_error::ErrorKind,
request::{RpcError, RpcResponseErrorData, MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS},
@ -18,13 +18,10 @@ use {
signers::Signers,
transaction::{Transaction, TransactionError},
},
solana_tpu_client::{
nonblocking::tpu_client::set_message_for_confirmed_transactions,
tpu_client::{Result, TpuSenderError},
},
solana_tpu_client::tpu_client::{Result, TpuSenderError},
std::{
sync::{
atomic::{AtomicU32, AtomicU64, Ordering},
atomic::{AtomicU64, AtomicUsize, Ordering},
Arc,
},
time::Duration,
@ -103,7 +100,7 @@ fn create_transaction_confirmation_task(
current_block_height: Arc<AtomicU64>,
unconfirmed_transasction_map: Arc<DashMap<Signature, TransactionData>>,
errors_map: Arc<DashMap<usize, TransactionError>>,
num_confirmed_transactions: Arc<AtomicU32>,
num_confirmed_transactions: Arc<AtomicUsize>,
) -> JoinHandle<()> {
tokio::spawn(async move {
// check transactions that are not expired or have just expired between two checks
@ -160,10 +157,25 @@ struct SendingContext {
unconfirmed_transasction_map: Arc<DashMap<Signature, TransactionData>>,
error_map: Arc<DashMap<usize, TransactionError>>,
blockhash_data_rw: Arc<RwLock<BlockHashData>>,
num_confirmed_transactions: Arc<AtomicU32>,
num_confirmed_transactions: Arc<AtomicUsize>,
total_transactions: usize,
current_block_height: Arc<AtomicU64>,
}
fn progress_from_context_and_block_height(
context: &SendingContext,
last_valid_block_height: u64,
) -> SendTransactionProgress {
SendTransactionProgress {
confirmed_transactions: context
.num_confirmed_transactions
.load(std::sync::atomic::Ordering::Relaxed),
total_transactions: context.total_transactions,
block_height: context
.current_block_height
.load(std::sync::atomic::Ordering::Relaxed),
last_valid_block_height,
}
}
async fn sign_all_messages_and_send<T: Signers + ?Sized>(
progress_bar: &Option<indicatif::ProgressBar>,
@ -235,14 +247,12 @@ async fn sign_all_messages_and_send<T: Signers + ?Sized>(
);
if let Some(progress_bar) = progress_bar {
set_message_for_confirmed_transactions(
progress_bar,
context
.num_confirmed_transactions
.load(std::sync::atomic::Ordering::Relaxed),
context.total_transactions,
None,
let progress = progress_from_context_and_block_height(
context,
blockhashdata.last_valid_blockheight,
);
progress.set_message_for_confirmed_transactions(
progress_bar,
&format!(
"Sending {}/{} transactions",
counter + 1,
@ -260,9 +270,7 @@ async fn confirm_transactions_till_block_height_and_resend_unexpired_transaction
context: &SendingContext,
) {
let unconfirmed_transasction_map = context.unconfirmed_transasction_map.clone();
let num_confirmed_transactions = context.num_confirmed_transactions.clone();
let current_block_height = context.current_block_height.clone();
let total_transactions = context.total_transactions;
let transactions_to_confirm = unconfirmed_transasction_map.len();
let max_valid_block_height = unconfirmed_transasction_map
@ -272,12 +280,9 @@ async fn confirm_transactions_till_block_height_and_resend_unexpired_transaction
if let Some(mut max_valid_block_height) = max_valid_block_height {
if let Some(progress_bar) = progress_bar {
set_message_for_confirmed_transactions(
let progress = progress_from_context_and_block_height(context, max_valid_block_height);
progress.set_message_for_confirmed_transactions(
progress_bar,
num_confirmed_transactions.load(std::sync::atomic::Ordering::Relaxed),
total_transactions,
Some(current_block_height.load(Ordering::Relaxed)),
max_valid_block_height,
&format!(
"Waiting for next block, {transactions_to_confirm} transactions pending..."
),
@ -291,12 +296,10 @@ async fn confirm_transactions_till_block_height_and_resend_unexpired_transaction
let blockheight = current_block_height.load(Ordering::Relaxed);
if let Some(progress_bar) = progress_bar {
set_message_for_confirmed_transactions(
let progress =
progress_from_context_and_block_height(context, max_valid_block_height);
progress.set_message_for_confirmed_transactions(
progress_bar,
num_confirmed_transactions.load(std::sync::atomic::Ordering::Relaxed),
total_transactions,
Some(blockheight),
max_valid_block_height,
"Checking transaction status...",
);
}
@ -332,12 +335,9 @@ async fn confirm_transactions_till_block_height_and_resend_unexpired_transaction
}
if let Some(progress_bar) = progress_bar {
set_message_for_confirmed_transactions(
let progress = progress_from_context_and_block_height(context, max_valid_block_height);
progress.set_message_for_confirmed_transactions(
progress_bar,
num_confirmed_transactions.load(std::sync::atomic::Ordering::Relaxed),
total_transactions,
Some(current_block_height.load(Ordering::Relaxed)),
max_valid_block_height,
"Checking transaction status...",
);
}
@ -391,7 +391,7 @@ pub async fn send_and_confirm_transactions_in_parallel<T: Signers + ?Sized>(
let unconfirmed_transasction_map = Arc::new(DashMap::<Signature, TransactionData>::new());
let error_map = Arc::new(DashMap::new());
let num_confirmed_transactions = Arc::new(AtomicU32::new(0));
let num_confirmed_transactions = Arc::new(AtomicUsize::new(0));
// tasks which confirms the transactions that were sent
let transaction_confirming_task = create_transaction_confirmation_task(
rpc_client.clone(),

View File

@ -14,8 +14,29 @@ pub fn new_progress_bar() -> ProgressBar {
progress_bar.set_style(
ProgressStyle::default_spinner()
.template("{spinner:.green} {wide_msg}")
.expect("ProgresStyle::template direct input to be correct"),
.expect("ProgressStyle::template direct input to be correct"),
);
progress_bar.enable_steady_tick(Duration::from_millis(100));
progress_bar
}
#[derive(Debug, Default)]
pub struct SendTransactionProgress {
pub confirmed_transactions: usize,
pub total_transactions: usize,
pub block_height: u64,
pub last_valid_block_height: u64,
}
impl SendTransactionProgress {
pub fn set_message_for_confirmed_transactions(&self, progress_bar: &ProgressBar, status: &str) {
progress_bar.set_message(format!(
"{:>5.1}% | {:<40} [block height {}; re-sign in {} blocks]",
self.confirmed_transactions as f64 * 100. / self.total_transactions as f64,
status,
self.block_height,
self.last_valid_block_height
.saturating_sub(self.block_height),
));
}
}

View File

@ -45,36 +45,11 @@ use {
#[cfg(feature = "spinner")]
use {
crate::tpu_client::{SEND_TRANSACTION_INTERVAL, TRANSACTION_RESEND_INTERVAL},
indicatif::ProgressBar,
solana_rpc_client::spinner,
solana_rpc_client::spinner::{self, SendTransactionProgress},
solana_rpc_client_api::request::MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS,
solana_sdk::{message::Message, signers::Signers, transaction::TransactionError},
};
#[cfg(feature = "spinner")]
pub fn set_message_for_confirmed_transactions(
progress_bar: &ProgressBar,
confirmed_transactions: u32,
total_transactions: usize,
block_height: Option<u64>,
last_valid_block_height: u64,
status: &str,
) {
progress_bar.set_message(format!(
"{:>5.1}% | {:<40}{}",
confirmed_transactions as f64 * 100. / total_transactions as f64,
status,
match block_height {
Some(block_height) => format!(
" [block height {}; re-sign in {} blocks]",
block_height,
last_valid_block_height.saturating_sub(block_height),
),
None => String::new(),
},
));
}
#[derive(Error, Debug)]
pub enum TpuSenderError {
#[error("Pubsub error: {0:?}")]
@ -453,6 +428,7 @@ where
messages: &[Message],
signers: &T,
) -> Result<Vec<Option<TransactionError>>> {
let mut progress = SendTransactionProgress::default();
let progress_bar = spinner::new_progress_bar();
progress_bar.set_message("Setting up...");
@ -461,15 +437,15 @@ where
.enumerate()
.map(|(i, message)| (i, Transaction::new_unsigned(message.clone())))
.collect::<Vec<_>>();
let total_transactions = transactions.len();
progress.total_transactions = transactions.len();
let mut transaction_errors = vec![None; transactions.len()];
let mut confirmed_transactions = 0;
let mut block_height = self.rpc_client.get_block_height().await?;
progress.block_height = self.rpc_client.get_block_height().await?;
for expired_blockhash_retries in (0..5).rev() {
let (blockhash, last_valid_block_height) = self
.rpc_client
.get_latest_blockhash_with_commitment(self.rpc_client.commitment())
.await?;
progress.last_valid_block_height = last_valid_block_height;
let mut pending_transactions = HashMap::new();
for (i, mut transaction) in transactions {
@ -478,7 +454,7 @@ where
}
let mut last_resend = Instant::now() - TRANSACTION_RESEND_INTERVAL;
while block_height <= last_valid_block_height {
while progress.block_height <= progress.last_valid_block_height {
let num_transactions = pending_transactions.len();
// Periodically re-send all pending transactions
@ -487,12 +463,8 @@ where
if !self.send_transaction(transaction).await {
let _result = self.rpc_client.send_transaction(transaction).await.ok();
}
set_message_for_confirmed_transactions(
progress.set_message_for_confirmed_transactions(
&progress_bar,
confirmed_transactions,
total_transactions,
None, //block_height,
last_valid_block_height,
&format!("Sending {}/{} transactions", index + 1, num_transactions,),
);
sleep(SEND_TRANSACTION_INTERVAL).await;
@ -502,21 +474,17 @@ where
// Wait for the next block before checking for transaction statuses
let mut block_height_refreshes = 10;
set_message_for_confirmed_transactions(
progress.set_message_for_confirmed_transactions(
&progress_bar,
confirmed_transactions,
total_transactions,
Some(block_height),
last_valid_block_height,
&format!("Waiting for next block, {num_transactions} transactions pending..."),
);
let mut new_block_height = block_height;
while block_height == new_block_height && block_height_refreshes > 0 {
let mut new_block_height = progress.block_height;
while progress.block_height == new_block_height && block_height_refreshes > 0 {
sleep(Duration::from_millis(500)).await;
new_block_height = self.rpc_client.get_block_height().await?;
block_height_refreshes -= 1;
}
block_height = new_block_height;
progress.block_height = new_block_height;
// Collect statuses for the transactions, drop those that are confirmed
let pending_signatures = pending_transactions.keys().cloned().collect::<Vec<_>>();
@ -535,7 +503,7 @@ where
if let Some(status) = status {
if status.satisfies_commitment(self.rpc_client.commitment()) {
if let Some((i, _)) = pending_transactions.remove(signature) {
confirmed_transactions += 1;
progress.confirmed_transactions += 1;
if status.err.is_some() {
progress_bar
.println(format!("Failed transaction: {status:?}"));
@ -546,12 +514,8 @@ where
}
}
}
set_message_for_confirmed_transactions(
progress.set_message_for_confirmed_transactions(
&progress_bar,
confirmed_transactions,
total_transactions,
Some(block_height),
last_valid_block_height,
"Checking transaction status...",
);
}