tx-pool: check transaction readiness before replacing (#10526)

* Update to vanilla tx pool error

* Prevent a non ready tx replacing a ready tx

* Make tests compile

* Test ready tx not replaced by future tx

* Transaction indirection

* Use StateReadiness to calculate Ready in `should_replace`

* Test existing txs from same sender are used to compute Readiness

* private-tx: Wire up ShouldReplace

* Revert "Use StateReadiness to calculate Ready in `should_replace`"

This reverts commit af9e69c8

* Make replace generic so it works with private-tx

* Rename Replace and add missing docs

* ShouldReplace no longer mutable

* tx-pool: update to transaction-pool 2.0 from crates.io

* tx-pool: generic error type alias

* Exit early for first unmatching nonce

* Fix private-tx test, use existing write lock

* Use read lock for pool scoring
This commit is contained in:
Andrew Jones
2019-04-01 09:48:51 +01:00
committed by Talha Cross
parent 89f828be1c
commit d9673b0d6b
12 changed files with 448 additions and 202 deletions

View File

@@ -27,7 +27,7 @@ use txpool::{self, Verifier};
use types::transaction;
use pool::{
self, scoring, verifier, client, ready, listener,
self, replace, scoring, verifier, client, ready, listener,
PrioritizationStrategy, PendingOrdering, PendingSettings,
};
use pool::local_transactions::LocalTransactionsList;
@@ -240,7 +240,7 @@ impl TransactionQueue {
///
/// Given blockchain and state access (Client)
/// verifies and imports transactions to the pool.
pub fn import<C: client::Client>(
pub fn import<C: client::Client + client::NonceClient + Clone>(
&self,
client: C,
transactions: Vec<verifier::Transaction>,
@@ -263,12 +263,14 @@ impl TransactionQueue {
};
let verifier = verifier::Verifier::new(
client,
client.clone(),
options,
self.insertion_id.clone(),
transaction_to_replace,
);
let mut replace = replace::ReplaceByScoreAndReadiness::new(self.pool.read().scoring().clone(), client);
let results = transactions
.into_iter()
.map(|transaction| {
@@ -286,7 +288,7 @@ impl TransactionQueue {
let imported = verifier
.verify_transaction(transaction)
.and_then(|verified| {
self.pool.write().import(verified).map_err(convert_error)
self.pool.write().import(verified, &mut replace).map_err(convert_error)
});
match imported {
@@ -579,17 +581,13 @@ impl TransactionQueue {
}
}
fn convert_error(err: txpool::Error) -> transaction::Error {
use self::txpool::ErrorKind;
fn convert_error<H: fmt::Debug + fmt::LowerHex>(err: txpool::Error<H>) -> transaction::Error {
use self::txpool::Error;
match *err.kind() {
ErrorKind::AlreadyImported(..) => transaction::Error::AlreadyImported,
ErrorKind::TooCheapToEnter(..) => transaction::Error::LimitReached,
ErrorKind::TooCheapToReplace(..) => transaction::Error::TooCheapToReplace,
ref e => {
warn!(target: "txqueue", "Unknown import error: {:?}", e);
transaction::Error::NotAllowed
},
match err {
Error::AlreadyImported(..) => transaction::Error::AlreadyImported,
Error::TooCheapToEnter(..) => transaction::Error::LimitReached,
Error::TooCheapToReplace(..) => transaction::Error::TooCheapToReplace
}
}