Recover transaction pool on light client (#3833)

* recover tx pool on light client

* revert local tests fix

* removed import renamings

* futures03::Future -> std::future::Future

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

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

* replace remove_from_ready with remove_invalid

* avoid excess hashing

* debug -> warn

* TransactionPool + BasicTransactionPool

* pause future tx reject when resubmitting

* bump impl_version to make CI happy

* and revert back local test fixes

* alter doc to restart CI

* Transaction::clone() -> Transaction::duplicate()

* transactions -> updated_tranasctions

* remove explicit consensus-common ref

* ::std:: -> std::

* manual set/unset flag -> calling clusore with given flag value

* removed comments

* removed force argument

* BestIterator -> Box<Iterator>

* separate crate for TxPool + Maintainer trait

* long line fix

* pos-merge fix

* fix benches compilation

* Rename txpoolapi to txpool_api

* Clean up.

* Finalize merge.

* post-merge fix

* Move transaction pool api to primitives directly.

* Consistent naming for txpool-runtime-api

* Warn about missing docs.

* Move  abstraction for offchain calls to tx-pool-api.

* Merge RPC instantiation.

* Update cargo.lock

* Post merge fixes.

* Avoid depending on client.

* Fix build
This commit is contained in:
Svyatoslav Nikolsky
2019-11-28 03:00:54 +03:00
committed by Gavin Wood
parent 3e26fceda4
commit a782021ee8
64 changed files with 2370 additions and 667 deletions
@@ -33,21 +33,21 @@ use sr_primitives::{
},
generic::BlockId,
};
use transaction_pool::txpool::{self, Pool as TransactionPool};
use txpool_api::{TransactionPool, InPoolTransaction};
use substrate_telemetry::{telemetry, CONSENSUS_INFO};
use block_builder::BlockBuilderApi;
/// Proposer factory.
pub struct ProposerFactory<C, A> where A: txpool::ChainApi {
pub struct ProposerFactory<C, A> where A: TransactionPool {
/// The client instance.
pub client: Arc<C>,
/// The transaction pool.
pub transaction_pool: Arc<TransactionPool<A>>,
pub transaction_pool: Arc<A>,
}
impl<B, E, Block, RA, A> ProposerFactory<SubstrateClient<B, E, Block, RA>, A>
where
A: txpool::ChainApi<Block=Block> + 'static,
A: TransactionPool<Block=Block> + 'static,
B: client_api::backend::Backend<Block, Blake2Hasher> + Send + Sync + 'static,
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone + 'static,
Block: BlockT<Hash=H256>,
@@ -85,7 +85,7 @@ where
impl<B, E, Block, RA, A> consensus_common::Environment<Block> for
ProposerFactory<SubstrateClient<B, E, Block, RA>, A>
where
A: txpool::ChainApi<Block=Block> + 'static,
A: TransactionPool<Block=Block> + 'static,
B: client_api::backend::Backend<Block, Blake2Hasher> + Send + Sync + 'static,
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone + 'static,
Block: BlockT<Hash=H256>,
@@ -106,24 +106,24 @@ where
}
/// The proposer logic.
pub struct Proposer<Block: BlockT, C, A: txpool::ChainApi> {
pub struct Proposer<Block: BlockT, C, A: TransactionPool> {
inner: Arc<ProposerInner<Block, C, A>>,
}
/// Proposer inner, to wrap parameters under Arc.
struct ProposerInner<Block: BlockT, C, A: txpool::ChainApi> {
struct ProposerInner<Block: BlockT, C, A: TransactionPool> {
client: Arc<C>,
parent_hash: <Block as BlockT>::Hash,
parent_id: BlockId<Block>,
parent_number: <<Block as BlockT>::Header as HeaderT>::Number,
transaction_pool: Arc<TransactionPool<A>>,
transaction_pool: Arc<A>,
now: Box<dyn Fn() -> time::Instant + Send + Sync>,
}
impl<B, E, Block, RA, A> consensus_common::Proposer<Block> for
Proposer<Block, SubstrateClient<B, E, Block, RA>, A>
where
A: txpool::ChainApi<Block=Block> + 'static,
A: TransactionPool<Block=Block> + 'static,
B: client_api::backend::Backend<Block, Blake2Hasher> + Send + Sync + 'static,
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone + 'static,
Block: BlockT<Hash=H256>,
@@ -151,7 +151,7 @@ where
}
impl<Block, B, E, RA, A> ProposerInner<Block, SubstrateClient<B, E, Block, RA>, A> where
A: txpool::ChainApi<Block=Block> + 'static,
A: TransactionPool<Block=Block> + 'static,
B: client_api::backend::Backend<Block, Blake2Hasher> + Send + Sync + 'static,
E: CallExecutor<Block, Blake2Hasher> + Send + Sync + Clone + 'static,
Block: BlockT<Hash=H256>,
@@ -192,22 +192,24 @@ impl<Block, B, E, RA, A> ProposerInner<Block, SubstrateClient<B, E, Block, RA>,
let pending_iterator = self.transaction_pool.ready();
debug!("Attempting to push transactions from the pool.");
for pending in pending_iterator {
for pending_tx in pending_iterator {
if (self.now)() > deadline {
debug!("Consensus deadline reached when pushing block transactions, proceeding with proposing.");
break;
}
trace!("[{:?}] Pushing to the block.", pending.hash);
match block_builder::BlockBuilder::push(&mut block_builder, pending.data.clone()) {
let pending_tx_data = pending_tx.data().clone();
let pending_tx_hash = pending_tx.hash().clone();
trace!("[{:?}] Pushing to the block.", pending_tx_hash);
match block_builder::BlockBuilder::push(&mut block_builder, pending_tx_data) {
Ok(()) => {
debug!("[{:?}] Pushed to the block.", pending.hash);
debug!("[{:?}] Pushed to the block.", pending_tx_hash);
}
Err(sp_blockchain::Error::ApplyExtrinsicFailed(sp_blockchain::ApplyExtrinsicFailed::Validity(e)))
if e.exhausted_resources() => {
if is_first {
debug!("[{:?}] Invalid transaction: FullBlock on empty block", pending.hash);
unqueue_invalid.push(pending.hash.clone());
debug!("[{:?}] Invalid transaction: FullBlock on empty block", pending_tx_hash);
unqueue_invalid.push(pending_tx_hash);
} else if skipped < MAX_SKIPPED_TRANSACTIONS {
skipped += 1;
debug!(
@@ -220,8 +222,8 @@ impl<Block, B, E, RA, A> ProposerInner<Block, SubstrateClient<B, E, Block, RA>,
}
}
Err(e) => {
debug!("[{:?}] Invalid transaction: {}", pending.hash, e);
unqueue_invalid.push(pending.hash.clone());
debug!("[{:?}] Invalid transaction: {}", pending_tx_hash, e);
unqueue_invalid.push(pending_tx_hash);
}
}
@@ -266,6 +268,7 @@ mod tests {
use parking_lot::Mutex;
use consensus_common::Proposer;
use test_client::{self, runtime::{Extrinsic, Transfer}, AccountKeyring};
use txpool::{BasicPool, FullChainApi};
fn extrinsic(nonce: u64) -> Extrinsic {
Transfer {
@@ -280,11 +283,10 @@ mod tests {
fn should_cease_building_block_when_deadline_is_reached() {
// given
let client = Arc::new(test_client::new());
let chain_api = transaction_pool::FullChainApi::new(client.clone());
let txpool = Arc::new(TransactionPool::new(Default::default(), chain_api));
let txpool = Arc::new(BasicPool::new(Default::default(), FullChainApi::new(client.clone())));
futures::executor::block_on(
txpool.submit_at(&BlockId::number(0), vec![extrinsic(0), extrinsic(1)], false)
txpool.submit_at(&BlockId::number(0), vec![extrinsic(0), extrinsic(1)])
).unwrap();
let mut proposer_factory = ProposerFactory {