diff --git a/send-transaction-service/src/send_transaction_service.rs b/send-transaction-service/src/send_transaction_service.rs index c3d8201619..a4efd300de 100644 --- a/send-transaction-service/src/send_transaction_service.rs +++ b/send-transaction-service/src/send_transaction_service.rs @@ -22,6 +22,8 @@ const MAX_TRANSACTION_QUEUE_SIZE: usize = 10_000; // This seems like a lot but m const DEFAULT_RETRY_RATE_MS: u64 = 2_000; /// Default number of leaders to forward transactions to const DEFAULT_LEADER_FORWARD_COUNT: u64 = 2; +/// Default max number of time the service will retry broadcast +const DEFAULT_SERVICE_MAX_RETRIES: usize = usize::MAX; pub struct SendTransactionService { thread: JoinHandle<()>, @@ -69,6 +71,8 @@ struct ProcessTransactionsResult { pub struct Config { pub retry_rate_ms: u64, pub leader_forward_count: u64, + pub default_max_retries: Option, + pub service_max_retries: usize, } impl Default for Config { @@ -76,6 +80,8 @@ impl Default for Config { Self { retry_rate_ms: DEFAULT_RETRY_RATE_MS, leader_forward_count: DEFAULT_LEADER_FORWARD_COUNT, + default_max_retries: None, + service_max_retries: DEFAULT_SERVICE_MAX_RETRIES, } } } @@ -238,7 +244,13 @@ impl SendTransactionService { inc_new_counter_info!("send_transaction_service-expired", 1); return false; } - if let Some(max_retries) = transaction_info.max_retries { + + let max_retries = transaction_info + .max_retries + .or(config.default_max_retries) + .map(|max_retries| max_retries.min(config.service_max_retries)); + + if let Some(max_retries) = max_retries { if transaction_info.retries >= max_retries { info!("Dropping transaction due to max retries: {}", signature); result.max_retries_elapsed += 1; diff --git a/validator/src/main.rs b/validator/src/main.rs index 887d770f3d..5a6cd32923 100644 --- a/validator/src/main.rs +++ b/validator/src/main.rs @@ -430,6 +430,9 @@ pub fn main() { let default_rpc_send_transaction_leader_forward_count = default_send_transaction_service_config .leader_forward_count .to_string(); + let default_rpc_send_transaction_service_max_retries = default_send_transaction_service_config + .service_max_retries + .to_string(); let default_rpc_threads = num_cpus::get().to_string(); let default_accountsdb_repl_threads = num_cpus::get().to_string(); let default_maximum_full_snapshot_archives_to_retain = @@ -1183,6 +1186,23 @@ pub fn main() { .default_value(&default_rpc_send_transaction_leader_forward_count) .help("The number of upcoming leaders to which to forward transactions sent via rpc service."), ) + .arg( + Arg::with_name("rpc_send_transaction_default_max_retries") + .long("rpc-send-default-max-retries") + .value_name("NUMBER") + .takes_value(true) + .validator(is_parsable::) + .help("The maximum number of transaction broadcast retries when unspecified by the request, otherwise retried until expiration."), + ) + .arg( + Arg::with_name("rpc_send_transaction_service_max_retries") + .long("rpc-send-service-max-retries") + .value_name("NUMBER") + .takes_value(true) + .validator(is_parsable::) + .default_value(&default_rpc_send_transaction_service_max_retries) + .help("The maximum number of transaction broadcast retries, regardless of requested value."), + ) .arg( Arg::with_name("rpc_scan_and_fix_roots") .long("rpc-scan-and-fix-roots") @@ -2102,6 +2122,17 @@ pub fn main() { "rpc_send_transaction_leader_forward_count", u64 ), + default_max_retries: value_t!( + matches, + "rpc_send_transaction_default_max_retries", + usize + ) + .ok(), + service_max_retries: value_t_or_exit!( + matches, + "rpc_send_transaction_service_max_retries", + usize + ), }, no_poh_speed_test: matches.is_present("no_poh_speed_test"), poh_pinned_cpu_core: value_of(&matches, "poh_pinned_cpu_core")