diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 017bbd5904..42401f8ad0 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -5481,6 +5481,7 @@ dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-block-builder 2.0.0", "substrate-client 2.0.0", @@ -5491,6 +5492,7 @@ dependencies = [ "substrate-telemetry 2.0.0", "substrate-test-runtime-client 2.0.0", "substrate-transaction-pool 2.0.0", + "tokio-executor 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6963,6 +6965,8 @@ version = "0.2.0-alpha.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-sync 0.2.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/substrate/client/basic-authorship/Cargo.toml b/substrate/client/basic-authorship/Cargo.toml index 4d3309fb2d..3732065f8c 100644 --- a/substrate/client/basic-authorship/Cargo.toml +++ b/substrate/client/basic-authorship/Cargo.toml @@ -17,6 +17,8 @@ inherents = { package = "substrate-inherents", path = "../../primitives/inherent substrate-telemetry = { path = "../telemetry" } transaction_pool = { package = "substrate-transaction-pool", path = "../transaction-pool" } block-builder = { package = "substrate-block-builder", path = "../block-builder" } +tokio-executor = { version = "0.2.0-alpha.6", features = ["blocking"] } [dev-dependencies] test-client = { package = "substrate-test-runtime-client", path = "../../test/utils/runtime/client" } +parking_lot = "0.9" diff --git a/substrate/client/basic-authorship/src/basic_authorship.rs b/substrate/client/basic-authorship/src/basic_authorship.rs index 7d8956152c..10b3b2b1a1 100644 --- a/substrate/client/basic-authorship/src/basic_authorship.rs +++ b/substrate/client/basic-authorship/src/basic_authorship.rs @@ -17,7 +17,6 @@ //! A consensus proposer for "basic" chains which use the primitive inherent-data. // FIXME #1021 move this into substrate-consensus-common -// use std::{time, sync::Arc}; use client_api::{error, CallExecutor}; @@ -45,10 +44,47 @@ pub struct ProposerFactory where A: txpool::ChainApi { pub transaction_pool: Arc>, } +impl ProposerFactory, A> +where + A: txpool::ChainApi + 'static, + B: client_api::backend::Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + Clone + 'static, + Block: BlockT, + RA: Send + Sync + 'static, + SubstrateClient: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: + BlockBuilderApi, +{ + pub fn init_with_now( + &mut self, + parent_header: &::Header, + now: Box time::Instant + Send + Sync>, + ) -> Result, A>, error::Error> { + let parent_hash = parent_header.hash(); + + let id = BlockId::hash(parent_hash); + + info!("Starting consensus session on top of parent {:?}", parent_hash); + + let proposer = Proposer { + inner: Arc::new(ProposerInner { + client: self.client.clone(), + parent_hash, + parent_id: id, + parent_number: *parent_header.number(), + transaction_pool: self.transaction_pool.clone(), + now, + }), + }; + + Ok(proposer) + } +} + impl consensus_common::Environment for ProposerFactory, A> where - A: txpool::ChainApi, + A: txpool::ChainApi + 'static, B: client_api::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + Clone + 'static, Block: BlockT, @@ -64,39 +100,29 @@ where &mut self, parent_header: &::Header, ) -> Result { - let parent_hash = parent_header.hash(); - - let id = BlockId::hash(parent_hash); - - info!("Starting consensus session on top of parent {:?}", parent_hash); - - let proposer = Proposer { - client: self.client.clone(), - parent_hash, - parent_id: id, - parent_number: *parent_header.number(), - transaction_pool: self.transaction_pool.clone(), - now: Box::new(time::Instant::now), - }; - - Ok(proposer) + self.init_with_now(parent_header, Box::new(time::Instant::now)) } } /// The proposer logic. pub struct Proposer { + inner: Arc>, +} + +/// Proposer inner, to wrap parameters under Arc. +struct ProposerInner { client: Arc, parent_hash: ::Hash, parent_id: BlockId, parent_number: <::Header as HeaderT>::Number, transaction_pool: Arc>, - now: Box time::Instant>, + now: Box time::Instant + Send + Sync>, } impl consensus_common::Proposer for Proposer, A> where - A: txpool::ChainApi, + A: txpool::ChainApi + 'static, B: client_api::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + Clone + 'static, Block: BlockT, @@ -105,7 +131,7 @@ where as ProvideRuntimeApi>::Api: BlockBuilderApi, { - type Create = futures::future::Ready>; + type Create = tokio_executor::blocking::Blocking>; type Error = error::Error; fn propose( @@ -114,14 +140,17 @@ where inherent_digests: DigestFor, max_duration: time::Duration, ) -> Self::Create { - // leave some time for evaluation and block finalization (33%) - let deadline = (self.now)() + max_duration - max_duration / 3; - futures::future::ready(self.propose_with(inherent_data, inherent_digests, deadline)) + let inner = self.inner.clone(); + tokio_executor::blocking::run(move || { + // leave some time for evaluation and block finalization (33%) + let deadline = (inner.now)() + max_duration - max_duration / 3; + inner.propose_with(inherent_data, inherent_digests, deadline) + }) } } -impl Proposer, A> where - A: txpool::ChainApi, +impl ProposerInner, A> where + A: txpool::ChainApi + 'static, B: client_api::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + Clone + 'static, Block: BlockT, @@ -232,8 +261,8 @@ impl Proposer, A> wh mod tests { use super::*; - use std::cell::RefCell; - use consensus_common::{Environment, Proposer}; + use parking_lot::Mutex; + use consensus_common::Proposer; use test_client::{self, runtime::{Extrinsic, Transfer}, AccountKeyring}; fn extrinsic(nonce: u64) -> Extrinsic { @@ -261,16 +290,19 @@ mod tests { transaction_pool: txpool.clone(), }; - let mut proposer = proposer_factory.init( + let cell = Mutex::new(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; + let new = old + time::Duration::from_secs(2); + *value = new; + old + }) ).unwrap(); // when - let cell = RefCell::new(time::Instant::now()); - proposer.now = Box::new(move || { - let new = *cell.borrow() + time::Duration::from_secs(2); - cell.replace(new) - }); let deadline = time::Duration::from_secs(3); let block = futures::executor::block_on(proposer.propose(Default::default(), Default::default(), deadline)) .unwrap();