From 70806ff543496aa6de7807feff49e7e1370efd20 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 23:48:52 +0000 Subject: [PATCH] [mempool] improve parking lot eviction (#14586) (#14589) --- mempool/src/core_mempool/transaction_store.rs | 21 +++- mempool/src/counters.rs | 31 ++++- mempool/src/shared_mempool/tasks.rs | 10 +- mempool/src/tests/common.rs | 72 +++++++++++- mempool/src/tests/core_mempool_test.rs | 104 ++++++++++++++++- mempool/src/tests/integration_tests.rs | 106 +++++++++--------- mempool/src/tests/test_framework.rs | 33 ++---- 7 files changed, 289 insertions(+), 88 deletions(-) diff --git a/mempool/src/core_mempool/transaction_store.rs b/mempool/src/core_mempool/transaction_store.rs index 6f7b1d6547b71..c225a52725707 100644 --- a/mempool/src/core_mempool/transaction_store.rs +++ b/mempool/src/core_mempool/transaction_store.rs @@ -357,8 +357,11 @@ impl TransactionStore { curr_sequence_number: u64, ) -> bool { if self.is_full() && self.check_txn_ready(txn, curr_sequence_number) { - // try to free some space in Mempool from ParkingLot by evicting a non-ready txn - if let Some(txn_pointer) = self.parking_lot_index.get_poppable() { + let now = Instant::now(); + // try to free some space in Mempool from ParkingLot by evicting non-ready txns + let mut evicted_txns = 0; + let mut evicted_bytes = 0; + while let Some(txn_pointer) = self.parking_lot_index.get_poppable() { if let Some(txn) = self .transactions .get_mut(&txn_pointer.sender) @@ -370,9 +373,23 @@ impl TransactionStore { txn.sequence_info.transaction_sequence_number )) ); + evicted_bytes += txn.get_estimated_bytes() as u64; + evicted_txns += 1; self.index_remove(&txn); + if !self.is_full() { + break; + } + } else { + error!("Transaction not found in mempool while evicting from parking lot"); + break; } } + if evicted_txns > 0 { + counters::CORE_MEMPOOL_PARKING_LOT_EVICTED_COUNT.observe(evicted_txns as f64); + counters::CORE_MEMPOOL_PARKING_LOT_EVICTED_BYTES.observe(evicted_bytes as f64); + counters::CORE_MEMPOOL_PARKING_LOT_EVICTED_LATENCY + .observe(now.elapsed().as_secs_f64()); + } } self.is_full() } diff --git a/mempool/src/counters.rs b/mempool/src/counters.rs index dba59738223e3..464523419e886 100644 --- a/mempool/src/counters.rs +++ b/mempool/src/counters.rs @@ -118,7 +118,7 @@ const RANKING_SCORE_BUCKETS: &[f64] = &[ const TXN_CONSENSUS_PULLED_BUCKETS: &[f64] = &[1.0, 2.0, 3.0, 4.0, 5.0, 10.0, 25.0, 50.0, 100.0]; -static TRANSACTION_COUNT_BUCKETS: Lazy> = Lazy::new(|| { +static TXN_COUNT_BUCKETS: Lazy> = Lazy::new(|| { exponential_buckets( /*start=*/ 1.5, /*factor=*/ 1.5, /*count=*/ 20, ) @@ -316,6 +316,33 @@ pub static CORE_MEMPOOL_TXN_CONSENSUS_PULLED_BY_BUCKET: Lazy = Laz .unwrap() }); +pub static CORE_MEMPOOL_PARKING_LOT_EVICTED_COUNT: Lazy = Lazy::new(|| { + register_histogram!( + "aptos_core_mempool_parking_lot_evicted_count", + "Number of txns evicted from parking lot", + TXN_COUNT_BUCKETS.clone() + ) + .unwrap() +}); + +pub static CORE_MEMPOOL_PARKING_LOT_EVICTED_BYTES: Lazy = Lazy::new(|| { + register_histogram!( + "aptos_core_mempool_parking_lot_evicted_bytes", + "Bytes of txns evicted from parking lot", + exponential_buckets(/*start=*/ 500.0, /*factor=*/ 1.4, /*count=*/ 32).unwrap() + ) + .unwrap() +}); + +pub static CORE_MEMPOOL_PARKING_LOT_EVICTED_LATENCY: Lazy = Lazy::new(|| { + register_histogram!( + "aptos_core_mempool_parking_lot_evicted_latency", + "Latency of evicting for each transaction from parking lot", + MEMPOOL_LATENCY_BUCKETS.to_vec() + ) + .unwrap() +}); + /// Counter of pending network events to Mempool pub static PENDING_MEMPOOL_NETWORK_EVENTS: Lazy = Lazy::new(|| { register_int_counter_vec!( @@ -333,7 +360,7 @@ static MEMPOOL_SERVICE_TXNS: Lazy = Lazy::new(|| { "aptos_mempool_service_transactions", "Number of transactions handled in one request/response between mempool and consensus/state sync", &["type"], - TRANSACTION_COUNT_BUCKETS.clone() + TXN_COUNT_BUCKETS.clone() ) .unwrap() }); diff --git a/mempool/src/shared_mempool/tasks.rs b/mempool/src/shared_mempool/tasks.rs index befefd98d7d09..d1acbe7ce1a2a 100644 --- a/mempool/src/shared_mempool/tasks.rs +++ b/mempool/src/shared_mempool/tasks.rs @@ -375,7 +375,15 @@ fn validate_and_add_transactions( .start_timer(); let validation_results = transactions .par_iter() - .map(|t| smp.validator.read().validate_transaction(t.0.clone())) + .map(|t| { + let result = smp.validator.read().validate_transaction(t.0.clone()); + // Pre-compute the hash and length if the transaction is valid, before locking mempool + if result.is_ok() { + t.0.committed_hash(); + t.0.txn_bytes_len(); + } + result + }) .collect::>(); vm_validation_timer.stop_and_record(); { diff --git a/mempool/src/tests/common.rs b/mempool/src/tests/common.rs index 9d94785a920fe..87fa0284a5a68 100644 --- a/mempool/src/tests/common.rs +++ b/mempool/src/tests/common.rs @@ -15,7 +15,7 @@ use aptos_types::{ account_address::AccountAddress, chain_id::ChainId, mempool_status::MempoolStatusCode, - transaction::{RawTransaction, Script, SignedTransaction}, + transaction::{RawTransaction, Script, SignedTransaction, TransactionArgument}, }; use once_cell::sync::Lazy; use rand::{rngs::StdRng, SeedableRng}; @@ -45,21 +45,83 @@ static ACCOUNTS: Lazy> = Lazy::new(|| { ] }); +static SMALL_SCRIPT: Lazy