Clearing old transactions

This commit is contained in:
Tomasz Drwięga 2016-12-09 15:05:03 +01:00
parent 83f791fa5d
commit 5d054f08c3
2 changed files with 46 additions and 1 deletions

View File

@ -81,6 +81,8 @@
//! 3. `remove_all` is used to inform the queue about client (state) nonce changes. //! 3. `remove_all` is used to inform the queue about client (state) nonce changes.
//! - It removes all transactions (either from `current` or `future`) with nonce < client nonce //! - It removes all transactions (either from `current` or `future`) with nonce < client nonce
//! - It moves matching `future` transactions to `current` //! - It moves matching `future` transactions to `current`
//! 4. `remove_old` is used periodically to clear the transactions if node goes out of sync
//! (in such case `remove_all` is not invoked because we are syncing the chain)
use std::ops::Deref; use std::ops::Deref;
use std::cmp::Ordering; use std::cmp::Ordering;
@ -765,6 +767,20 @@ impl TransactionQueue {
assert_eq!(self.future.by_priority.len() + self.current.by_priority.len(), self.by_hash.len()); assert_eq!(self.future.by_priority.len() + self.current.by_priority.len(), self.by_hash.len());
} }
/// Checks the current nonce for all transactions' senders in the queue and removes the old transactions.
pub fn remove_old<F>(&mut self, fetch_account: &F) where
F: Fn(&Address) -> AccountDetails,
{
let senders = self.current.by_address
.keys()
.map(|key| (*key, fetch_account(key).nonce))
.collect::<Vec<_>>();
for (sender, nonce) in senders {
self.remove_all(sender, nonce);
}
}
/// Penalize transactions from sender of transaction with given hash. /// Penalize transactions from sender of transaction with given hash.
/// I.e. it should change the priority of the transaction in the queue. /// I.e. it should change the priority of the transaction in the queue.
/// ///
@ -2438,7 +2454,7 @@ mod test {
} }
#[test] #[test]
fn should_reject_transactions_below_bas_gas() { fn should_reject_transactions_below_base_gas() {
// given // given
let mut txq = TransactionQueue::default(); let mut txq = TransactionQueue::default();
let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into()); let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
@ -2457,4 +2473,27 @@ mod test {
} }
#[test]
fn should_clear_all_old_transactions() {
// given
let mut txq = TransactionQueue::default();
let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
let (tx3, tx4) = new_tx_pair_default(1.into(), 0.into());
let nonce1 = tx1.nonce;
let new_details = |_a: &Address| AccountDetails { nonce: nonce1 + U256::one(), balance: !U256::zero() };
// Insert all transactions
txq.add(tx1, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
txq.add(tx2, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
txq.add(tx3, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
txq.add(tx4, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
assert_eq!(txq.top_transactions().len(), 4);
// when
txq.remove_old(&new_details);
// then
assert_eq!(txq.top_transactions().len(), 2);
}
} }

View File

@ -18,6 +18,7 @@
use std::hash::Hash; use std::hash::Hash;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::hash_map::Keys;
/// Structure to hold double-indexed values /// Structure to hold double-indexed values
/// ///
@ -41,6 +42,11 @@ impl<Row, Col, Val> Table<Row, Col, Val>
} }
} }
/// Returns keys iterator for this Table.
pub fn keys(&self) -> Keys<Row, HashMap<Col, Val>> {
self.map.keys()
}
/// Removes all elements from this Table /// Removes all elements from this Table
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.map.clear(); self.map.clear();