-
Notifications
You must be signed in to change notification settings - Fork 300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
deploy: Check signature statuses in parallel #1384
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1384 +/- ##
=======================================
Coverage 82.8% 82.8%
=======================================
Files 867 867
Lines 368875 368879 +4
=======================================
+ Hits 305646 305660 +14
+ Misses 63229 63219 -10 |
What if you try diff --git client/Cargo.toml client/Cargo.toml
index ece0b..b0652 100644
--- client/Cargo.toml
+++ client/Cargo.toml
@@ -35,6 +35,7 @@ solana-tpu-client = { workspace = true, features = ["default"] }
solana-udp-client = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true, features = ["full"] }
+itertools = {workspace = true}
[dev-dependencies]
crossbeam-channel = { workspace = true }
diff --git client/src/send_and_confirm_transactions_in_parallel.rs client/src/send_and_confirm_transactions_in_parallel.rs
index aa65ef..35e73 100644
--- client/src/send_and_confirm_transactions_in_parallel.rs
+++ client/src/send_and_confirm_transactions_in_parallel.rs
@@ -6,6 +6,7 @@ use {
bincode::serialize,
dashmap::DashMap,
futures_util::future::join_all,
+ itertools::Itertools,
solana_quic_client::{QuicConfig, QuicConnectionManager, QuicPool},
solana_rpc_client::spinner::{self, SendTransactionProgress},
solana_rpc_client_api::{
@@ -16,7 +17,7 @@ use {
solana_sdk::{
hash::Hash,
message::Message,
- signature::{Signature, SignerError},
+ signature::{self, Signature, SignerError},
signers::Signers,
transaction::{Transaction, TransactionError},
},
@@ -113,11 +114,12 @@ fn create_transaction_confirmation_task(
tokio::spawn(async move {
// check transactions that are not expired or have just expired between two checks
let mut last_block_height = current_block_height.load(Ordering::Relaxed);
+ let mut futures = tokio::task::JoinSet::new();
loop {
if !unconfirmed_transaction_map.is_empty() {
let current_block_height = current_block_height.load(Ordering::Relaxed);
- let transactions_to_verify: Vec<Signature> = unconfirmed_transaction_map
+ let transactions_to_verify: Vec<Vec<Signature>> = unconfirmed_transaction_map
.iter()
.filter(|x| {
let is_not_expired = current_block_height <= x.last_valid_block_height;
@@ -127,11 +129,23 @@ fn create_transaction_confirmation_task(
is_not_expired || is_recently_expired
})
.map(|x| *x.key())
+ .chunks(MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS)
+ .into_iter()
+ .map(|chunk| chunk.collect::<Vec<_>>())
.collect();
- for signatures in
- transactions_to_verify.chunks(MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS)
- {
- if let Ok(result) = rpc_client.get_signature_statuses(signatures).await {
+ while futures.join_next().await.is_some() {}
+
+ for signatures in transactions_to_verify {
+ let rpc_client = rpc_client.clone();
+ let errors_map = errors_map.clone();
+ let num_confirmed_transactions = num_confirmed_transactions.clone();
+ let unconfirmed_transaction_map = unconfirmed_transaction_map.clone();
+ //let signatures = signatures.to_vec();
+ futures.spawn(async move {
+ let Ok(result) = rpc_client.get_signature_statuses(&signatures).await
+ else {
+ return;
+ };
let statuses = result.value;
for (signature, status) in signatures.iter().zip(statuses.into_iter()) {
if let Some((status, data)) = status
@@ -153,12 +167,12 @@ fn create_transaction_confirmation_task(
}
};
}
- }
+ });
}
last_block_height = current_block_height;
}
- tokio::time::sleep(Duration::from_secs(1)).await;
+ //tokio::time::sleep(Duration::from_secs(1)).await;
}
})
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if it doesn't improve the performance, I would just simplify the code with let-else without adding join_all
let futures = transactions_to_verify | ||
.chunks(MAX_GET_SIGNATURE_STATUSES_QUERY_ITEMS) | ||
.map(|signatures| async { | ||
if let Ok(result) = rpc_client.get_signature_statuses(signatures).await { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you a rein this code, I would prefer to exit early:
let Ok(result) = rpc_client.get_signature_statuses(signatures).await else {
return;
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
works for me!
Sorry, I think |
I think there is some misunderstanding of the patch intention. I was curious if there any performance boost due to Independently on this particular code, I think there are some benefits of using
|
Closing since the new TPU client will be the best option 😄 |
Problem
During deployment, we need to check the status of sent transactions in order to see if they have been confirmed. If they are confirmed, they are removed from the resend list.
Unfortunately, the code currently checks signature statuses in series, which means it can take a long time to find out the status of thousands of transactions.
Summary of Changes
Check signature statuses concurrently. There isn't a huge impact in testing 1000 self-transfers on testnet, but here are some timings:
If you think this isn't worth it, I'm happy to close, but let me know!