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
+22 -6
View File
@@ -963,6 +963,14 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
who: PeerId,
extrinsics: message::Transactions<B::Extrinsic>
) {
// sending extrinsic to light node is considered a bad behavior
if !self.config.roles.is_full() {
trace!(target: "sync", "Peer {} is trying to send extrinsic to the light node", who);
self.behaviour.disconnect_peer(&who);
self.peerset_handle.report_peer(who, i32::min_value());
return;
}
// Accept extrinsics only when fully synced
if self.sync.status().state != SyncState::Idle {
trace!(target: "sync", "{} Ignoring extrinsics while syncing", who);
@@ -971,12 +979,15 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
trace!(target: "sync", "Received {} extrinsics from {}", extrinsics.len(), who);
if let Some(ref mut peer) = self.context_data.peers.get_mut(&who) {
for t in extrinsics {
if let Some(hash) = self.transaction_pool.import(&t) {
self.peerset_handle.report_peer(who.clone(), NEW_EXTRINSIC_REPUTATION_CHANGE);
peer.known_extrinsics.insert(hash);
} else {
trace!(target: "sync", "Extrinsic rejected");
}
let hash = self.transaction_pool.hash_of(&t);
peer.known_extrinsics.insert(hash);
self.transaction_pool.import(
self.peerset_handle.clone().into(),
who.clone(),
NEW_EXTRINSIC_REPUTATION_CHANGE,
t,
);
}
}
}
@@ -995,6 +1006,11 @@ impl<B: BlockT, S: NetworkSpecialization<B>, H: ExHashT> Protocol<B, S, H> {
let extrinsics = self.transaction_pool.transactions();
let mut propagated_to = HashMap::new();
for (who, peer) in self.context_data.peers.iter_mut() {
// never send extrinsics to the light node
if !peer.info.roles.is_full() {
continue;
}
let (hashes, to_send): (Vec<_>, Vec<_>) = extrinsics
.iter()
.filter(|&(ref hash, _)| peer.known_extrinsics.insert(hash.clone()))
+17 -1
View File
@@ -65,8 +65,18 @@ impl<T> ExHashT for T where
pub trait TransactionPool<H: ExHashT, B: BlockT>: Send + Sync {
/// Get transactions from the pool that are ready to be propagated.
fn transactions(&self) -> Vec<(H, B::Extrinsic)>;
/// Get hash of transaction.
fn hash_of(&self, transaction: &B::Extrinsic) -> H;
/// Import a transaction into the pool.
fn import(&self, transaction: &B::Extrinsic) -> Option<H>;
///
/// Peer reputation is changed by reputation_change if transaction is accepted by the pool.
fn import(
&self,
report_handle: ReportHandle,
who: PeerId,
reputation_change: i32,
transaction: B::Extrinsic,
);
/// Notify the pool about transactions broadcast.
fn on_broadcasted(&self, propagations: HashMap<H, Vec<String>>);
}
@@ -77,6 +87,12 @@ pub struct ReportHandle {
inner: PeersetHandle, // wraps it so we don't have to worry about breaking API.
}
impl From<PeersetHandle> for ReportHandle {
fn from(peerset_handle: PeersetHandle) -> Self {
ReportHandle { inner: peerset_handle }
}
}
impl ReportHandle {
/// Report a given peer as either beneficial (+) or costly (-) according to the
/// given scalar.
+5 -3
View File
@@ -47,7 +47,7 @@ use consensus::Error as ConsensusError;
use consensus::{BlockOrigin, ForkChoiceStrategy, BlockImportParams, BlockCheckParams, JustificationImport};
use futures::prelude::*;
use futures03::{StreamExt as _, TryStreamExt as _};
use crate::{NetworkWorker, NetworkService, config::ProtocolId};
use crate::{NetworkWorker, NetworkService, ReportHandle, config::ProtocolId};
use crate::config::{NetworkConfiguration, TransportConfig, BoxFinalityProofRequestBuilder};
use libp2p::PeerId;
use parking_lot::Mutex;
@@ -400,10 +400,12 @@ impl TransactionPool<Hash, Block> for EmptyTransactionPool {
Vec::new()
}
fn import(&self, _transaction: &Extrinsic) -> Option<Hash> {
None
fn hash_of(&self, _transaction: &Extrinsic) -> Hash {
Hash::default()
}
fn import(&self, _report_handle: ReportHandle, _who: PeerId, _rep_change: i32, _transaction: Extrinsic) {}
fn on_broadcasted(&self, _: HashMap<Hash, Vec<String>>) {}
}