tx pool: always accept local transactions (#10375)
* tx pool: always accept local transactions * tx pool: `choose` local txs with same sender and nonce
This commit is contained in:
parent
b58a3ed0ad
commit
4e0ec4e66b
@ -123,15 +123,16 @@ impl<P> txpool::Scoring<P> for NonceAndGasPrice where P: ScoredTransaction + txp
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn should_replace(&self, old: &P, new: &P) -> scoring::Choice {
|
fn should_replace(&self, old: &P, new: &P) -> scoring::Choice {
|
||||||
|
let both_local = old.priority().is_local() && new.priority().is_local();
|
||||||
if old.sender() == new.sender() {
|
if old.sender() == new.sender() {
|
||||||
// prefer earliest transaction
|
// prefer earliest transaction
|
||||||
match new.nonce().cmp(&old.nonce()) {
|
match new.nonce().cmp(&old.nonce()) {
|
||||||
|
cmp::Ordering::Equal => self.choose(old, new),
|
||||||
|
_ if both_local => scoring::Choice::InsertNew,
|
||||||
cmp::Ordering::Less => scoring::Choice::ReplaceOld,
|
cmp::Ordering::Less => scoring::Choice::ReplaceOld,
|
||||||
cmp::Ordering::Greater => scoring::Choice::RejectNew,
|
cmp::Ordering::Greater => scoring::Choice::RejectNew,
|
||||||
cmp::Ordering::Equal => self.choose(old, new),
|
|
||||||
}
|
}
|
||||||
} else if old.priority().is_local() && new.priority().is_local() {
|
} else if both_local {
|
||||||
// accept local transactions over the limit
|
|
||||||
scoring::Choice::InsertNew
|
scoring::Choice::InsertNew
|
||||||
} else {
|
} else {
|
||||||
let old_score = (old.priority(), old.gas_price());
|
let old_score = (old.priority(), old.gas_price());
|
||||||
@ -141,7 +142,7 @@ impl<P> txpool::Scoring<P> for NonceAndGasPrice where P: ScoredTransaction + txp
|
|||||||
} else {
|
} else {
|
||||||
scoring::Choice::RejectNew
|
scoring::Choice::RejectNew
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_ignore_sender_limit(&self, new: &P) -> bool {
|
fn should_ignore_sender_limit(&self, new: &P) -> bool {
|
||||||
@ -154,11 +155,66 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use ethkey::{Random, Generator};
|
use ethkey::{Random, Generator, KeyPair};
|
||||||
use pool::tests::tx::{Tx, TxExt};
|
use pool::tests::tx::{Tx, TxExt};
|
||||||
use txpool::Scoring;
|
use txpool::Scoring;
|
||||||
use txpool::scoring::Choice::*;
|
use txpool::scoring::Choice::*;
|
||||||
|
|
||||||
|
fn local_tx_verified(tx: Tx, keypair: &KeyPair) -> VerifiedTransaction {
|
||||||
|
let mut verified_tx = tx.unsigned().sign(keypair.secret(), None).verified();
|
||||||
|
verified_tx.priority = ::pool::Priority::Local;
|
||||||
|
verified_tx
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_always_accept_local_transactions_unless_same_sender_and_nonce() {
|
||||||
|
let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly);
|
||||||
|
|
||||||
|
// same sender txs
|
||||||
|
let keypair = Random.generate().unwrap();
|
||||||
|
|
||||||
|
let same_sender_tx1 = local_tx_verified(Tx {
|
||||||
|
nonce: 1,
|
||||||
|
gas_price: 1,
|
||||||
|
..Default::default()
|
||||||
|
}, &keypair);
|
||||||
|
|
||||||
|
let same_sender_tx2 = local_tx_verified(Tx {
|
||||||
|
nonce: 2,
|
||||||
|
gas_price: 100,
|
||||||
|
..Default::default()
|
||||||
|
}, &keypair);
|
||||||
|
|
||||||
|
let same_sender_tx3 = local_tx_verified(Tx {
|
||||||
|
nonce: 2,
|
||||||
|
gas_price: 200,
|
||||||
|
..Default::default()
|
||||||
|
}, &keypair);
|
||||||
|
|
||||||
|
// different sender txs
|
||||||
|
let different_sender_tx1 = local_tx_verified(Tx {
|
||||||
|
nonce: 2,
|
||||||
|
gas_price: 1,
|
||||||
|
..Default::default()
|
||||||
|
}, &Random.generate().unwrap());
|
||||||
|
|
||||||
|
let different_sender_tx2 = local_tx_verified(Tx {
|
||||||
|
nonce: 1,
|
||||||
|
gas_price: 10,
|
||||||
|
..Default::default()
|
||||||
|
}, &Random.generate().unwrap());
|
||||||
|
|
||||||
|
assert_eq!(scoring.should_replace(&same_sender_tx1, &same_sender_tx2), InsertNew);
|
||||||
|
assert_eq!(scoring.should_replace(&same_sender_tx2, &same_sender_tx1), InsertNew);
|
||||||
|
|
||||||
|
assert_eq!(scoring.should_replace(&different_sender_tx1, &different_sender_tx2), InsertNew);
|
||||||
|
assert_eq!(scoring.should_replace(&different_sender_tx2, &different_sender_tx1), InsertNew);
|
||||||
|
|
||||||
|
// txs with same sender and nonce
|
||||||
|
assert_eq!(scoring.should_replace(&same_sender_tx2, &same_sender_tx3), ReplaceOld);
|
||||||
|
assert_eq!(scoring.should_replace(&same_sender_tx3, &same_sender_tx2), RejectNew);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_replace_same_sender_by_nonce() {
|
fn should_replace_same_sender_by_nonce() {
|
||||||
let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly);
|
let scoring = NonceAndGasPrice(PrioritizationStrategy::GasPriceOnly);
|
||||||
|
Loading…
Reference in New Issue
Block a user