mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-13 20:55:50 +00:00
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:
committed by
GitHub
parent
facf31f77e
commit
387c31598d
@@ -36,8 +36,14 @@ use parking_lot::Mutex;
|
||||
use client::{runtime_api::BlockT, Client};
|
||||
use exit_future::Signal;
|
||||
use futures::prelude::*;
|
||||
use futures03::stream::{StreamExt as _, TryStreamExt as _};
|
||||
use network::{NetworkService, NetworkState, specialization::NetworkSpecialization, Event, DhtEvent};
|
||||
use futures03::{
|
||||
future::{ready, FutureExt as _, TryFutureExt as _},
|
||||
stream::{StreamExt as _, TryStreamExt as _},
|
||||
};
|
||||
use network::{
|
||||
NetworkService, NetworkState, specialization::NetworkSpecialization,
|
||||
Event, DhtEvent, PeerId, ReportHandle,
|
||||
};
|
||||
use log::{log, warn, debug, error, Level};
|
||||
use codec::{Encode, Decode};
|
||||
use primitives::{Blake2Hasher, H256};
|
||||
@@ -168,6 +174,7 @@ macro_rules! new_impl {
|
||||
imports_external_transactions: !$config.roles.is_light(),
|
||||
pool: transaction_pool.clone(),
|
||||
client: client.clone(),
|
||||
executor: Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone(), on_exit: exit.clone() }),
|
||||
});
|
||||
|
||||
let protocol_id = {
|
||||
@@ -233,12 +240,13 @@ macro_rules! new_impl {
|
||||
let txpool = txpool.upgrade();
|
||||
|
||||
if let (Some(txpool), Some(client)) = (txpool.as_ref(), wclient.upgrade()) {
|
||||
$maintain_transaction_pool(
|
||||
let future = $maintain_transaction_pool(
|
||||
&BlockId::hash(notification.hash),
|
||||
&*client,
|
||||
&client,
|
||||
&*txpool,
|
||||
¬ification.retracted,
|
||||
).map_err(|e| warn!("Pool error processing new block: {:?}", e))?;
|
||||
let _ = to_spawn_tx_.unbounded_send(future);
|
||||
}
|
||||
|
||||
let offchain = offchain.as_ref().and_then(|o| o.upgrade());
|
||||
@@ -871,6 +879,7 @@ pub struct TransactionPoolAdapter<C, P> {
|
||||
imports_external_transactions: bool,
|
||||
pool: Arc<P>,
|
||||
client: Arc<C>,
|
||||
executor: TaskExecutor,
|
||||
}
|
||||
|
||||
/// Get transactions for propagation.
|
||||
@@ -898,7 +907,7 @@ impl<B, H, C, PoolApi, E> network::TransactionPool<H, B> for
|
||||
TransactionPoolAdapter<C, TransactionPool<PoolApi>>
|
||||
where
|
||||
C: network::ClientHandle<B> + Send + Sync,
|
||||
PoolApi: ChainApi<Block=B, Hash=H, Error=E>,
|
||||
PoolApi: 'static + ChainApi<Block=B, Hash=H, Error=E>,
|
||||
B: BlockT,
|
||||
H: std::hash::Hash + Eq + sr_primitives::traits::Member + sr_primitives::traits::MaybeSerialize,
|
||||
E: txpool::error::IntoPoolError + From<txpool::error::Error>,
|
||||
@@ -907,38 +916,40 @@ where
|
||||
transactions_to_propagate(&self.pool)
|
||||
}
|
||||
|
||||
fn import(&self, transaction: &<B as BlockT>::Extrinsic) -> Option<H> {
|
||||
fn hash_of(&self, transaction: &B::Extrinsic) -> H {
|
||||
self.pool.hash_of(transaction)
|
||||
}
|
||||
|
||||
fn import(&self, report_handle: ReportHandle, who: PeerId, reputation_change: i32, transaction: B::Extrinsic) {
|
||||
if !self.imports_external_transactions {
|
||||
debug!("Transaction rejected");
|
||||
return None;
|
||||
return;
|
||||
}
|
||||
|
||||
let encoded = transaction.encode();
|
||||
match Decode::decode(&mut &encoded[..]) {
|
||||
Ok(uxt) => {
|
||||
let best_block_id = BlockId::hash(self.client.info().chain.best_hash);
|
||||
match self.pool.submit_one(&best_block_id, uxt) {
|
||||
Ok(hash) => Some(hash),
|
||||
Err(e) => match e.into_pool_error() {
|
||||
Ok(txpool::error::Error::AlreadyImported(hash)) => {
|
||||
hash.downcast::<H>().ok()
|
||||
.map(|x| x.as_ref().clone())
|
||||
},
|
||||
Ok(e) => {
|
||||
debug!("Error adding transaction to the pool: {:?}", e);
|
||||
None
|
||||
},
|
||||
Err(e) => {
|
||||
debug!("Error converting pool error: {:?}", e);
|
||||
None
|
||||
},
|
||||
}
|
||||
let import_future = self.pool.submit_one(&best_block_id, uxt);
|
||||
let import_future = import_future
|
||||
.then(move |import_result| {
|
||||
match import_result {
|
||||
Ok(_) => report_handle.report_peer(who, reputation_change),
|
||||
Err(e) => match e.into_pool_error() {
|
||||
Ok(txpool::error::Error::AlreadyImported(_)) => (),
|
||||
Ok(e) => debug!("Error adding transaction to the pool: {:?}", e),
|
||||
Err(e) => debug!("Error converting pool error: {:?}", e),
|
||||
}
|
||||
}
|
||||
ready(Ok(()))
|
||||
})
|
||||
.compat();
|
||||
|
||||
if let Err(e) = self.executor.execute(Box::new(import_future)) {
|
||||
warn!("Error scheduling extrinsic import: {:?}", e);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
debug!("Error decoding transaction {}", e);
|
||||
None
|
||||
}
|
||||
Err(e) => debug!("Error decoding transaction {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -950,6 +961,7 @@ where
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use futures03::executor::block_on;
|
||||
use consensus_common::SelectChain;
|
||||
use sr_primitives::traits::BlindCheckable;
|
||||
use substrate_test_runtime_client::{prelude::*, runtime::{Extrinsic, Transfer}};
|
||||
@@ -961,7 +973,7 @@ mod tests {
|
||||
let client = Arc::new(client);
|
||||
let pool = Arc::new(TransactionPool::new(
|
||||
Default::default(),
|
||||
transaction_pool::ChainApi::new(client.clone())
|
||||
transaction_pool::FullChainApi::new(client.clone())
|
||||
));
|
||||
let best = longest_chain.best_chain().unwrap();
|
||||
let transaction = Transfer {
|
||||
@@ -970,8 +982,8 @@ mod tests {
|
||||
from: AccountKeyring::Alice.into(),
|
||||
to: Default::default(),
|
||||
}.into_signed_tx();
|
||||
pool.submit_one(&BlockId::hash(best.hash()), transaction.clone()).unwrap();
|
||||
pool.submit_one(&BlockId::hash(best.hash()), Extrinsic::IncludeData(vec![1])).unwrap();
|
||||
block_on(pool.submit_one(&BlockId::hash(best.hash()), transaction.clone())).unwrap();
|
||||
block_on(pool.submit_one(&BlockId::hash(best.hash()), Extrinsic::IncludeData(vec![1]))).unwrap();
|
||||
assert_eq!(pool.status().ready, 2);
|
||||
|
||||
// when
|
||||
|
||||
Reference in New Issue
Block a user