diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 5f77a7f38f..e1d9a49793 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -4165,7 +4165,6 @@ dependencies = [ "parity-codec 4.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 2.0.0", "substrate-client 2.0.0", - "substrate-consensus-aura-primitives 2.0.0", "substrate-consensus-common 2.0.0", "substrate-inherents 2.0.0", "substrate-primitives 2.0.0", diff --git a/substrate/core/basic-authorship/Cargo.toml b/substrate/core/basic-authorship/Cargo.toml index ca6e4f0b8a..955677faf0 100644 --- a/substrate/core/basic-authorship/Cargo.toml +++ b/substrate/core/basic-authorship/Cargo.toml @@ -5,17 +5,16 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -log = "0.4" -futures-preview = "0.3.0-alpha.17" -codec = { package = "parity-codec", version = "4.1.1" } -runtime_primitives = { package = "sr-primitives", path = "../../core/sr-primitives" } client = { package = "substrate-client", path = "../../core/client" } -aura_primitives = { package = "substrate-consensus-aura-primitives", path = "../../core/consensus/aura/primitives" } +codec = { package = "parity-codec", version = "4.1.1" } consensus_common = { package = "substrate-consensus-common", path = "../../core/consensus/common" } -primitives = { package = "substrate-primitives", path = "../../core/primitives" } +futures-preview = "0.3.0-alpha.17" inherents = { package = "substrate-inherents", path = "../inherents" } -transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" } +log = "0.4" +primitives = { package = "substrate-primitives", path = "../../core/primitives" } +runtime_primitives = { package = "sr-primitives", path = "../../core/sr-primitives" } substrate-telemetry = { path = "../telemetry" } +transaction_pool = { package = "substrate-transaction-pool", path = "../../core/transaction-pool" } [dev-dependencies] test-client = { package = "substrate-test-runtime-client", path = "../../core/test-runtime/client" } diff --git a/substrate/core/basic-authorship/src/basic_authorship.rs b/substrate/core/basic-authorship/src/basic_authorship.rs index 00408a1545..d7450e4287 100644 --- a/substrate/core/basic-authorship/src/basic_authorship.rs +++ b/substrate/core/basic-authorship/src/basic_authorship.rs @@ -18,101 +18,25 @@ // FIXME #1021 move this into substrate-consensus-common // -use std::{self, time, sync::Arc}; - -use log::{info, debug, trace}; +use std::{time, sync::Arc}; use client::{ - self, error, Client as SubstrateClient, CallExecutor, - block_builder::api::BlockBuilder as BlockBuilderApi, runtime_api::Core, + error, Client as SubstrateClient, CallExecutor, + block_builder::api::BlockBuilder as BlockBuilderApi, }; use codec::Decode; -use consensus_common::{self, evaluation}; +use consensus_common::{evaluation}; +use inherents::InherentData; +use log::{error, info, debug, trace}; use primitives::{H256, Blake2Hasher, ExecutionContext}; +use runtime_primitives::{ApplyError, generic::BlockId}; use runtime_primitives::traits::{ Block as BlockT, Hash as HashT, Header as HeaderT, ProvideRuntimeApi, - DigestFor, + DigestFor, BlakeTwo256, }; -use runtime_primitives::generic::BlockId; -use runtime_primitives::ApplyError; use transaction_pool::txpool::{self, Pool as TransactionPool}; -use inherents::InherentData; use substrate_telemetry::{telemetry, CONSENSUS_INFO}; -/// Build new blocks. -pub trait BlockBuilder { - /// Push an extrinsic onto the block. Fails if the extrinsic is invalid. - fn push_extrinsic(&mut self, extrinsic: ::Extrinsic) -> Result<(), error::Error>; -} - -/// Local client abstraction for the consensus. -pub trait AuthoringApi: Send + Sync + ProvideRuntimeApi where - ::Api: Core -{ - /// The block used for this API type. - type Block: BlockT; - /// The error used by this API type. - type Error: std::error::Error; - - /// Build a block on top of the given block, with inherent extrinsics and - /// inherent digests pre-pushed. - fn build_block) -> ()>( - &self, - at: &BlockId, - inherent_data: InherentData, - inherent_digests: DigestFor, - build_ctx: F, - ) -> Result; -} - -impl<'a, B, E, Block, RA> BlockBuilder - for client::block_builder::BlockBuilder<'a, Block, SubstrateClient> -where - B: client::backend::Backend + 'static, - E: CallExecutor + Send + Sync + Clone + 'static, - Block: BlockT, - RA: Send + Sync + 'static, - SubstrateClient : ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: BlockBuilderApi, -{ - fn push_extrinsic(&mut self, extrinsic: ::Extrinsic) -> Result<(), error::Error> { - client::block_builder::BlockBuilder::push(self, extrinsic).map_err(Into::into) - } -} - -impl AuthoringApi for SubstrateClient where - B: client::backend::Backend + Send + Sync + 'static, - E: CallExecutor + Send + Sync + Clone + 'static, - Block: BlockT, - RA: Send + Sync + 'static, - SubstrateClient : ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: BlockBuilderApi, -{ - type Block = Block; - type Error = client::error::Error; - - fn build_block) -> ()>( - &self, - at: &BlockId, - inherent_data: InherentData, - inherent_digests: DigestFor, - mut build_ctx: F, - ) -> Result { - - let mut block_builder = self.new_block_at(at, inherent_digests)?; - - let runtime_api = self.runtime_api(); - // We don't check the API versions any further here since the dispatch compatibility - // check should be enough. - runtime_api.inherent_extrinsics_with_context(at, ExecutionContext::BlockConstruction, inherent_data)? - .into_iter().try_for_each(|i| block_builder.push(i))?; - - build_ctx(&mut block_builder); - - block_builder.bake().map_err(Into::into) - } -} - /// Proposer factory. pub struct ProposerFactory where A: txpool::ChainApi { /// The client instance. @@ -121,19 +45,23 @@ pub struct ProposerFactory where A: txpool::ChainApi { pub transaction_pool: Arc>, } -impl consensus_common::Environment<::Block> for ProposerFactory where - C: AuthoringApi, - ::Api: BlockBuilderApi<::Block>, - A: txpool::ChainApi::Block>, - client::error::Error: From<::Error>, - Proposer<::Block, C, A>: consensus_common::Proposer<::Block>, +impl consensus_common::Environment for +ProposerFactory, A> +where + A: txpool::ChainApi, + B: client::backend::Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + Clone + 'static, + Block: BlockT, + RA: Send + Sync + 'static, + SubstrateClient: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: BlockBuilderApi, { - type Proposer = Proposer<::Block, C, A>; + type Proposer = Proposer, A>; type Error = error::Error; fn init( - &self, - parent_header: &<::Block as BlockT>::Header, + &mut self, + parent_header: &::Header, ) -> Result { let parent_hash = parent_header.hash(); @@ -164,18 +92,22 @@ pub struct Proposer { now: Box time::Instant>, } -impl consensus_common::Proposer<::Block> for Proposer where - Block: BlockT, - C: AuthoringApi, - ::Api: BlockBuilderApi, +impl consensus_common::Proposer for +Proposer, A> +where A: txpool::ChainApi, - client::error::Error: From<::Error> + B: client::backend::Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + Clone + 'static, + Block: BlockT, + RA: Send + Sync + 'static, + SubstrateClient: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: BlockBuilderApi, { - type Create = futures::future::Ready::Block, error::Error>>; + type Create = futures::future::Ready>; type Error = error::Error; fn propose( - &self, + &mut self, inherent_data: InherentData, inherent_digests: DigestFor, max_duration: time::Duration, @@ -186,80 +118,89 @@ impl consensus_common::Proposer<::Block> for Pro } } -impl Proposer where - Block: BlockT, - C: AuthoringApi, - ::Api: BlockBuilderApi, +impl Proposer, A> where A: txpool::ChainApi, - client::error::Error: From<::Error>, + B: client::backend::Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + Clone + 'static, + Block: BlockT, + RA: Send + Sync + 'static, + SubstrateClient: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: BlockBuilderApi, { fn propose_with( &self, inherent_data: InherentData, inherent_digests: DigestFor, deadline: time::Instant, - ) -> Result<::Block, error::Error> - { - use runtime_primitives::traits::BlakeTwo256; - + ) -> Result { /// If the block is full we will attempt to push at most /// this number of transactions before quitting for real. /// It allows us to increase block utilization. const MAX_SKIPPED_TRANSACTIONS: usize = 8; - let block = self.client.build_block( - &self.parent_id, - inherent_data, - inherent_digests.clone(), - |block_builder| { - // proceed with transactions - let mut is_first = true; - let mut skipped = 0; - let mut unqueue_invalid = Vec::new(); - let pending_iterator = self.transaction_pool.ready(); + let mut block_builder = self.client.new_block_at(&self.parent_id, inherent_digests)?; - debug!("Attempting to push transactions from the pool."); - for pending in pending_iterator { - if (self.now)() > deadline { - debug!("Consensus deadline reached when pushing block transactions, proceeding with proposing."); + // We don't check the API versions any further here since the dispatch compatibility + // check should be enough. + for extrinsic in self.client.runtime_api() + .inherent_extrinsics_with_context( + &self.parent_id, + ExecutionContext::BlockConstruction, + inherent_data + )? + { + block_builder.push(extrinsic)?; + } + + // proceed with transactions + let mut is_first = true; + let mut skipped = 0; + let mut unqueue_invalid = Vec::new(); + let pending_iterator = self.transaction_pool.ready(); + + debug!("Attempting to push transactions from the pool."); + for pending 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 client::block_builder::BlockBuilder::push(&mut block_builder, pending.data.clone()) { + Ok(()) => { + debug!("[{:?}] Pushed to the block.", pending.hash); + } + Err(error::Error::ApplyExtrinsicFailed(ApplyError::FullBlock)) => { + if is_first { + debug!("[{:?}] Invalid transaction: FullBlock on empty block", pending.hash); + unqueue_invalid.push(pending.hash.clone()); + } else if skipped < MAX_SKIPPED_TRANSACTIONS { + skipped += 1; + debug!( + "Block seems full, but will try {} more transactions before quitting.", + MAX_SKIPPED_TRANSACTIONS - skipped + ); + } else { + debug!("Block is full, proceed with proposing."); break; } - - trace!("[{:?}] Pushing to the block.", pending.hash); - match block_builder.push_extrinsic(pending.data.clone()) { - Ok(()) => { - debug!("[{:?}] Pushed to the block.", pending.hash); - } - Err(error::Error::ApplyExtrinsicFailed(ApplyError::FullBlock)) => { - if is_first { - debug!("[{:?}] Invalid transaction: FullBlock on empty block", pending.hash); - unqueue_invalid.push(pending.hash.clone()); - } else if skipped < MAX_SKIPPED_TRANSACTIONS { - skipped += 1; - debug!( - "Block seems full, but will try {} more transactions before quitting.", - MAX_SKIPPED_TRANSACTIONS - skipped - ); - } else { - debug!("Block is full, proceed with proposing."); - break; - } - } - Err(e) => { - debug!("[{:?}] Invalid transaction: {}", pending.hash, e); - unqueue_invalid.push(pending.hash.clone()); - } - } - - is_first = false; } + Err(e) => { + debug!("[{:?}] Invalid transaction: {}", pending.hash, e); + unqueue_invalid.push(pending.hash.clone()); + } + } - self.transaction_pool.remove_invalid(&unqueue_invalid); - })?; + is_first = false; + } + + self.transaction_pool.remove_invalid(&unqueue_invalid); + + let block = block_builder.bake()?; info!("Prepared block for proposing at {} [hash: {:?}; parent_hash: {}; extrinsics: [{}]]", block.header().number(), - <::Block as BlockT>::Hash::from(block.header().hash()), + ::Hash::from(block.header().hash()), block.header().parent_hash(), block.extrinsics() .iter() @@ -269,19 +210,18 @@ impl Proposer where ); telemetry!(CONSENSUS_INFO; "prepared_block_for_proposing"; "number" => ?block.header().number(), - "hash" => ?<::Block as BlockT>::Hash::from(block.header().hash()), + "hash" => ?::Hash::from(block.header().hash()), ); - let substrate_block = Decode::decode(&mut block.encode().as_slice()) - .expect("blocks are defined to serialize to substrate blocks correctly; qed"); + if Decode::decode(&mut block.encode().as_slice()).as_ref() != Some(&block) { + error!("Failed to verify block encoding/decoding"); + } - assert!(evaluation::evaluate_initial( - &substrate_block, - &self.parent_hash, - self.parent_number, - ).is_ok()); + if let Err(err) = evaluation::evaluate_initial(&block, &self.parent_hash, self.parent_number) { + error!("Failed to evaluate authored block: {:?}", err); + } - Ok(substrate_block) + Ok(block) } } @@ -311,7 +251,7 @@ mod tests { txpool.submit_at(&BlockId::number(0), vec![extrinsic(0), extrinsic(1)]).unwrap(); - let proposer_factory = ProposerFactory { + let mut proposer_factory = ProposerFactory { client: client.clone(), transaction_pool: txpool.clone(), }; diff --git a/substrate/core/basic-authorship/src/lib.rs b/substrate/core/basic-authorship/src/lib.rs index 88a55c3bac..e579dadd83 100644 --- a/substrate/core/basic-authorship/src/lib.rs +++ b/substrate/core/basic-authorship/src/lib.rs @@ -15,9 +15,44 @@ // along with Substrate. If not, see . //! Basic implementation of block-authoring logic. - -#![warn(unused_extern_crates)] +//! +//! # Example +//! +//! ``` +//! # use substrate_basic_authorship::ProposerFactory; +//! # use consensus_common::{Environment, Proposer}; +//! # use runtime_primitives::generic::BlockId; +//! # use std::{sync::Arc, time::Duration}; +//! # use test_client::{self, runtime::{Extrinsic, Transfer}, AccountKeyring}; +//! # use transaction_pool::txpool::{self, Pool as TransactionPool}; +//! # let client = Arc::new(test_client::new()); +//! # let chain_api = transaction_pool::ChainApi::new(client.clone()); +//! # let txpool = Arc::new(TransactionPool::new(Default::default(), chain_api)); +//! // The first step is to create a `ProposerFactory`. +//! let mut proposer_factory = ProposerFactory { +//! client: client.clone(), +//! transaction_pool: txpool.clone(), +//! }; +//! +//! // From this factory, we create a `Proposer`. +//! let mut proposer = proposer_factory.init( +//! &client.header(&BlockId::number(0)).unwrap().unwrap(), +//! ).unwrap(); +//! +//! // This `Proposer` allows us to create a block proposition. +//! // The proposer will grab transactions from the transaction pool, and put them into the block. +//! let future = proposer.propose( +//! Default::default(), +//! Default::default(), +//! Duration::from_secs(2) +//! ); +//! +//! // We wait until the proposition is performed. +//! let block = futures::executor::block_on(future).unwrap(); +//! println!("Generated block: {:?}", block); +//! ``` +//! mod basic_authorship; -pub use crate::basic_authorship::{ProposerFactory, BlockBuilder, AuthoringApi, Proposer}; +pub use crate::basic_authorship::{ProposerFactory, Proposer}; diff --git a/substrate/core/consensus/aura/src/lib.rs b/substrate/core/consensus/aura/src/lib.rs index 485d4c78d0..1dd644b751 100644 --- a/substrate/core/consensus/aura/src/lib.rs +++ b/substrate/core/consensus/aura/src/lib.rs @@ -135,7 +135,7 @@ pub fn start_aura( client: Arc, select_chain: SC, block_import: I, - env: Arc, + env: E, sync_oracle: SO, inherent_data_providers: InherentDataProviders, force_authoring: bool, @@ -180,7 +180,7 @@ pub fn start_aura( struct AuraWorker { client: Arc, block_import: Arc>, - env: Arc, + env: E, local_key: Arc

, sync_oracle: SO, force_authoring: bool, @@ -204,7 +204,7 @@ impl SlotWorker for AuraWorker w type OnSlot = Pin> + Send>>; fn on_slot( - &self, + &mut self, chain_head: B::Header, slot_info: SlotInfo, ) -> Self::OnSlot { @@ -212,7 +212,6 @@ impl SlotWorker for AuraWorker w let public_key = self.local_key.public(); let client = self.client.clone(); let block_import = self.block_import.clone(); - let env = self.env.clone(); let (timestamp, slot_num, slot_duration) = (slot_info.timestamp, slot_info.number, slot_info.duration); @@ -253,7 +252,7 @@ impl SlotWorker for AuraWorker w ); // we are the slot author. make a block and sign it. - let proposer = match env.init(&chain_head) { + let mut proposer = match self.env.init(&chain_head) { Ok(p) => p, Err(e) => { warn!("Unable to author block in slot {:?}: {:?}", slot_num, e); @@ -742,7 +741,7 @@ mod tests { type Proposer = DummyProposer; type Error = Error; - fn init(&self, parent_header: &::Header) + fn init(&mut self, parent_header: &::Header) -> Result { Ok(DummyProposer(parent_header.number + 1, self.0.clone())) @@ -754,7 +753,7 @@ mod tests { type Create = future::Ready>; fn propose( - &self, + &mut self, _: InherentData, digests: DigestFor, _: Duration, @@ -841,7 +840,7 @@ mod tests { let select_chain = LongestChain::new( client.backend().clone(), ); - let environ = Arc::new(DummyFactory(client.clone())); + let environ = DummyFactory(client.clone()); import_notifications.push( client.import_notification_stream() .take_while(|n| future::ready(!(n.origin != BlockOrigin::Own && n.header.number() < &5))) @@ -862,7 +861,7 @@ mod tests { client.clone(), select_chain, client, - environ.clone(), + environ, DummyOracle, inherent_data_providers, false, diff --git a/substrate/core/consensus/babe/src/lib.rs b/substrate/core/consensus/babe/src/lib.rs index 38b6257c8a..4f5f9856ff 100644 --- a/substrate/core/consensus/babe/src/lib.rs +++ b/substrate/core/consensus/babe/src/lib.rs @@ -154,7 +154,7 @@ pub struct BabeParams { pub block_import: I, /// The environment - pub env: Arc, + pub env: E, /// A sync oracle pub sync_oracle: SO, @@ -220,7 +220,7 @@ pub fn start_babe(BabeParams { struct BabeWorker { client: Arc, block_import: Arc>, - env: Arc, + env: E, local_key: Arc, sync_oracle: SO, force_authoring: bool, @@ -245,14 +245,13 @@ impl SlotWorker for BabeWorker w type OnSlot = Pin> + Send>>; fn on_slot( - &self, + &mut self, chain_head: B::Header, slot_info: SlotInfo, ) -> Self::OnSlot { let pair = self.local_key.clone(); let ref client = self.client; let block_import = self.block_import.clone(); - let ref env = self.env; let (timestamp, slot_number, slot_duration) = (slot_info.timestamp, slot_info.number, slot_info.duration); @@ -305,7 +304,7 @@ impl SlotWorker for BabeWorker w ); // we are the slot author. make a block and sign it. - let proposer = match env.init(&chain_head) { + let mut proposer = match self.env.init(&chain_head) { Ok(p) => p, Err(e) => { warn!(target: "babe", diff --git a/substrate/core/consensus/babe/src/tests.rs b/substrate/core/consensus/babe/src/tests.rs index 1a68c35dbe..700ef690f3 100644 --- a/substrate/core/consensus/babe/src/tests.rs +++ b/substrate/core/consensus/babe/src/tests.rs @@ -52,7 +52,7 @@ impl Environment for DummyFactory { type Proposer = DummyProposer; type Error = Error; - fn init(&self, parent_header: &::Header) + fn init(&mut self, parent_header: &::Header) -> Result { Ok(DummyProposer(parent_header.number + 1, self.0.clone())) @@ -64,7 +64,7 @@ impl Proposer for DummyProposer { type Create = future::Ready>; fn propose( - &self, + &mut self, _: InherentData, digests: DigestFor, _: Duration, @@ -199,7 +199,7 @@ fn run_one_test() { let mut runtime = current_thread::Runtime::new().unwrap(); for (peer_id, key) in peers { let client = net.lock().peer(*peer_id).client().as_full().unwrap(); - let environ = Arc::new(DummyFactory(client.clone())); + let environ = DummyFactory(client.clone()); import_notifications.push( client.import_notification_stream() .take_while(|n| future::ready(!(n.origin != BlockOrigin::Own && n.header.number() < &5))) @@ -224,7 +224,7 @@ fn run_one_test() { block_import: client.clone(), select_chain, client, - env: environ.clone(), + env: environ, sync_oracle: DummyOracle, inherent_data_providers, force_authoring: false, @@ -236,7 +236,7 @@ fn run_one_test() { net.lock().poll(); Ok::<_, ()>(futures01::Async::NotReady::<()>) })); - + runtime.block_on(future::join_all(import_notifications) .map(|_| Ok::<(), ()>(())).compat()).unwrap(); } diff --git a/substrate/core/consensus/common/src/lib.rs b/substrate/core/consensus/common/src/lib.rs index d901610df9..53816752b1 100644 --- a/substrate/core/consensus/common/src/lib.rs +++ b/substrate/core/consensus/common/src/lib.rs @@ -61,7 +61,7 @@ pub trait Environment { /// Initialize the proposal logic on top of a specific header. Provide /// the authorities at that header. - fn init(&self, parent_header: &B::Header) + fn init(&mut self, parent_header: &B::Header) -> Result; } @@ -78,7 +78,7 @@ pub trait Proposer { type Create: Future>; /// Create a proposal. fn propose( - &self, + &mut self, inherent_data: InherentData, inherent_digests: DigestFor, max_duration: Duration, @@ -92,10 +92,10 @@ pub trait Proposer { pub trait SyncOracle { /// Whether the synchronization service is undergoing major sync. /// Returns true if so. - fn is_major_syncing(&self) -> bool; + fn is_major_syncing(&mut self) -> bool; /// Whether the synchronization service is offline. /// Returns true if so. - fn is_offline(&self) -> bool; + fn is_offline(&mut self) -> bool; } /// A synchronization oracle for when there is no network. @@ -103,16 +103,18 @@ pub trait SyncOracle { pub struct NoNetwork; impl SyncOracle for NoNetwork { - fn is_major_syncing(&self) -> bool { false } - fn is_offline(&self) -> bool { false } + fn is_major_syncing(&mut self) -> bool { false } + fn is_offline(&mut self) -> bool { false } } -impl SyncOracle for Arc { - fn is_major_syncing(&self) -> bool { - T::is_major_syncing(&*self) +impl SyncOracle for Arc +where T: ?Sized, for<'r> &'r T: SyncOracle +{ + fn is_major_syncing(&mut self) -> bool { + <&T>::is_major_syncing(&mut &**self) } - fn is_offline(&self) -> bool { - T::is_offline(&*self) + fn is_offline(&mut self) -> bool { + <&T>::is_offline(&mut &**self) } } diff --git a/substrate/core/consensus/rhd/src/lib.rs b/substrate/core/consensus/rhd/src/lib.rs index 4670cb5dee..281f497cbc 100644 --- a/substrate/core/consensus/rhd/src/lib.rs +++ b/substrate/core/consensus/rhd/src/lib.rs @@ -1392,7 +1392,7 @@ mod tests { type Proposer = DummyProposer; type Error = Error; - fn init(&self, parent_header: &TestHeader, _authorities: &[AuthorityId], _sign_with: Arc) + fn init(&mut self, parent_header: &TestHeader, _authorities: &[AuthorityId], _sign_with: Arc) -> Result { Ok(DummyProposer(parent_header.number + 1)) diff --git a/substrate/core/consensus/slots/src/lib.rs b/substrate/core/consensus/slots/src/lib.rs index 7e39d49651..4cea9d82bf 100644 --- a/substrate/core/consensus/slots/src/lib.rs +++ b/substrate/core/consensus/slots/src/lib.rs @@ -46,7 +46,7 @@ pub trait SlotWorker { type OnSlot: Future>; /// Called when a new slot is triggered. - fn on_slot(&self, chain_head: B::Header, slot_info: SlotInfo) -> Self::OnSlot; + fn on_slot(&mut self, chain_head: B::Header, slot_info: SlotInfo) -> Self::OnSlot; } /// Slot compatible inherent data. @@ -69,8 +69,8 @@ pub trait SlotCompatible { pub fn start_slot_worker( slot_duration: SlotDuration, client: C, - worker: W, - sync_oracle: SO, + mut worker: W, + mut sync_oracle: SO, inherent_data_providers: InherentDataProviders, timestamp_extractor: SC, ) -> impl Future diff --git a/substrate/core/network/src/service.rs b/substrate/core/network/src/service.rs index 5b4c880c89..2075aef286 100644 --- a/substrate/core/network/src/service.rs +++ b/substrate/core/network/src/service.rs @@ -505,11 +505,22 @@ impl, H: ExHashT> NetworkServic impl, H: ExHashT> ::consensus::SyncOracle for NetworkService { - fn is_major_syncing(&self) -> bool { - self.is_major_syncing() + fn is_major_syncing(&mut self) -> bool { + NetworkService::is_major_syncing(self) } - fn is_offline(&self) -> bool { + fn is_offline(&mut self) -> bool { + self.num_connected.load(Ordering::Relaxed) == 0 + } +} + +impl<'a, B: BlockT + 'static, S: NetworkSpecialization, H: ExHashT> + ::consensus::SyncOracle for &'a NetworkService { + fn is_major_syncing(&mut self) -> bool { + NetworkService::is_major_syncing(self) + } + + fn is_offline(&mut self) -> bool { self.num_connected.load(Ordering::Relaxed) == 0 } } diff --git a/substrate/node-template/src/service.rs b/substrate/node-template/src/service.rs index 2a981c3bcc..e5d83a1893 100644 --- a/substrate/node-template/src/service.rs +++ b/substrate/node-template/src/service.rs @@ -70,10 +70,10 @@ construct_service_factory! { |service: Self::FullService| { if let Some(key) = service.authority_key() { info!("Using authority key {}", key.public()); - let proposer = Arc::new(ProposerFactory { + let proposer = ProposerFactory { client: service.client(), transaction_pool: service.transaction_pool(), - }); + }; let client = service.client(); let select_chain = service.select_chain() .ok_or_else(|| ServiceError::SelectChainRequired)?; diff --git a/substrate/node/cli/src/service.rs b/substrate/node/cli/src/service.rs index aeeb8e2061..6c45f45d00 100644 --- a/substrate/node/cli/src/service.rs +++ b/substrate/node/cli/src/service.rs @@ -122,10 +122,10 @@ construct_service_factory! { if let Some(babe_key) = service.authority_key() { info!("Using BABE key {}", babe_key.public()); - let proposer = Arc::new(substrate_basic_authorship::ProposerFactory { + let proposer = substrate_basic_authorship::ProposerFactory { client: service.client(), transaction_pool: service.transaction_pool(), - }); + }; let client = service.client(); let select_chain = service.select_chain() @@ -355,10 +355,10 @@ mod tests { let parent_id = BlockId::number(service.client().info().chain.best_number); let parent_header = service.client().header(&parent_id).unwrap().unwrap(); - let proposer_factory = Arc::new(substrate_basic_authorship::ProposerFactory { + let mut proposer_factory = substrate_basic_authorship::ProposerFactory { client: service.client(), transaction_pool: service.transaction_pool(), - }); + }; let mut digest = Digest::::default(); @@ -381,7 +381,7 @@ mod tests { digest.push(::babe_pre_digest(babe_pre_digest)); - let proposer = proposer_factory.init(&parent_header).unwrap(); + let mut proposer = proposer_factory.init(&parent_header).unwrap(); let new_block = futures03::executor::block_on(proposer.propose( inherent_data, digest,