diff --git a/core/src/banking_stage/committer.rs b/core/src/banking_stage/committer.rs index 6e5f411dc0f4ae..d91900299107c8 100644 --- a/core/src/banking_stage/committer.rs +++ b/core/src/banking_stage/committer.rs @@ -74,10 +74,7 @@ impl Committer { bank: &Arc, pre_balance_info: &mut PreBalanceInfo, execute_and_commit_timings: &mut LeaderExecuteAndCommitTimings, - signature_count: u64, - executed_transactions_count: usize, - executed_non_vote_transactions_count: usize, - executed_with_successful_result_count: usize, + execution_counts: &ExecutedTransactionCounts, ) -> (u64, Vec) { let executed_transactions = execution_results .iter() @@ -90,14 +87,7 @@ impl Committer { execution_results, last_blockhash, lamports_per_signature, - ExecutedTransactionCounts { - executed_transactions_count: executed_transactions_count as u64, - executed_non_vote_transactions_count: executed_non_vote_transactions_count as u64, - executed_with_failure_result_count: executed_transactions_count - .saturating_sub(executed_with_successful_result_count) - as u64, - signature_count, - }, + execution_counts, &mut execute_and_commit_timings.execute_timings, )); execute_and_commit_timings.commit_us = commit_time_us; diff --git a/core/src/banking_stage/consume_worker.rs b/core/src/banking_stage/consume_worker.rs index 57a4778d3204b3..449ea9ab963a39 100644 --- a/core/src/banking_stage/consume_worker.rs +++ b/core/src/banking_stage/consume_worker.rs @@ -224,9 +224,7 @@ impl ConsumeWorkerMetrics { fn update_on_execute_and_commit_transactions_output( &self, ExecuteAndCommitTransactionsOutput { - transactions_attempted_execution_count, - executed_transactions_count, - executed_with_successful_result_count, + transaction_counts, retryable_transaction_indexes, execute_and_commit_timings, error_counters, @@ -237,13 +235,19 @@ impl ConsumeWorkerMetrics { ) { self.count_metrics .transactions_attempted_execution_count - .fetch_add(*transactions_attempted_execution_count, Ordering::Relaxed); + .fetch_add( + transaction_counts.attempted_execution_count, + Ordering::Relaxed, + ); self.count_metrics .executed_transactions_count - .fetch_add(*executed_transactions_count, Ordering::Relaxed); + .fetch_add(transaction_counts.executed_count, Ordering::Relaxed); self.count_metrics .executed_with_successful_result_count - .fetch_add(*executed_with_successful_result_count, Ordering::Relaxed); + .fetch_add( + transaction_counts.executed_with_successful_result_count, + Ordering::Relaxed, + ); self.count_metrics .retryable_transaction_count .fetch_add(retryable_transaction_indexes.len(), Ordering::Relaxed); @@ -406,12 +410,12 @@ impl ConsumeWorkerMetrics { } struct ConsumeWorkerCountMetrics { - transactions_attempted_execution_count: AtomicUsize, - executed_transactions_count: AtomicUsize, - executed_with_successful_result_count: AtomicUsize, + transactions_attempted_execution_count: AtomicU64, + executed_transactions_count: AtomicU64, + executed_with_successful_result_count: AtomicU64, retryable_transaction_count: AtomicUsize, retryable_expired_bank_count: AtomicUsize, - cost_model_throttled_transactions_count: AtomicUsize, + cost_model_throttled_transactions_count: AtomicU64, min_prioritization_fees: AtomicU64, max_prioritization_fees: AtomicU64, } @@ -419,12 +423,12 @@ struct ConsumeWorkerCountMetrics { impl Default for ConsumeWorkerCountMetrics { fn default() -> Self { Self { - transactions_attempted_execution_count: AtomicUsize::default(), - executed_transactions_count: AtomicUsize::default(), - executed_with_successful_result_count: AtomicUsize::default(), + transactions_attempted_execution_count: AtomicU64::default(), + executed_transactions_count: AtomicU64::default(), + executed_with_successful_result_count: AtomicU64::default(), retryable_transaction_count: AtomicUsize::default(), retryable_expired_bank_count: AtomicUsize::default(), - cost_model_throttled_transactions_count: AtomicUsize::default(), + cost_model_throttled_transactions_count: AtomicU64::default(), min_prioritization_fees: AtomicU64::new(u64::MAX), max_prioritization_fees: AtomicU64::default(), } diff --git a/core/src/banking_stage/consumer.rs b/core/src/banking_stage/consumer.rs index f4e15edd0888f9..9965b1c3214c3d 100644 --- a/core/src/banking_stage/consumer.rs +++ b/core/src/banking_stage/consumer.rs @@ -2,7 +2,9 @@ use { super::{ committer::{CommitTransactionDetails, Committer, PreBalanceInfo}, immutable_deserialized_packet::ImmutableDeserializedPacket, - leader_slot_metrics::{LeaderSlotMetricsTracker, ProcessTransactionsSummary}, + leader_slot_metrics::{ + LeaderSlotMetricsTracker, ProcessTransactionsCounts, ProcessTransactionsSummary, + }, leader_slot_timing_metrics::LeaderExecuteAndCommitTimings, qos_service::QosService, unprocessed_transaction_storage::{ConsumeScannerPayload, UnprocessedTransactionStorage}, @@ -46,21 +48,16 @@ pub const TARGET_NUM_TRANSACTIONS_PER_BATCH: usize = 64; pub struct ProcessTransactionBatchOutput { // The number of transactions filtered out by the cost model - pub(crate) cost_model_throttled_transactions_count: usize, + pub(crate) cost_model_throttled_transactions_count: u64, // Amount of time spent running the cost model pub(crate) cost_model_us: u64, pub execute_and_commit_transactions_output: ExecuteAndCommitTransactionsOutput, } pub struct ExecuteAndCommitTransactionsOutput { - // Total number of transactions that were passed as candidates for execution - pub(crate) transactions_attempted_execution_count: usize, - // The number of transactions of that were executed. See description of in `ProcessTransactionsSummary` - // for possible outcomes of execution. - pub(crate) executed_transactions_count: usize, - // Total number of the executed transactions that returned success/not - // an error. - pub(crate) executed_with_successful_result_count: usize, + // Transactions counts reported to `ConsumeWorkerMetrics` and then + // accumulated later for `LeaderSlotMetrics` + pub(crate) transaction_counts: ExecuteAndCommitTransactionsCounts, // Transactions that either were not executed, or were executed and failed to be committed due // to the block ending. pub(crate) retryable_transaction_indexes: Vec, @@ -73,6 +70,18 @@ pub struct ExecuteAndCommitTransactionsOutput { pub(crate) max_prioritization_fees: u64, } +#[derive(Debug, Default, PartialEq)] +pub struct ExecuteAndCommitTransactionsCounts { + // Total number of transactions that were passed as candidates for execution + pub(crate) attempted_execution_count: u64, + // The number of transactions of that were executed. See description of in `ProcessTransactionsSummary` + // for possible outcomes of execution. + pub(crate) executed_count: u64, + // Total number of the executed transactions that returned success/not + // an error. + pub(crate) executed_with_successful_result_count: u64, +} + pub struct Consumer { committer: Committer, transaction_recorder: TransactionRecorder, @@ -275,17 +284,8 @@ impl Consumer { ) -> ProcessTransactionsSummary { let mut chunk_start = 0; let mut all_retryable_tx_indexes = vec![]; - // All the transactions that attempted execution. See description of - // struct ProcessTransactionsSummary above for possible outcomes. - let mut total_transactions_attempted_execution_count: usize = 0; - // All transactions that were executed and committed - let mut total_committed_transactions_count: usize = 0; - // All transactions that were executed and committed with a successful result - let mut total_committed_transactions_with_successful_result_count: usize = 0; - // All transactions that were executed but then failed record because the - // slot ended - let mut total_failed_commit_count: usize = 0; - let mut total_cost_model_throttled_transactions_count: usize = 0; + let mut total_transaction_counts = ProcessTransactionsCounts::default(); + let mut total_cost_model_throttled_transactions_count: u64 = 0; let mut total_cost_model_us: u64 = 0; let mut total_execute_and_commit_timings = LeaderExecuteAndCommitTimings::default(); let mut total_error_counters = TransactionErrorMetrics::default(); @@ -315,9 +315,7 @@ impl Consumer { saturating_add_assign!(total_cost_model_us, new_cost_model_us); let ExecuteAndCommitTransactionsOutput { - transactions_attempted_execution_count: new_transactions_attempted_execution_count, - executed_transactions_count: new_executed_transactions_count, - executed_with_successful_result_count: new_executed_with_successful_result_count, + transaction_counts: new_transaction_counts, retryable_transaction_indexes: new_retryable_transaction_indexes, commit_transactions_result: new_commit_transactions_result, execute_and_commit_timings: new_execute_and_commit_timings, @@ -329,33 +327,16 @@ impl Consumer { total_execute_and_commit_timings.accumulate(&new_execute_and_commit_timings); total_error_counters.accumulate(&new_error_counters); - saturating_add_assign!( - total_transactions_attempted_execution_count, - new_transactions_attempted_execution_count + total_transaction_counts.accumulate( + &new_transaction_counts, + new_commit_transactions_result.is_ok(), ); + overall_min_prioritization_fees = std::cmp::min(overall_min_prioritization_fees, min_prioritization_fees); overall_max_prioritization_fees = std::cmp::min(overall_max_prioritization_fees, max_prioritization_fees); - trace!( - "process_transactions result: {:?}", - new_commit_transactions_result - ); - - if new_commit_transactions_result.is_ok() { - saturating_add_assign!( - total_committed_transactions_count, - new_executed_transactions_count - ); - saturating_add_assign!( - total_committed_transactions_with_successful_result_count, - new_executed_with_successful_result_count - ); - } else { - saturating_add_assign!(total_failed_commit_count, new_executed_transactions_count); - } - // Add the retryable txs (transactions that errored in a way that warrants a retry) // to the list of unprocessed txs. all_retryable_tx_indexes.extend_from_slice(&new_retryable_transaction_indexes); @@ -387,11 +368,7 @@ impl Consumer { ProcessTransactionsSummary { reached_max_poh_height, - transactions_attempted_execution_count: total_transactions_attempted_execution_count, - committed_transactions_count: total_committed_transactions_count, - committed_transactions_with_successful_result_count: - total_committed_transactions_with_successful_result_count, - failed_commit_count: total_failed_commit_count, + transaction_counts: total_transaction_counts, retryable_transaction_indexes: all_retryable_tx_indexes, cost_model_throttled_transactions_count: total_cost_model_throttled_transactions_count, cost_model_us: total_cost_model_us, @@ -646,13 +623,15 @@ impl Consumer { let LoadAndExecuteTransactionsOutput { execution_results, - executed_transactions_count, - executed_non_vote_transactions_count, - executed_with_successful_result_count, - signature_count, + execution_counts, } = load_and_execute_transactions_output; - let transactions_attempted_execution_count = execution_results.len(); + let transaction_counts = ExecuteAndCommitTransactionsCounts { + executed_count: execution_counts.executed_transactions_count, + executed_with_successful_result_count: execution_counts.executed_successfully_count, + attempted_execution_count: execution_results.len() as u64, + }; + let (executed_transactions, execution_results_to_transactions_us) = measure_us!(execution_results .iter() @@ -701,9 +680,7 @@ impl Consumer { )); return ExecuteAndCommitTransactionsOutput { - transactions_attempted_execution_count, - executed_transactions_count, - executed_with_successful_result_count, + transaction_counts, retryable_transaction_indexes, commit_transactions_result: Err(recorder_err), execute_and_commit_timings, @@ -713,27 +690,25 @@ impl Consumer { }; } - let (commit_time_us, commit_transaction_statuses) = if executed_transactions_count != 0 { - self.committer.commit_transactions( - batch, - execution_results, - last_blockhash, - lamports_per_signature, - starting_transaction_index, - bank, - &mut pre_balance_info, - &mut execute_and_commit_timings, - signature_count, - executed_transactions_count, - executed_non_vote_transactions_count, - executed_with_successful_result_count, - ) - } else { - ( - 0, - vec![CommitTransactionDetails::NotCommitted; execution_results.len()], - ) - }; + let (commit_time_us, commit_transaction_statuses) = + if execution_counts.executed_transactions_count != 0 { + self.committer.commit_transactions( + batch, + execution_results, + last_blockhash, + lamports_per_signature, + starting_transaction_index, + bank, + &mut pre_balance_info, + &mut execute_and_commit_timings, + &execution_counts, + ) + } else { + ( + 0, + vec![CommitTransactionDetails::NotCommitted; execution_results.len()], + ) + }; drop(freeze_lock); @@ -752,14 +727,12 @@ impl Consumer { ); debug_assert_eq!( - commit_transaction_statuses.len(), - transactions_attempted_execution_count + transaction_counts.attempted_execution_count, + commit_transaction_statuses.len() as u64, ); ExecuteAndCommitTransactionsOutput { - transactions_attempted_execution_count, - executed_transactions_count, - executed_with_successful_result_count, + transaction_counts, retryable_transaction_indexes, commit_transactions_result: Ok(commit_transaction_statuses), execute_and_commit_timings, @@ -1140,16 +1113,19 @@ mod tests { consumer.process_and_record_transactions(&bank, &transactions, 0); let ExecuteAndCommitTransactionsOutput { - transactions_attempted_execution_count, - executed_transactions_count, - executed_with_successful_result_count, + transaction_counts, commit_transactions_result, .. } = process_transactions_batch_output.execute_and_commit_transactions_output; - assert_eq!(transactions_attempted_execution_count, 1); - assert_eq!(executed_transactions_count, 1); - assert_eq!(executed_with_successful_result_count, 1); + assert_eq!( + transaction_counts, + ExecuteAndCommitTransactionsCounts { + attempted_execution_count: 1, + executed_count: 1, + executed_with_successful_result_count: 1, + } + ); assert!(commit_transactions_result.is_ok()); // Tick up to max tick height @@ -1185,17 +1161,20 @@ mod tests { consumer.process_and_record_transactions(&bank, &transactions, 0); let ExecuteAndCommitTransactionsOutput { - transactions_attempted_execution_count, - executed_transactions_count, - executed_with_successful_result_count, + transaction_counts, retryable_transaction_indexes, commit_transactions_result, .. } = process_transactions_batch_output.execute_and_commit_transactions_output; - assert_eq!(transactions_attempted_execution_count, 1); - // Transactions was still executed, just wasn't committed, so should be counted here. - assert_eq!(executed_transactions_count, 1); - assert_eq!(executed_with_successful_result_count, 1); + assert_eq!( + transaction_counts, + ExecuteAndCommitTransactionsCounts { + attempted_execution_count: 1, + // Transactions was still executed, just wasn't committed, so should be counted here. + executed_count: 1, + executed_with_successful_result_count: 1, + } + ); assert_eq!(retryable_transaction_indexes, vec![0]); assert_matches!( commit_transactions_result, @@ -1323,16 +1302,19 @@ mod tests { let process_transactions_batch_output = consumer.process_and_record_transactions(&bank, &transactions, 0); let ExecuteAndCommitTransactionsOutput { - transactions_attempted_execution_count, - executed_transactions_count, - executed_with_successful_result_count, + transaction_counts, commit_transactions_result, .. } = process_transactions_batch_output.execute_and_commit_transactions_output; - assert_eq!(transactions_attempted_execution_count, 1); - assert_eq!(executed_transactions_count, 1); - assert_eq!(executed_with_successful_result_count, 0); + assert_eq!( + transaction_counts, + ExecuteAndCommitTransactionsCounts { + attempted_execution_count: 1, + executed_count: 1, + executed_with_successful_result_count: 0, + } + ); assert!(commit_transactions_result.is_ok()); // Ensure that poh did the last tick after recording transactions @@ -1425,17 +1407,20 @@ mod tests { consumer.process_and_record_transactions(&bank, &transactions, 0); let ExecuteAndCommitTransactionsOutput { - transactions_attempted_execution_count, - executed_transactions_count, - executed_with_successful_result_count, + transaction_counts, commit_transactions_result, retryable_transaction_indexes, .. } = process_transactions_batch_output.execute_and_commit_transactions_output; - assert_eq!(transactions_attempted_execution_count, 1); - assert_eq!(executed_transactions_count, 0); - assert_eq!(executed_with_successful_result_count, 0); + assert_eq!( + transaction_counts, + ExecuteAndCommitTransactionsCounts { + attempted_execution_count: 1, + executed_count: 0, + executed_with_successful_result_count: 0, + } + ); assert!(retryable_transaction_indexes.is_empty()); assert_eq!( commit_transactions_result.ok(), @@ -1517,11 +1502,11 @@ mod tests { consumer.process_and_record_transactions(&bank, &transactions, 0); let ExecuteAndCommitTransactionsOutput { - executed_with_successful_result_count, + transaction_counts, commit_transactions_result, .. } = process_transactions_batch_output.execute_and_commit_transactions_output; - assert_eq!(executed_with_successful_result_count, 1); + assert_eq!(transaction_counts.executed_with_successful_result_count, 1); assert!(commit_transactions_result.is_ok()); let block_cost = get_block_cost(); @@ -1547,12 +1532,12 @@ mod tests { consumer.process_and_record_transactions(&bank, &transactions, 0); let ExecuteAndCommitTransactionsOutput { - executed_with_successful_result_count, + transaction_counts, commit_transactions_result, retryable_transaction_indexes, .. } = process_transactions_batch_output.execute_and_commit_transactions_output; - assert_eq!(executed_with_successful_result_count, 1); + assert_eq!(transaction_counts.executed_with_successful_result_count, 1); assert!(commit_transactions_result.is_ok()); // first one should have been committed, second one not committed due to AccountInUse error during @@ -1671,16 +1656,21 @@ mod tests { let _ = poh_simulator.join(); let ExecuteAndCommitTransactionsOutput { - transactions_attempted_execution_count, - executed_transactions_count, + transaction_counts, retryable_transaction_indexes, commit_transactions_result, .. } = process_transactions_batch_output.execute_and_commit_transactions_output; - assert_eq!(transactions_attempted_execution_count, 2); - assert_eq!(executed_transactions_count, 1); - assert_eq!(retryable_transaction_indexes, vec![1],); + assert_eq!( + transaction_counts, + ExecuteAndCommitTransactionsCounts { + attempted_execution_count: 2, + executed_count: 1, + executed_with_successful_result_count: 1, + } + ); + assert_eq!(retryable_transaction_indexes, vec![1]); assert!(commit_transactions_result.is_ok()); } Blockstore::destroy(ledger_path.path()).unwrap(); @@ -1723,28 +1713,30 @@ mod tests { genesis_config.hash(), )); - let transactions_count = transactions.len(); + let transactions_len = transactions.len(); let ProcessTransactionsSummary { reached_max_poh_height, - transactions_attempted_execution_count, - committed_transactions_count, - committed_transactions_with_successful_result_count, - failed_commit_count, + transaction_counts, retryable_transaction_indexes, .. } = execute_transactions_with_dummy_poh_service(bank, transactions); // All the transactions should have been replayed, but only 1 committed assert!(!reached_max_poh_height); - assert_eq!(transactions_attempted_execution_count, transactions_count); - // Both transactions should have been committed, even though one was an error, - // because InstructionErrors are committed - assert_eq!(committed_transactions_count, 2); - assert_eq!(committed_transactions_with_successful_result_count, 1); - assert_eq!(failed_commit_count, 0); + assert_eq!( + transaction_counts, + ProcessTransactionsCounts { + attempted_execution_count: transactions_len as u64, + // Both transactions should have been committed, even though one was an error, + // because InstructionErrors are committed + committed_transactions_count: 2, + committed_transactions_with_successful_result_count: 1, + executed_but_failed_commit: 0, + } + ); assert_eq!( retryable_transaction_indexes, - (1..transactions_count - 1).collect::>() + (1..transactions_len - 1).collect::>() ); } @@ -1782,28 +1774,30 @@ mod tests { genesis_config.hash(), )); - let transactions_count = transactions.len(); + let transactions_len = transactions.len(); let ProcessTransactionsSummary { reached_max_poh_height, - transactions_attempted_execution_count, - committed_transactions_count, - committed_transactions_with_successful_result_count, - failed_commit_count, + transaction_counts, retryable_transaction_indexes, .. } = execute_transactions_with_dummy_poh_service(bank, transactions); // All the transactions should have been replayed, but only 2 committed (first and last) assert!(!reached_max_poh_height); - assert_eq!(transactions_attempted_execution_count, transactions_count); - assert_eq!(committed_transactions_count, 2); - assert_eq!(committed_transactions_with_successful_result_count, 2); - assert_eq!(failed_commit_count, 0,); + assert_eq!( + transaction_counts, + ProcessTransactionsCounts { + attempted_execution_count: transactions_len as u64, + committed_transactions_count: 2, + committed_transactions_with_successful_result_count: 2, + executed_but_failed_commit: 0, + } + ); // Everything except first and last index of the transactions failed and are last retryable assert_eq!( retryable_transaction_indexes, - (1..transactions_count - 1).collect::>() + (1..transactions_len - 1).collect::>() ); } @@ -1861,19 +1855,21 @@ mod tests { let ProcessTransactionsSummary { reached_max_poh_height, - transactions_attempted_execution_count, - committed_transactions_count, - committed_transactions_with_successful_result_count, - failed_commit_count, + transaction_counts, mut retryable_transaction_indexes, .. } = process_transactions_summary; assert!(reached_max_poh_height); - assert_eq!(transactions_attempted_execution_count, 1); - assert_eq!(failed_commit_count, 1); - // MaxHeightReached error does not commit, should be zero here - assert_eq!(committed_transactions_count, 0); - assert_eq!(committed_transactions_with_successful_result_count, 0); + assert_eq!( + transaction_counts, + ProcessTransactionsCounts { + attempted_execution_count: 1, + // MaxHeightReached error does not commit, should be zero here + committed_transactions_count: 0, + committed_transactions_with_successful_result_count: 0, + executed_but_failed_commit: 1, + } + ); retryable_transaction_indexes.sort_unstable(); let expected: Vec = (0..transactions.len()).collect(); diff --git a/core/src/banking_stage/leader_slot_metrics.rs b/core/src/banking_stage/leader_slot_metrics.rs index 390e128b6c8428..4e290600a4de3c 100644 --- a/core/src/banking_stage/leader_slot_metrics.rs +++ b/core/src/banking_stage/leader_slot_metrics.rs @@ -1,5 +1,6 @@ use { super::{ + consumer::ExecuteAndCommitTransactionsCounts, leader_slot_timing_metrics::{LeaderExecuteAndCommitTimings, LeaderSlotTimingMetrics}, packet_deserializer::PacketReceiverStats, unprocessed_transaction_storage::{ @@ -19,47 +20,80 @@ use { /// counted in `Self::retryable_transaction_indexes`. /// 2) Did not execute due to some fatal error like too old, or duplicate signature. These /// will be dropped from the transactions queue and not counted in `Self::retryable_transaction_indexes` -/// 3) Were executed and committed, captured by `committed_transactions_count` below. -/// 4) Were executed and failed commit, captured by `failed_commit_count` below. +/// 3) Were executed and committed, captured by `transaction_counts` below. +/// 4) Were executed and failed commit, captured by `transaction_counts` below. pub(crate) struct ProcessTransactionsSummary { - // Returns true if we hit the end of the block/max PoH height for the block before - // processing all the transactions in the batch. + /// Returns true if we hit the end of the block/max PoH height for the block + /// before processing all the transactions in the batch. pub reached_max_poh_height: bool, - // Total number of transactions that were passed as candidates for execution. See description - // of struct above for possible outcomes for these transactions - pub transactions_attempted_execution_count: usize, + /// Total transaction counts tracked for reporting `LeaderSlotMetrics`. See + /// description of struct above for possible outcomes for these transactions + pub transaction_counts: ProcessTransactionsCounts, - // Total number of transactions that made it into the block - pub committed_transactions_count: usize, - - // Total number of transactions that made it into the block where the transactions - // output from execution was success/no error. - pub committed_transactions_with_successful_result_count: usize, - - // All transactions that were executed but then failed record because the - // slot ended - pub failed_commit_count: usize, - - // Indexes of transactions in the transactions slice that were not committed but are retryable + /// Indexes of transactions in the transactions slice that were not + /// committed but are retryable pub retryable_transaction_indexes: Vec, - // The number of transactions filtered out by the cost model - pub cost_model_throttled_transactions_count: usize, + /// The number of transactions filtered out by the cost model + pub cost_model_throttled_transactions_count: u64, - // Total amount of time spent running the cost model + /// Total amount of time spent running the cost model pub cost_model_us: u64, - // Breakdown of time spent executing and committing transactions + /// Breakdown of time spent executing and committing transactions pub execute_and_commit_timings: LeaderExecuteAndCommitTimings, - // Breakdown of all the transaction errors from transactions passed for execution + /// Breakdown of all the transaction errors from transactions passed for + /// execution pub error_counters: TransactionErrorMetrics, pub min_prioritization_fees: u64, pub max_prioritization_fees: u64, } +#[derive(Debug, Default, PartialEq)] +pub struct ProcessTransactionsCounts { + /// Total number of transactions that were passed as candidates for execution + pub attempted_execution_count: u64, + /// Total number of transactions that made it into the block + pub committed_transactions_count: u64, + /// Total number of transactions that made it into the block where the + /// transactions output from execution was success/no error. + pub committed_transactions_with_successful_result_count: u64, + /// All transactions that were executed but then failed record because the + /// slot ended + pub executed_but_failed_commit: u64, +} + +impl ProcessTransactionsCounts { + pub fn accumulate( + &mut self, + transaction_counts: &ExecuteAndCommitTransactionsCounts, + committed: bool, + ) { + saturating_add_assign!( + self.attempted_execution_count, + transaction_counts.attempted_execution_count + ); + if committed { + saturating_add_assign!( + self.committed_transactions_count, + transaction_counts.executed_count + ); + saturating_add_assign!( + self.committed_transactions_with_successful_result_count, + transaction_counts.executed_with_successful_result_count + ); + } else { + saturating_add_assign!( + self.executed_but_failed_commit, + transaction_counts.executed_count + ); + } + } +} + // Metrics describing prioritization fee information for each transaction storage before processing transactions #[derive(Debug, Default)] struct LeaderPrioritizationFeesMetrics { @@ -559,10 +593,7 @@ impl LeaderSlotMetricsTracker { ) { if let Some(leader_slot_metrics) = &mut self.leader_slot_metrics { let ProcessTransactionsSummary { - transactions_attempted_execution_count, - committed_transactions_count, - committed_transactions_with_successful_result_count, - failed_commit_count, + transaction_counts, ref retryable_transaction_indexes, cost_model_throttled_transactions_count, cost_model_us, @@ -577,28 +608,28 @@ impl LeaderSlotMetricsTracker { leader_slot_metrics .packet_count_metrics .transactions_attempted_execution_count, - *transactions_attempted_execution_count as u64 + transaction_counts.attempted_execution_count ); saturating_add_assign!( leader_slot_metrics .packet_count_metrics .committed_transactions_count, - *committed_transactions_count as u64 + transaction_counts.committed_transactions_count ); saturating_add_assign!( leader_slot_metrics .packet_count_metrics .committed_transactions_with_successful_result_count, - *committed_transactions_with_successful_result_count as u64 + transaction_counts.committed_transactions_with_successful_result_count ); saturating_add_assign!( leader_slot_metrics .packet_count_metrics .executed_transactions_failed_commit_count, - *failed_commit_count as u64 + transaction_counts.executed_but_failed_commit ); saturating_add_assign!( @@ -612,9 +643,10 @@ impl LeaderSlotMetricsTracker { leader_slot_metrics .packet_count_metrics .nonretryable_errored_transactions_count, - transactions_attempted_execution_count - .saturating_sub(*committed_transactions_count) - .saturating_sub(retryable_transaction_indexes.len()) as u64 + transaction_counts + .attempted_execution_count + .saturating_sub(transaction_counts.committed_transactions_count) + .saturating_sub(retryable_transaction_indexes.len() as u64) ); saturating_add_assign!( @@ -635,7 +667,7 @@ impl LeaderSlotMetricsTracker { leader_slot_metrics .packet_count_metrics .cost_model_throttled_transactions_count, - *cost_model_throttled_transactions_count as u64 + *cost_model_throttled_transactions_count ); saturating_add_assign!( diff --git a/core/src/banking_stage/qos_service.rs b/core/src/banking_stage/qos_service.rs index eafc3052aa26dd..afa871277cce42 100644 --- a/core/src/banking_stage/qos_service.rs +++ b/core/src/banking_stage/qos_service.rs @@ -44,7 +44,7 @@ impl QosService { bank: &Bank, transactions: &[SanitizedTransaction], pre_results: impl Iterator>, - ) -> (Vec>, usize) { + ) -> (Vec>, u64) { let transaction_costs = self.compute_transaction_costs(&bank.feature_set, transactions.iter(), pre_results); let (transactions_qos_cost_results, num_included) = self.select_transactions_per_cost( @@ -56,7 +56,7 @@ impl QosService { transactions_qos_cost_results.iter(), )); let cost_model_throttled_transactions_count = - transactions.len().saturating_sub(num_included); + transactions.len().saturating_sub(num_included) as u64; ( transactions_qos_cost_results, diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 2eeb6f924b13a3..cebf31f2d7f945 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -321,14 +321,9 @@ pub struct LoadAndExecuteTransactionsOutput { // Vector of results indicating whether a transaction was executed or could not // be executed. Note executed transactions can still have failed! pub execution_results: Vec, - // Total number of transactions that were executed - pub executed_transactions_count: usize, - // Number of non-vote transactions that were executed - pub executed_non_vote_transactions_count: usize, - // Total number of the executed transactions that returned success/not - // an error. - pub executed_with_successful_result_count: usize, - pub signature_count: u64, + // Executed transaction counts used to update bank transaction counts and + // for metrics reporting. + pub execution_counts: ExecutedTransactionCounts, } pub struct TransactionSimulationResult { @@ -890,10 +885,11 @@ struct PrevEpochInflationRewards { foundation_rate: f64, } +#[derive(Debug, Default, PartialEq)] pub struct ExecutedTransactionCounts { pub executed_transactions_count: u64, + pub executed_successfully_count: u64, pub executed_non_vote_transactions_count: u64, - pub executed_with_failure_result_count: u64, pub signature_count: u64, } @@ -3635,10 +3631,7 @@ impl Bank { measure_us!(self.collect_logs(sanitized_txs, &sanitized_output.execution_results)); timings.saturating_add_in_place(ExecuteTimingType::CollectLogsUs, collect_logs_us); - let mut signature_count = 0; - let mut executed_transactions_count: usize = 0; - let mut executed_non_vote_transactions_count: usize = 0; - let mut executed_with_successful_result_count: usize = 0; + let mut execution_counts = ExecutedTransactionCounts::default(); let err_count = &mut error_counters.total; for (execution_result, tx) in sanitized_output.execution_results.iter().zip(sanitized_txs) { @@ -3656,17 +3649,18 @@ impl Bank { // Signature count must be accumulated only if the transaction // is executed, otherwise a mismatched count between banking and // replay could occur - signature_count += u64::from(tx.message().header().num_required_signatures); - executed_transactions_count += 1; + execution_counts.signature_count += + u64::from(tx.message().header().num_required_signatures); + execution_counts.executed_transactions_count += 1; if !tx.is_simple_vote_transaction() { - executed_non_vote_transactions_count += 1; + execution_counts.executed_non_vote_transactions_count += 1; } } match execution_result.flattened_result() { Ok(()) => { - executed_with_successful_result_count += 1; + execution_counts.executed_successfully_count += 1; } Err(err) => { if *err_count == 0 { @@ -3679,10 +3673,7 @@ impl Bank { LoadAndExecuteTransactionsOutput { execution_results: sanitized_output.execution_results, - executed_transactions_count, - executed_non_vote_transactions_count, - executed_with_successful_result_count, - signature_count, + execution_counts, } } @@ -3888,7 +3879,7 @@ impl Bank { mut execution_results: Vec, last_blockhash: Hash, lamports_per_signature: u64, - counts: ExecutedTransactionCounts, + execution_counts: &ExecutedTransactionCounts, timings: &mut ExecuteTimings, ) -> Vec { assert!( @@ -3899,9 +3890,9 @@ impl Bank { let ExecutedTransactionCounts { executed_transactions_count, executed_non_vote_transactions_count, - executed_with_failure_result_count, + executed_successfully_count, signature_count, - } = counts; + } = *execution_counts; self.increment_transaction_count(executed_transactions_count); self.increment_non_vote_transaction_count_since_restart( @@ -3909,6 +3900,8 @@ impl Bank { ); self.increment_signature_count(signature_count); + let executed_with_failure_result_count = + executed_transactions_count.saturating_sub(executed_successfully_count); if executed_with_failure_result_count > 0 { self.transaction_error_count .fetch_add(executed_with_failure_result_count, Relaxed); @@ -4702,10 +4695,7 @@ impl Bank { let LoadAndExecuteTransactionsOutput { execution_results, - executed_transactions_count, - executed_non_vote_transactions_count, - executed_with_successful_result_count, - signature_count, + execution_counts, } = self.load_and_execute_transactions( batch, max_age, @@ -4729,14 +4719,7 @@ impl Bank { execution_results, last_blockhash, lamports_per_signature, - ExecutedTransactionCounts { - executed_transactions_count: executed_transactions_count as u64, - executed_non_vote_transactions_count: executed_non_vote_transactions_count as u64, - executed_with_failure_result_count: executed_transactions_count - .saturating_sub(executed_with_successful_result_count) - as u64, - signature_count, - }, + &execution_counts, timings, ); let post_balances = if collect_balances {