Prepare for asynchronous transaction validation in tx pool (#3650)

* async txpool API

* Update core/rpc/src/author/mod.rs

Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com>

* Update core/transaction-pool/graph/src/pool.rs

Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com>

* Pool -> Pool + ValidatedPool

* removed lost block_on when importing xt from network

* fix grumbles

* alias for future::Executor in rpc

* removed executor from Author RPCs

* Pool + SharedValidatedPool -> Pool

* fix compilation after merge

* another fix

* another fix
This commit is contained in:
Svyatoslav Nikolsky
2019-10-01 12:14:25 +03:00
committed by GitHub
parent facf31f77e
commit 387c31598d
29 changed files with 912 additions and 497 deletions
+11 -6
View File
@@ -37,24 +37,24 @@ use sr_primitives::{
use crate::error;
/// The transaction pool logic
pub struct ChainApi<T, Block> {
pub struct FullChainApi<T, Block> {
client: Arc<T>,
_marker: PhantomData<Block>,
}
impl<T, Block> ChainApi<T, Block> where
impl<T, Block> FullChainApi<T, Block> where
Block: traits::Block,
T: traits::ProvideRuntimeApi + HeaderBackend<Block> {
/// Create new transaction pool logic.
pub fn new(client: Arc<T>) -> Self {
ChainApi {
FullChainApi {
client,
_marker: Default::default()
}
}
}
impl<T, Block> txpool::ChainApi for ChainApi<T, Block> where
impl<T, Block> txpool::ChainApi for FullChainApi<T, Block> where
Block: traits::Block<Hash=H256>,
T: traits::ProvideRuntimeApi + HeaderBackend<Block>,
T::Api: TaggedTransactionQueue<Block>
@@ -62,9 +62,14 @@ impl<T, Block> txpool::ChainApi for ChainApi<T, Block> where
type Block = Block;
type Hash = H256;
type Error = error::Error;
type ValidationFuture = futures::future::Ready<error::Result<TransactionValidity>>;
fn validate_transaction(&self, at: &BlockId<Self::Block>, uxt: txpool::ExtrinsicFor<Self>) -> error::Result<TransactionValidity> {
Ok(self.client.runtime_api().validate_transaction(at, uxt)?)
fn validate_transaction(
&self,
at: &BlockId<Self::Block>,
uxt: txpool::ExtrinsicFor<Self>,
) -> Self::ValidationFuture {
futures::future::ready(self.client.runtime_api().validate_transaction(at, uxt).map_err(Into::into))
}
fn block_id_to_number(&self, at: &BlockId<Self::Block>) -> error::Result<Option<txpool::NumberFor<Self>>> {
+1 -1
View File
@@ -25,5 +25,5 @@ mod tests;
pub mod error;
pub use api::ChainApi;
pub use api::FullChainApi;
pub use txpool;
+17 -15
View File
@@ -18,6 +18,7 @@
use super::*;
use codec::Encode;
use futures::executor::block_on;
use txpool::{self, Pool};
use test_client::{runtime::{AccountId, Block, Hash, Index, Extrinsic, Transfer}, AccountKeyring::{self, *}};
use sr_primitives::{
@@ -38,12 +39,13 @@ impl txpool::ChainApi for TestApi {
type Block = Block;
type Hash = Hash;
type Error = error::Error;
type ValidationFuture = futures::future::Ready<error::Result<TransactionValidity>>;
fn validate_transaction(
&self,
at: &BlockId<Self::Block>,
uxt: txpool::ExtrinsicFor<Self>,
) -> error::Result<TransactionValidity> {
) -> Self::ValidationFuture {
let expected = index(at);
let requires = if expected == uxt.transfer().nonce {
vec![]
@@ -52,7 +54,7 @@ impl txpool::ChainApi for TestApi {
};
let provides = vec![vec![uxt.transfer().nonce as u8]];
Ok(
futures::future::ready(Ok(
Ok(ValidTransaction {
priority: 1,
requires,
@@ -60,7 +62,7 @@ impl txpool::ChainApi for TestApi {
longevity: 64,
propagate: true,
})
)
))
}
fn block_id_to_number(&self, at: &BlockId<Self::Block>) -> error::Result<Option<txpool::NumberFor<Self>>> {
@@ -111,7 +113,7 @@ fn pool() -> Pool<TestApi> {
fn submission_should_work() {
let pool = pool();
assert_eq!(209, index(&BlockId::number(0)));
pool.submit_one(&BlockId::number(0), uxt(Alice, 209)).unwrap();
block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap();
let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect();
assert_eq!(pending, vec![209]);
@@ -120,8 +122,8 @@ fn submission_should_work() {
#[test]
fn multiple_submission_should_work() {
let pool = pool();
pool.submit_one(&BlockId::number(0), uxt(Alice, 209)).unwrap();
pool.submit_one(&BlockId::number(0), uxt(Alice, 210)).unwrap();
block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap();
block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).unwrap();
let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect();
assert_eq!(pending, vec![209, 210]);
@@ -130,7 +132,7 @@ fn multiple_submission_should_work() {
#[test]
fn early_nonce_should_be_culled() {
let pool = pool();
pool.submit_one(&BlockId::number(0), uxt(Alice, 208)).unwrap();
block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 208))).unwrap();
let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect();
assert_eq!(pending, Vec::<Index>::new());
@@ -140,11 +142,11 @@ fn early_nonce_should_be_culled() {
fn late_nonce_should_be_queued() {
let pool = pool();
pool.submit_one(&BlockId::number(0), uxt(Alice, 210)).unwrap();
block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).unwrap();
let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect();
assert_eq!(pending, Vec::<Index>::new());
pool.submit_one(&BlockId::number(0), uxt(Alice, 209)).unwrap();
block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap();
let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect();
assert_eq!(pending, vec![209, 210]);
}
@@ -152,13 +154,13 @@ fn late_nonce_should_be_queued() {
#[test]
fn prune_tags_should_work() {
let pool = pool();
pool.submit_one(&BlockId::number(0), uxt(Alice, 209)).unwrap();
pool.submit_one(&BlockId::number(0), uxt(Alice, 210)).unwrap();
block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap();
block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).unwrap();
let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect();
assert_eq!(pending, vec![209, 210]);
pool.prune_tags(&BlockId::number(1), vec![vec![209]], vec![]).unwrap();
block_on(pool.prune_tags(&BlockId::number(1), vec![vec![209]], vec![])).unwrap();
let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect();
assert_eq!(pending, vec![210]);
@@ -168,14 +170,14 @@ fn prune_tags_should_work() {
fn should_ban_invalid_transactions() {
let pool = pool();
let uxt = uxt(Alice, 209);
let hash = pool.submit_one(&BlockId::number(0), uxt.clone()).unwrap();
let hash = block_on(pool.submit_one(&BlockId::number(0), uxt.clone())).unwrap();
pool.remove_invalid(&[hash]);
pool.submit_one(&BlockId::number(0), uxt.clone()).unwrap_err();
block_on(pool.submit_one(&BlockId::number(0), uxt.clone())).unwrap_err();
// when
let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect();
assert_eq!(pending, Vec::<Index>::new());
// then
pool.submit_one(&BlockId::number(0), uxt.clone()).unwrap_err();
block_on(pool.submit_one(&BlockId::number(0), uxt.clone())).unwrap_err();
}