Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions bin/node-template/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ txpool-api = { package = "sp-transaction-pool-api", path = "../../primitives/tra
network = { package = "substrate-network", path = "../../client/network" }
aura = { package = "substrate-consensus-aura", path = "../../client/consensus/aura" }
aura-primitives = { package = "substrate-consensus-aura-primitives", path = "../../primitives/consensus/aura" }
consensus-common = { package = "substrate-consensus-common", path = "../../primitives/consensus/common" }
grandpa = { package = "substrate-finality-grandpa", path = "../../client/finality-grandpa" }
grandpa-primitives = { package = "substrate-finality-grandpa-primitives", path = "../../primitives/finality-grandpa" }
substrate-client = { path = "../../client/" }
Expand Down
6 changes: 5 additions & 1 deletion bin/node-template/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@ pub fn new_full<C: Send + Default + 'static>(config: Configuration<C, GenesisCon
let select_chain = service.select_chain()
.ok_or(ServiceError::SelectChainRequired)?;

let aura = aura::start_aura::<_, _, _, _, _, AuraPair, _, _, _>(
let can_author_with =
consensus_common::CanAuthorWithNativeVersion::new(client.executor().clone());

let aura = aura::start_aura::<_, _, _, _, _, AuraPair, _, _, _, _>(
aura::SlotDuration::get_or_compute(&*client)?,
client,
select_chain,
Expand All @@ -121,6 +124,7 @@ pub fn new_full<C: Send + Default + 'static>(config: Configuration<C, GenesisCon
inherent_data_providers.clone(),
force_authoring,
service.keystore(),
can_author_with,
)?;

// the AURA authoring task is considered essential, i.e. if it
Expand Down
2 changes: 1 addition & 1 deletion bin/node/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ substrate-basic-authorship = { path = "../../../client/basic-authorship" }
substrate-service = { path = "../../../client/service", default-features = false }
substrate-telemetry = { package = "substrate-telemetry", path = "../../../client/telemetry" }
authority-discovery = { package = "substrate-authority-discovery", path = "../../../client/authority-discovery"}
consensus-common = { package = "substrate-consensus-common", path = "../../../primitives/consensus/common" }

# frame dependencies
indices = { package = "pallet-indices", path = "../../../frame/indices" }
Expand Down Expand Up @@ -99,7 +100,6 @@ rand6 = { package = "rand", version = "0.6", features = ["wasm-bindgen"], option
[dev-dependencies]
keystore = { package = "substrate-keystore", path = "../../../client/keystore" }
babe = { package = "substrate-consensus-babe", path = "../../../client/consensus/babe", features = ["test-helpers"] }
consensus-common = { package = "substrate-consensus-common", path = "../../../primitives/consensus/common" }
service-test = { package = "substrate-service-test", path = "../../../client/service/test" }
futures = "0.3.1"
tempfile = "3.1.0"
Expand Down
4 changes: 4 additions & 0 deletions bin/node/cli/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ macro_rules! new_full {
let select_chain = service.select_chain()
.ok_or(substrate_service::Error::SelectChainRequired)?;

let can_author_with =
consensus_common::CanAuthorWithNativeVersion::new(client.executor().clone());

let babe_config = babe::BabeParams {
keystore: service.keystore(),
client,
Expand All @@ -179,6 +182,7 @@ macro_rules! new_full {
inherent_data_providers: inherent_data_providers.clone(),
force_authoring,
babe_link,
can_author_with,
};

let babe = babe::start_babe(babe_config)?;
Expand Down
16 changes: 10 additions & 6 deletions client/consensus/aura/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@
use std::{sync::Arc, time::Duration, thread, marker::PhantomData, hash::Hash, fmt::Debug, pin::Pin};

use codec::{Encode, Decode, Codec};
use consensus_common::{self, BlockImport, Environment, Proposer,
ForkChoiceStrategy, BlockImportParams, BlockOrigin, Error as ConsensusError,
SelectChain,
use consensus_common::{
self, BlockImport, Environment, Proposer, CanAuthorWith, ForkChoiceStrategy, BlockImportParams,
BlockOrigin, Error as ConsensusError, SelectChain,
};
use consensus_common::import_queue::{
Verifier, BasicQueue, BoxBlockImport, BoxJustificationImport, BoxFinalityProofImport,
Expand Down Expand Up @@ -143,7 +143,7 @@ impl SlotCompatible for AuraSlotCompatible {
}

/// Start the aura worker. The returned future should be run in a futures executor.
pub fn start_aura<B, C, SC, E, I, P, SO, Error, H>(
pub fn start_aura<B, C, SC, E, I, P, SO, CAW, Error, H>(
slot_duration: SlotDuration,
client: Arc<C>,
select_chain: SC,
Expand All @@ -153,6 +153,7 @@ pub fn start_aura<B, C, SC, E, I, P, SO, Error, H>(
inherent_data_providers: InherentDataProviders,
force_authoring: bool,
keystore: KeyStorePtr,
can_author_with: CAW,
) -> Result<impl futures01::Future<Item = (), Error = ()>, consensus_common::Error> where
B: BlockT<Header=H>,
C: ProvideRuntimeApi + BlockOf + ProvideCache<B> + AuxStore + Send + Sync,
Expand All @@ -168,6 +169,7 @@ pub fn start_aura<B, C, SC, E, I, P, SO, Error, H>(
I: BlockImport<B> + Send + Sync + 'static,
Error: ::std::error::Error + Send + From<::consensus_common::Error> + From<I::Error> + 'static,
SO: SyncOracle + Send + Sync + Clone,
CAW: CanAuthorWith<B> + Send,
{
let worker = AuraWorker {
client: client.clone(),
Expand All @@ -182,13 +184,14 @@ pub fn start_aura<B, C, SC, E, I, P, SO, Error, H>(
&inherent_data_providers,
slot_duration.0.slot_duration()
)?;
Ok(slots::start_slot_worker::<_, _, _, _, _, AuraSlotCompatible>(
Ok(slots::start_slot_worker::<_, _, _, _, _, AuraSlotCompatible, _>(
slot_duration.0,
select_chain,
worker,
sync_oracle,
inherent_data_providers,
AuraSlotCompatible,
can_author_with,
).map(|()| Ok::<(), ()>(())).compat())
}

Expand Down Expand Up @@ -864,7 +867,7 @@ mod tests {
&inherent_data_providers, slot_duration.get()
).expect("Registers aura inherent data provider");

let aura = start_aura::<_, _, _, _, _, AuthorityPair, _, _, _>(
let aura = start_aura::<_, _, _, _, _, AuthorityPair, _, _, _, _>(
slot_duration,
client.clone(),
select_chain,
Expand All @@ -874,6 +877,7 @@ mod tests {
inherent_data_providers,
false,
keystore,
consensus_common::AlwaysCanAuthor,
).expect("Starts aura");

runtime.spawn(aura);
Expand Down
14 changes: 10 additions & 4 deletions client/consensus/babe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub use babe_primitives::{
pub use consensus_common::SyncOracle;
use std::{collections::HashMap, sync::Arc, u64, pin::Pin, time::{Instant, Duration}};
use babe_primitives;
use consensus_common::ImportResult;
use consensus_common::{ImportResult, CanAuthorWith};
use consensus_common::import_queue::{
BoxJustificationImport, BoxFinalityProofImport,
};
Expand Down Expand Up @@ -241,7 +241,7 @@ impl std::ops::Deref for Config {
}

/// Parameters for BABE.
pub struct BabeParams<B: BlockT, C, E, I, SO, SC> {
pub struct BabeParams<B: BlockT, C, E, I, SO, SC, CAW> {
/// The keystore that manages the keys of the node.
pub keystore: KeyStorePtr,

Expand Down Expand Up @@ -270,10 +270,13 @@ pub struct BabeParams<B: BlockT, C, E, I, SO, SC> {

/// The source of timestamps for relative slots
pub babe_link: BabeLink<B>,

/// Checks if the current native implementation can author with a runtime at a given block.
pub can_author_with: CAW,
}

/// Start the babe worker. The returned future should be run in a tokio runtime.
pub fn start_babe<B, C, SC, E, I, SO, Error>(BabeParams {
pub fn start_babe<B, C, SC, E, I, SO, CAW, Error>(BabeParams {
keystore,
client,
select_chain,
Expand All @@ -283,7 +286,8 @@ pub fn start_babe<B, C, SC, E, I, SO, Error>(BabeParams {
inherent_data_providers,
force_authoring,
babe_link,
}: BabeParams<B, C, E, I, SO, SC>) -> Result<
can_author_with,
}: BabeParams<B, C, E, I, SO, SC, CAW>) -> Result<
impl futures01::Future<Item=(), Error=()>,
consensus_common::Error,
> where
Expand All @@ -298,6 +302,7 @@ pub fn start_babe<B, C, SC, E, I, SO, Error>(BabeParams {
I: BlockImport<B,Error=ConsensusError> + Send + Sync + 'static,
Error: std::error::Error + Send + From<::consensus_common::Error> + From<I::Error> + 'static,
SO: SyncOracle + Send + Sync + Clone,
CAW: CanAuthorWith<B> + Send,
{
let config = babe_link.config;
let worker = BabeWorker {
Expand Down Expand Up @@ -326,6 +331,7 @@ pub fn start_babe<B, C, SC, E, I, SO, Error>(BabeParams {
sync_oracle,
inherent_data_providers,
babe_link.time_source,
can_author_with,
);

Ok(slot_worker.map(|_| Ok::<(), ()>(())).compat())
Expand Down
1 change: 1 addition & 0 deletions client/consensus/babe/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ fn run_one_test(
force_authoring: false,
babe_link: data.link.clone(),
keystore,
can_author_with: consensus_common::AlwaysCanAuthor,
}).expect("Starts babe"));
}

Expand Down
24 changes: 20 additions & 4 deletions client/consensus/pow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use primitives::H256;
use inherents::{InherentDataProviders, InherentData};
use consensus_common::{
BlockImportParams, BlockOrigin, ForkChoiceStrategy, SyncOracle, Environment, Proposer,
SelectChain, Error as ConsensusError
SelectChain, Error as ConsensusError, CanAuthorWith,
};
use consensus_common::import_queue::{BoxBlockImport, BasicQueue, Verifier};
use codec::{Encode, Decode};
Expand Down Expand Up @@ -372,7 +372,7 @@ pub fn import_queue<B, C, S, Algorithm>(
/// information, or just be a graffiti. `round` is for number of rounds the
/// CPU miner runs each time. This parameter should be tweaked so that each
/// mining round is within sub-second time.
pub fn start_mine<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S>(
pub fn start_mine<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S, CAW>(
mut block_import: BoxBlockImport<B>,
client: Arc<C>,
algorithm: Algorithm,
Expand All @@ -383,13 +383,15 @@ pub fn start_mine<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S>(
build_time: std::time::Duration,
select_chain: Option<S>,
inherent_data_providers: inherents::InherentDataProviders,
can_author_with: CAW,
) where
C: HeaderBackend<B> + AuxStore + 'static,
Algorithm: PowAlgorithm<B> + Send + Sync + 'static,
E: Environment<B> + Send + Sync + 'static,
E::Error: std::fmt::Debug,
SO: SyncOracle + Send + Sync + 'static,
S: SelectChain<B> + 'static,
CAW: CanAuthorWith<B> + Send + 'static,
{
if let Err(_) = register_pow_inherent_data_provider(&inherent_data_providers) {
warn!("Registering inherent data provider for timestamp failed");
Expand All @@ -407,7 +409,8 @@ pub fn start_mine<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S>(
&mut sync_oracle,
build_time.clone(),
select_chain.as_ref(),
&inherent_data_providers
&inherent_data_providers,
&can_author_with,
) {
Ok(()) => (),
Err(e) => error!(
Expand All @@ -420,7 +423,7 @@ pub fn start_mine<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S>(
});
}

fn mine_loop<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S>(
fn mine_loop<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S, CAW>(
block_import: &mut BoxBlockImport<B>,
client: &C,
algorithm: &Algorithm,
Expand All @@ -431,13 +434,15 @@ fn mine_loop<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S>(
build_time: std::time::Duration,
select_chain: Option<&S>,
inherent_data_providers: &inherents::InherentDataProviders,
can_author_with: &CAW,
) -> Result<(), Error<B>> where
C: HeaderBackend<B> + AuxStore,
Algorithm: PowAlgorithm<B>,
E: Environment<B>,
E::Error: std::fmt::Debug,
SO: SyncOracle,
S: SelectChain<B>,
CAW: CanAuthorWith<B>,
{
'outer: loop {
if sync_oracle.is_major_syncing() {
Expand All @@ -461,6 +466,17 @@ fn mine_loop<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S>(
(hash, header)
},
};

if can_author_with.can_author_with(&BlockId::Hash(best_hash)) {
debug!(
target: "pow",
"Skipping proposal `can_author_with` returned `false`. \
Probably a node update is required!"
);
std::thread::sleep(std::time::Duration::from_secs(1));
continue 'outer
}

let mut aux = PowAux::read(client, &best_hash)?;
let mut proposer = env.init(&best_header)
.map_err(|e| Error::Environment(format!("{:?}", e)))?;
Expand Down
32 changes: 23 additions & 9 deletions client/consensus/slots/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use slots::Slots;
pub use aux_schema::{check_equivocation, MAX_SLOT_CAPACITY, PRUNING_BOUND};

use codec::{Decode, Encode};
use consensus_common::{BlockImport, Proposer, SyncOracle, SelectChain};
use consensus_common::{BlockImport, Proposer, SyncOracle, SelectChain, CanAuthorWith};
use futures::{prelude::*, future::{self, Either}};
use futures_timer::Delay;
use inherents::{InherentData, InherentDataProviders};
Expand Down Expand Up @@ -304,22 +304,24 @@ pub trait SlotCompatible {
///
/// Every time a new slot is triggered, `worker.on_slot` is called and the future it returns is
/// polled until completion, unless we are major syncing.
pub fn start_slot_worker<B, C, W, T, SO, SC>(
pub fn start_slot_worker<B, C, W, T, SO, SC, CAW>(
slot_duration: SlotDuration<T>,
client: C,
mut worker: W,
mut sync_oracle: SO,
inherent_data_providers: InherentDataProviders,
timestamp_extractor: SC,
can_author_with: CAW,
) -> impl Future<Output = ()>
where
B: BlockT,
C: SelectChain<B> + Clone,
C: SelectChain<B>,
W: SlotWorker<B>,
W::OnSlot: Unpin,
SO: SyncOracle + Send + Clone,
SO: SyncOracle + Send,
SC: SlotCompatible + Unpin,
T: SlotData + Clone,
CAW: CanAuthorWith<B> + Send,
{
let SlotDuration(slot_duration) = slot_duration;

Expand All @@ -346,11 +348,23 @@ where
}
};

Either::Left(worker.on_slot(chain_head, slot_info).map_err(
|e| {
warn!(target: "slots", "Encountered consensus error: {:?}", e);
}).or_else(|_| future::ready(Ok(())))
)
if can_author_with.can_author_with(&BlockId::Hash(chain_head.hash())) {
Either::Left(
worker.on_slot(chain_head, slot_info)
.map_err(|e| {
warn!(target: "slots", "Encountered consensus error: {:?}", e);
})
.or_else(|_| future::ready(Ok(())))
)
} else {
warn!(
target: "slots",
"Unable to author block in slot {}. `can_author_with` returned `false`. \
Probably a node update is required!",
slot_num,
);
Either::Right(future::ready(Ok(())))
}
}).then(|res| {
if let Err(err) = res {
warn!(target: "slots", "Slots stream terminated with an error: {:?}", err);
Expand Down
5 changes: 1 addition & 4 deletions client/executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,7 @@ pub trait RuntimeInfo {
fn native_version(&self) -> &NativeVersion;

/// Extract RuntimeVersion of given :code block
fn runtime_version<E: Externalities> (
&self,
ext: &mut E,
) -> Option<RuntimeVersion>;
fn runtime_version<E: Externalities> (&self, ext: &mut E) -> error::Result<RuntimeVersion>;
}

#[cfg(test)]
Expand Down
12 changes: 3 additions & 9 deletions client/executor/src/native_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use codec::{Decode, Encode};

use primitives::{NativeOrEncoded, traits::{CodeExecutor, Externalities}};

use log::{trace, warn};
use log::trace;

use std::{result, cell::RefCell, panic::{UnwindSafe, AssertUnwindSafe}};

Expand Down Expand Up @@ -181,14 +181,8 @@ impl<D: NativeExecutionDispatch> RuntimeInfo for NativeExecutor<D> {
fn runtime_version<E: Externalities>(
&self,
ext: &mut E,
) -> Option<RuntimeVersion> {
match self.with_runtime(ext, |_runtime, version, _ext| Ok(Ok(version.clone()))) {
Ok(version) => Some(version),
Err(e) => {
warn!(target: "executor", "Failed to fetch runtime: {:?}", e);
None
}
}
) -> Result<RuntimeVersion> {
self.with_runtime(ext, |_runtime, version, _ext| Ok(Ok(version.clone())))
}
}

Expand Down
Loading