mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-30 22:27:56 +00:00
Check in block authoring that we can author with current authoring version (#4201)
* Check in block authoring that we can author with current authoring version * Update client/consensus/pow/src/lib.rs Co-Authored-By: André Silva <andre.beat@gmail.com> * Fix compilation
This commit is contained in:
Generated
+1
@@ -3177,6 +3177,7 @@ dependencies = [
|
||||
"substrate-client 2.0.0",
|
||||
"substrate-consensus-aura 2.0.0",
|
||||
"substrate-consensus-aura-primitives 2.0.0",
|
||||
"substrate-consensus-common 2.0.0",
|
||||
"substrate-executor 2.0.0",
|
||||
"substrate-finality-grandpa 2.0.0",
|
||||
"substrate-finality-grandpa-primitives 2.0.0",
|
||||
|
||||
@@ -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/" }
|
||||
|
||||
@@ -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,
|
||||
@@ -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
|
||||
|
||||
@@ -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" }
|
||||
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
@@ -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)?;
|
||||
|
||||
@@ -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,
|
||||
@@ -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,
|
||||
@@ -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,
|
||||
@@ -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(),
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
@@ -874,6 +877,7 @@ mod tests {
|
||||
inherent_data_providers,
|
||||
false,
|
||||
keystore,
|
||||
consensus_common::AlwaysCanAuthor,
|
||||
).expect("Starts aura");
|
||||
|
||||
runtime.spawn(aura);
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
@@ -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
|
||||
@@ -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 {
|
||||
@@ -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())
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
|
||||
@@ -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};
|
||||
@@ -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,
|
||||
@@ -383,6 +383,7 @@ 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,
|
||||
@@ -390,6 +391,7 @@ pub fn start_mine<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S>(
|
||||
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");
|
||||
@@ -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!(
|
||||
@@ -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,
|
||||
@@ -431,6 +434,7 @@ 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>,
|
||||
@@ -438,6 +442,7 @@ fn mine_loop<B: BlockT<Hash=H256>, C, Algorithm, E, SO, S>(
|
||||
E::Error: std::fmt::Debug,
|
||||
SO: SyncOracle,
|
||||
S: SelectChain<B>,
|
||||
CAW: CanAuthorWith<B>,
|
||||
{
|
||||
'outer: loop {
|
||||
if sync_oracle.is_major_syncing() {
|
||||
@@ -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)))?;
|
||||
|
||||
@@ -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};
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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}};
|
||||
|
||||
@@ -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())))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -547,7 +547,8 @@ fn runtime_version<Block: BlockT, F: Fetcher<Block>>(
|
||||
Bytes(Vec::new()),
|
||||
)
|
||||
.then(|version| ready(version.and_then(|version|
|
||||
Decode::decode(&mut &version.0[..]).map_err(|_| client_err(ClientError::VersionInvalid))
|
||||
Decode::decode(&mut &version.0[..])
|
||||
.map_err(|e| client_err(ClientError::VersionInvalid(e.what().into())))
|
||||
)))
|
||||
}
|
||||
|
||||
@@ -696,7 +697,7 @@ fn ignore_error<F, T>(future: F) -> impl std::future::Future<Output=Result<Optio
|
||||
future.then(|result| ready(match result {
|
||||
Ok(result) => Ok(Some(result)),
|
||||
Err(()) => Ok(None),
|
||||
}))
|
||||
}))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -63,10 +63,10 @@ impl<B, E> Clone for LocalCallExecutor<B, E> where E: Clone {
|
||||
}
|
||||
|
||||
impl<B, E, Block> CallExecutor<Block, Blake2Hasher> for LocalCallExecutor<B, E>
|
||||
where
|
||||
B: backend::Backend<Block, Blake2Hasher>,
|
||||
E: CodeExecutor + RuntimeInfo,
|
||||
Block: BlockT<Hash=H256>,
|
||||
where
|
||||
B: backend::Backend<Block, Blake2Hasher>,
|
||||
E: CodeExecutor + RuntimeInfo,
|
||||
Block: BlockT<Hash=H256>,
|
||||
{
|
||||
type Error = E::Error;
|
||||
|
||||
@@ -202,7 +202,7 @@ where
|
||||
let _lock = self.backend.get_import_lock().read();
|
||||
self.backend.destroy_state(state)?;
|
||||
}
|
||||
version.ok_or(sp_blockchain::Error::VersionInvalid.into())
|
||||
version.map_err(|e| sp_blockchain::Error::VersionInvalid(format!("{:?}", e)).into())
|
||||
}
|
||||
|
||||
fn call_at_state<
|
||||
@@ -268,3 +268,21 @@ where
|
||||
Some(self.executor.native_version())
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, E, Block> runtime_version::GetRuntimeVersion<Block> for LocalCallExecutor<B, E>
|
||||
where
|
||||
B: backend::Backend<Block, Blake2Hasher>,
|
||||
E: CodeExecutor + RuntimeInfo,
|
||||
Block: BlockT<Hash=H256>,
|
||||
{
|
||||
fn native_version(&self) -> &runtime_version::NativeVersion {
|
||||
self.executor.native_version()
|
||||
}
|
||||
|
||||
fn runtime_version(
|
||||
&self,
|
||||
at: &BlockId<Block>,
|
||||
) -> Result<runtime_version::RuntimeVersion, String> {
|
||||
CallExecutor::runtime_version(self, at).map_err(|e| format!("{:?}", e))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1753,9 +1753,10 @@ where
|
||||
}
|
||||
|
||||
impl<BE, E, B, RA> consensus::block_validation::Chain<B> for Client<BE, E, B, RA>
|
||||
where BE: backend::Backend<B, Blake2Hasher>,
|
||||
E: CallExecutor<B, Blake2Hasher>,
|
||||
B: BlockT<Hash = H256>
|
||||
where
|
||||
BE: backend::Backend<B, Blake2Hasher>,
|
||||
E: CallExecutor<B, Blake2Hasher>,
|
||||
B: BlockT<Hash = H256>
|
||||
{
|
||||
fn block_status(&self, id: &BlockId<B>) -> Result<BlockStatus, Box<dyn std::error::Error + Send>> {
|
||||
Client::block_status(self, id).map_err(|e| Box::new(e) as Box<_>)
|
||||
|
||||
@@ -28,7 +28,6 @@ use parity_scale_codec::Error as CodecError;
|
||||
/// Client Result type alias
|
||||
pub type Result<T> = result::Result<T, Error>;
|
||||
|
||||
|
||||
/// Error when the runtime failed to apply an extrinsic.
|
||||
#[derive(Debug, Display)]
|
||||
pub enum ApplyExtrinsicFailed {
|
||||
@@ -72,8 +71,9 @@ pub enum Error {
|
||||
#[display(fmt = "Current state of blockchain has invalid authorities set")]
|
||||
InvalidAuthoritiesSet,
|
||||
/// Could not get runtime version.
|
||||
#[display(fmt = "On-chain runtime does not specify version")]
|
||||
VersionInvalid,
|
||||
#[display(fmt = "Failed to get runtime version: {}", _0)]
|
||||
#[from(ignore)]
|
||||
VersionInvalid(String),
|
||||
/// Genesis config is invalid.
|
||||
#[display(fmt = "Genesis config provided is invalid")]
|
||||
GenesisInvalid,
|
||||
@@ -125,7 +125,6 @@ pub enum Error {
|
||||
InvalidStateRoot,
|
||||
/// A convenience variant for String
|
||||
#[display(fmt = "{}", _0)]
|
||||
#[from(ignore)]
|
||||
Msg(String),
|
||||
}
|
||||
|
||||
@@ -139,12 +138,6 @@ impl error::Error for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Error {
|
||||
fn from(s: String) -> Self {
|
||||
Error::Msg(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for Error {
|
||||
fn from(s: &'a str) -> Self {
|
||||
Error::Msg(s.into())
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use sr_primitives::traits::{Block as BlockT, DigestFor};
|
||||
use sr_primitives::{traits::{Block as BlockT, DigestFor}, generic::BlockId};
|
||||
use futures::prelude::*;
|
||||
pub use inherents::InherentData;
|
||||
|
||||
@@ -123,13 +123,59 @@ impl SyncOracle for NoNetwork {
|
||||
fn is_offline(&mut self) -> bool { false }
|
||||
}
|
||||
|
||||
impl<T> SyncOracle for Arc<T>
|
||||
where T: ?Sized, for<'r> &'r T: SyncOracle
|
||||
{
|
||||
impl<T> SyncOracle for Arc<T> where T: ?Sized, for<'r> &'r T: SyncOracle {
|
||||
fn is_major_syncing(&mut self) -> bool {
|
||||
<&T>::is_major_syncing(&mut &**self)
|
||||
}
|
||||
|
||||
fn is_offline(&mut self) -> bool {
|
||||
<&T>::is_offline(&mut &**self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if the current active native block authoring implementation can author with the runtime
|
||||
/// at the given block.
|
||||
pub trait CanAuthorWith<Block: BlockT> {
|
||||
/// See trait docs for more information.
|
||||
fn can_author_with(&self, at: &BlockId<Block>) -> bool;
|
||||
}
|
||||
|
||||
/// Checks if the node can author blocks by using
|
||||
/// [`NativeVersion::can_author_with`](runtime_version::NativeVersion::can_author_with).
|
||||
pub struct CanAuthorWithNativeVersion<T>(T);
|
||||
|
||||
impl<T> CanAuthorWithNativeVersion<T> {
|
||||
/// Creates a new instance of `Self`.
|
||||
pub fn new(inner: T) -> Self {
|
||||
Self(inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: runtime_version::GetRuntimeVersion<Block>, Block: BlockT> CanAuthorWith<Block>
|
||||
for CanAuthorWithNativeVersion<T>
|
||||
{
|
||||
fn can_author_with(&self, at: &BlockId<Block>) -> bool {
|
||||
match self.0.runtime_version(at) {
|
||||
Ok(version) => self.0.native_version().can_author_with(&version),
|
||||
Err(e) => {
|
||||
error!(
|
||||
target: "CanAuthorWithNativeVersion",
|
||||
"Failed to get runtime version at `{}` and will disable authoring. Error: {}",
|
||||
at,
|
||||
e,
|
||||
);
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns always `true` for `can_author_with`. This is useful for tests.
|
||||
pub struct AlwaysCanAuthor;
|
||||
|
||||
impl<Block: BlockT> CanAuthorWith<Block> for AlwaysCanAuthor {
|
||||
fn can_author_with(&self, _: &BlockId<Block>) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,9 @@ use codec::Decode;
|
||||
use sr_primitives::RuntimeString;
|
||||
pub use sr_primitives::create_runtime_str;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use sr_primitives::{traits::Block as BlockT, generic::BlockId};
|
||||
|
||||
/// The identity of a particular API interface that the runtime might provide.
|
||||
pub type ApiId = [u8; 8];
|
||||
|
||||
@@ -165,6 +168,27 @@ impl NativeVersion {
|
||||
}
|
||||
}
|
||||
|
||||
/// Something that can provide the runtime version at a given block and the native runtime version.
|
||||
#[cfg(feature = "std")]
|
||||
pub trait GetRuntimeVersion<Block: BlockT> {
|
||||
/// Returns the version of the native runtime.
|
||||
fn native_version(&self) -> &NativeVersion;
|
||||
|
||||
/// Returns the version of runtime at the given block.
|
||||
fn runtime_version(&self, at: &BlockId<Block>) -> Result<RuntimeVersion, String>;
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<T: GetRuntimeVersion<Block>, Block: BlockT> GetRuntimeVersion<Block> for std::sync::Arc<T> {
|
||||
fn native_version(&self) -> &NativeVersion {
|
||||
(&**self).native_version()
|
||||
}
|
||||
|
||||
fn runtime_version(&self, at: &BlockId<Block>) -> Result<RuntimeVersion, String> {
|
||||
(&**self).runtime_version(at)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
mod apis_serialize {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user