Disable per-sender limit for local transactions. (#9148)

* Disable per-sender limit for local transactions.

* Add a missing new line.
This commit is contained in:
Tomasz Drwięga 2018-07-18 09:14:03 +02:00 committed by Marek Kotewicz
parent 070695b348
commit 4d9c8926b1
7 changed files with 48 additions and 7 deletions

View File

@ -143,6 +143,10 @@ impl txpool::Scoring<VerifiedTransaction> for NonceAndGasPrice {
}
}
}
fn should_ignore_sender_limit(&self, new: &VerifiedTransaction) -> bool {
new.priority().is_local()
}
}
#[cfg(test)]

View File

@ -116,12 +116,11 @@ fn should_never_drop_local_transactions_from_different_senders() {
let r1 = txq.import(TestClient::new(), vec![tx1].local());
let r2 = txq.import(TestClient::new(), vec![tx2].local());
assert_eq!(r1, vec![Ok(())]);
// max-per-sender is reached, that's ok.
assert_eq!(r2, vec![Err(transaction::Error::LimitReached)]);
assert_eq!(txq.status().status.transaction_count, 1);
assert_eq!(r2, vec![Ok(())]);
assert_eq!(txq.status().status.transaction_count, 2);
// then
assert_eq!(txq.next_nonce(TestClient::new(), &sender), Some(nonce + 1.into()));
assert_eq!(txq.next_nonce(TestClient::new(), &sender), Some(nonce + 2.into()));
// when
let tx1 = Tx::gas_price(2).signed();
@ -134,8 +133,8 @@ fn should_never_drop_local_transactions_from_different_senders() {
// then
assert_eq!(res, vec![Ok(()), Ok(())]);
assert_eq!(res2, vec![Ok(()), Ok(())]);
assert_eq!(txq.status().status.transaction_count, 5);
assert_eq!(txq.next_nonce(TestClient::new(), &sender), Some(nonce + 1.into()));
assert_eq!(txq.status().status.transaction_count, 6);
assert_eq!(txq.next_nonce(TestClient::new(), &sender), Some(nonce + 2.into()));
}
#[test]

View File

@ -613,3 +613,4 @@ impl<'a, T, R, S, L> Iterator for PendingIterator<'a, T, R, S, L> where
None
}
}

View File

@ -102,6 +102,12 @@ pub trait Scoring<T>: fmt::Debug {
///
/// NOTE returning `InsertNew` here can lead to some transactions being accepted above pool limits.
fn should_replace(&self, old: &T, new: &T) -> Choice;
/// Decides if the transaction should ignore per-sender limit in the pool.
///
/// If you return `true` for given transaction it's going to be accepted even though
/// the per-sender limit is exceeded.
fn should_ignore_sender_limit(&self, _new: &T) -> bool { false }
}
/// A score with a reference to the transaction.

View File

@ -77,6 +77,10 @@ impl Scoring<Transaction> for DummyScoring {
scoring::Choice::RejectNew
}
}
fn should_ignore_sender_limit(&self, _new: &Transaction) -> bool {
self.always_insert
}
}
#[derive(Default)]

View File

@ -591,6 +591,33 @@ fn should_not_import_even_if_limit_is_reached_and_should_replace_returns_false()
});
}
#[test]
fn should_import_even_if_sender_limit_is_reached() {
// given
let b = TransactionBuilder::default();
let mut txq = TestPool::with_scoring(DummyScoring::always_insert(), Options {
max_count: 1,
max_per_sender: 1,
..Default::default()
});
txq.import(b.tx().nonce(0).gas_price(5).new()).unwrap();
assert_eq!(txq.light_status(), LightStatus {
transaction_count: 1,
senders: 1,
mem_usage: 0,
});
// when
txq.import(b.tx().nonce(1).gas_price(5).new()).unwrap();
// then
assert_eq!(txq.light_status(), LightStatus {
transaction_count: 2,
senders: 1,
mem_usage: 0,
});
}
mod listener {
use std::cell::RefCell;
use std::rc::Rc;

View File

@ -95,7 +95,7 @@ impl<T: fmt::Debug, S: Scoring<T>> Transactions<T, S> {
fn push_cheapest_transaction(&mut self, tx: Transaction<T>, scoring: &S, max_count: usize) -> AddResult<Transaction<T>, S::Score> {
let index = self.transactions.len();
if index == max_count {
if index == max_count && !scoring.should_ignore_sender_limit(&tx) {
let min_score = self.scores[index - 1].clone();
AddResult::TooCheapToEnter(tx, min_score)
} else {