transaction-pool: drop unpropagable txs if local node cant author blocks (#8048)

* transaction-pool: drop unpropagable txs if local node cant author blocks

* fix test compilation

* transaction-pool: remove unnecessary static bound on CanAuthor

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

* rpc-api: add translation for PoolError::Unactionable

* transaction-pool: add test for rejecting unactionable transactions

* basic-authorship: fix doc test

* transaction-pool: fix benchmark compilation

* transaction-pool: rename CanAuthor to IsValidator

* transaction-pool: nit in error message

Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>
This commit is contained in:
André Silva
2021-02-04 19:18:44 +00:00
committed by GitHub
parent 8e36d87ca8
commit 54def5f3d3
19 changed files with 157 additions and 56 deletions
@@ -90,9 +90,25 @@ pub type ValidatedTransactionFor<B> = ValidatedTransaction<
<B as ChainApi>::Error,
>;
/// A closure that returns true if the local node is a validator that can author blocks.
pub struct IsValidator(Box<dyn Fn() -> bool + Send + Sync>);
impl From<bool> for IsValidator {
fn from(is_validator: bool) -> Self {
IsValidator(Box::new(move || is_validator))
}
}
impl From<Box<dyn Fn() -> bool + Send + Sync>> for IsValidator {
fn from(is_validator: Box<dyn Fn() -> bool + Send + Sync>) -> Self {
IsValidator(is_validator)
}
}
/// Pool that deals with validated transactions.
pub struct ValidatedPool<B: ChainApi> {
api: Arc<B>,
is_validator: IsValidator,
options: Options,
listener: RwLock<Listener<ExtrinsicHash<B>, B>>,
pool: RwLock<base::BasePool<
@@ -116,9 +132,10 @@ where
impl<B: ChainApi> ValidatedPool<B> {
/// Create a new transaction pool.
pub fn new(options: Options, api: Arc<B>) -> Self {
pub fn new(options: Options, is_validator: IsValidator, api: Arc<B>) -> Self {
let base_pool = base::BasePool::new(options.reject_future_transactions);
ValidatedPool {
is_validator,
options,
listener: Default::default(),
api,
@@ -183,6 +200,10 @@ impl<B: ChainApi> ValidatedPool<B> {
fn submit_one(&self, tx: ValidatedTransactionFor<B>) -> Result<ExtrinsicHash<B>, B::Error> {
match tx {
ValidatedTransaction::Valid(tx) => {
if !tx.propagate && !(self.is_validator.0)() {
return Err(error::Error::Unactionable.into());
}
let imported = self.pool.write().import(tx)?;
if let base::Imported::Ready { ref hash, .. } = imported {