Produce block always on updated transaction pool state (#5227)

* make sure return ready iterator once state is updated

* update sc_basic_authorship tests

* update node tests

* fix manual seal

* actually fix service test

* add tests

* Update client/basic-authorship/src/basic_authorship.rs

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

* helper function

* review suggestions

* warning and continue

* add debug log

* use futures::chennel::oneshot

* use declaration bound

* no option for updated_at

* no allocation

* ready_at / ready

* Update client/transaction-pool/src/lib.rs

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* Update client/transaction-pool/src/lib.rs

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* Update client/transaction-pool/src/lib.rs

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* Update client/transaction-pool/src/lib.rs

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* Update client/transaction-pool/src/lib.rs

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* Update client/transaction-pool/src/lib.rs

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Nikolay Volf
2020-03-17 08:24:04 -07:00
committed by GitHub
parent bbf5bc6acf
commit db86094b03
12 changed files with 257 additions and 25 deletions
@@ -33,7 +33,7 @@ use sp_transaction_pool::{TransactionPool, InPoolTransaction};
use sc_telemetry::{telemetry, CONSENSUS_INFO};
use sc_block_builder::{BlockBuilderApi, BlockBuilderProvider};
use sp_api::{ProvideRuntimeApi, ApiExt};
use futures::prelude::*;
use futures::{executor, future, future::Either};
use sp_blockchain::{HeaderBackend, ApplyExtrinsicFailed};
use std::marker::PhantomData;
@@ -210,7 +210,18 @@ impl<A, B, Block, C> ProposerInner<B, Block, C, A>
let mut is_first = true;
let mut skipped = 0;
let mut unqueue_invalid = Vec::new();
let pending_iterator = self.transaction_pool.ready();
let pending_iterator = match executor::block_on(future::select(
self.transaction_pool.ready_at(self.parent_number),
futures_timer::Delay::new((deadline - (self.now)()) / 8),
)) {
Either::Left((iterator, _)) => iterator,
Either::Right(_) => {
log::warn!(
"Timeout fired waiting for transaction pool to be ready. Proceeding to block production anyway.",
);
self.transaction_pool.ready()
}
};
debug!("Attempting to push transactions from the pool.");
debug!("Pool status: {:?}", self.transaction_pool.status());
@@ -304,10 +315,12 @@ mod tests {
prelude::*,
runtime::{Extrinsic, Transfer},
};
use sp_transaction_pool::{ChainEvent, MaintainedTransactionPool};
use sc_transaction_pool::{BasicPool, FullChainApi};
use sp_api::Core;
use backend::Backend;
use sp_blockchain::HeaderBackend;
use sp_runtime::traits::NumberFor;
fn extrinsic(nonce: u64) -> Extrinsic {
Transfer {
@@ -318,6 +331,17 @@ mod tests {
}.into_signed_tx()
}
fn chain_event<B: BlockT>(block_number: u64, header: B::Header) -> ChainEvent<B>
where NumberFor<B>: From<u64>
{
ChainEvent::NewBlock {
id: BlockId::Number(block_number.into()),
retracted: vec![],
is_new_best: true,
header: header,
}
}
#[test]
fn should_cease_building_block_when_deadline_is_reached() {
// given
@@ -330,16 +354,27 @@ mod tests {
txpool.submit_at(&BlockId::number(0), vec![extrinsic(0), extrinsic(1)])
).unwrap();
futures::executor::block_on(
txpool.maintain(chain_event(
0,
client.header(&BlockId::Number(0u64)).expect("header get error").expect("there should be header")
))
);
let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone());
let cell = Mutex::new(time::Instant::now());
let cell = Mutex::new((false, time::Instant::now()));
let mut proposer = proposer_factory.init_with_now(
&client.header(&BlockId::number(0)).unwrap().unwrap(),
Box::new(move || {
let mut value = cell.lock();
let old = *value;
if !value.0 {
value.0 = true;
return value.1;
}
let old = value.1;
let new = old + time::Duration::from_secs(2);
*value = new;
*value = (true, new);
old
})
);
@@ -371,6 +406,13 @@ mod tests {
txpool.submit_at(&BlockId::number(0), vec![extrinsic(0)]),
).unwrap();
futures::executor::block_on(
txpool.maintain(chain_event(
0,
client.header(&BlockId::Number(0u64)).expect("header get error").expect("there should be header")
))
);
let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone());
let mut proposer = proposer_factory.init_with_now(
@@ -459,15 +501,26 @@ mod tests {
block
};
futures::executor::block_on(
txpool.maintain(chain_event(
0,
client.header(&BlockId::Number(0u64)).expect("header get error").expect("there should be header")
))
);
// let's create one block and import it
let block = propose_block(&client, 0, 2, 7);
client.import(BlockOrigin::Own, block).unwrap();
// now let's make sure that we can still make some progress
futures::executor::block_on(
txpool.maintain(chain_event(
1,
client.header(&BlockId::Number(1)).expect("header get error").expect("there should be header")
))
);
// This is most likely incorrect, and caused by #5139
let tx_remaining = 0;
let block = propose_block(&client, 1, 2, tx_remaining);
// now let's make sure that we can still make some progress
let block = propose_block(&client, 1, 2, 5);
client.import(BlockOrigin::Own, block).unwrap();
}
}