diff --git a/src/builder_state.rs b/src/builder_state.rs index 8b5ce045..b6aeb562 100644 --- a/src/builder_state.rs +++ b/src/builder_state.rs @@ -136,9 +136,15 @@ pub struct BuilderState { (TxTimeStamp, TYPES::Transaction, TransactionSource), >, - /// Included txs set while building blocks + /// Recent included txs set while building blocks pub included_txns: HashSet>, + /// Old txs to be garbage collected + pub included_txns_old: HashSet>, + + /// Expiring txs to be garbage collected + pub included_txns_expiring: HashSet>, + /// da_proposal_payload_commit to (da_proposal, node_count) #[allow(clippy::type_complexity)] pub da_proposal_payload_commit_to_da_proposal: @@ -184,6 +190,12 @@ pub struct BuilderState { /// instance state to enfoce max_block_size pub instance_state: Arc, + + /// txn garbage collection every duration time + pub txn_garbage_collect_duration: Duration, + + /// time of next garbage collection for txns + pub next_txn_garbage_collect_time: Instant, } /// Trait to hold the helper functions for the builder @@ -239,7 +251,7 @@ impl BuilderProgress for BuilderState { let tx_hash = tx.commit(); tracing::debug!("Transaction hash: {:?}", tx_hash); if self.tx_hash_to_available_txns.contains_key(&tx_hash) - || self.included_txns.contains(&tx_hash) + || self.included_txns.contains(&tx_hash) || self.included_txns_old.contains(&tx_hash) || self.included_txns_expiring.contains(&tx_hash) { tracing::debug!("Transaction already exists in the builderinfo.txid_to_tx hashmap, So we can ignore it"); } else { @@ -270,7 +282,7 @@ impl BuilderProgress for BuilderState { // HOTSHOT MEMPOOL TRANSACTION PROCESSING // If it already exists, then discard it. Decide the existence based on the tx_hash_tx and check in both the local pool and already included txns if self.tx_hash_to_available_txns.contains_key(&tx_hash) - || self.included_txns.contains(&tx_hash) + || self.included_txns.contains(&tx_hash) || self.included_txns_old.contains(&tx_hash) || self.included_txns_expiring.contains(&tx_hash) { tracing::debug!("Transaction already exists in the builderinfo.txid_to_tx hashmap, So we can ignore it"); } else { @@ -922,11 +934,14 @@ impl BuilderState { maximize_txn_capture_timeout: Duration, base_fee: u64, instance_state: Arc, + txn_garbage_collect_duration: Duration, ) -> Self { BuilderState { timestamp_to_tx: BTreeMap::new(), tx_hash_to_available_txns: HashMap::new(), included_txns: HashSet::new(), + included_txns_old: HashSet::new(), + included_txns_expiring: HashSet::new(), built_from_proposed_block, tx_receiver, decide_receiver, @@ -941,13 +956,39 @@ impl BuilderState { maximize_txn_capture_timeout, base_fee, instance_state, + txn_garbage_collect_duration, + next_txn_garbage_collect_time: Instant::now() + txn_garbage_collect_duration, } } pub fn clone_with_receiver(&self, req_receiver: BroadcastReceiver>) -> Self { + // Handle the garbage collection of txns + let ( + included_txns, + included_txns_old, + included_txns_expiring, + next_txn_garbage_collect_time, + ) = if Instant::now() >= self.next_txn_garbage_collect_time { + ( + HashSet::new(), + self.included_txns.clone(), + self.included_txns_old.clone(), + Instant::now() + self.txn_garbage_collect_duration, + ) + } else { + ( + self.included_txns.clone(), + self.included_txns_old.clone(), + self.included_txns_expiring.clone(), + self.next_txn_garbage_collect_time, + ) + }; + BuilderState { timestamp_to_tx: self.timestamp_to_tx.clone(), tx_hash_to_available_txns: self.tx_hash_to_available_txns.clone(), - included_txns: self.included_txns.clone(), + included_txns, + included_txns_old, + included_txns_expiring, built_from_proposed_block: self.built_from_proposed_block.clone(), tx_receiver: self.tx_receiver.clone(), decide_receiver: self.decide_receiver.clone(), @@ -962,6 +1003,8 @@ impl BuilderState { maximize_txn_capture_timeout: self.maximize_txn_capture_timeout, base_fee: self.base_fee, instance_state: self.instance_state.clone(), + txn_garbage_collect_duration: self.txn_garbage_collect_duration, + next_txn_garbage_collect_time, } } } diff --git a/src/testing/basic_test.rs b/src/testing/basic_test.rs index 56bf3868..394dfa2d 100644 --- a/src/testing/basic_test.rs +++ b/src/testing/basic_test.rs @@ -347,6 +347,7 @@ mod tests { Duration::from_millis(10), // max time to wait for non-zero txn block 0, // base fee Arc::new(TestInstanceState {}), + Duration::from_secs(3600), // duration for txn garbage collection ); //builder_state.event_loop().await;