diff --git a/substrate/bin/node-template/node/src/service.rs b/substrate/bin/node-template/node/src/service.rs index c73956d885..86b57f689e 100644 --- a/substrate/bin/node-template/node/src/service.rs +++ b/substrate/bin/node-template/node/src/service.rs @@ -30,12 +30,7 @@ pub fn new_partial(config: &Configuration) -> Result, sc_transaction_pool::FullPool, ( - sc_consensus_aura::AuraBlockImport< - Block, - FullClient, - sc_finality_grandpa::GrandpaBlockImport, - AuraPair - >, + sc_finality_grandpa::GrandpaBlockImport, sc_finality_grandpa::LinkHalf, Option, ) @@ -84,15 +79,11 @@ pub fn new_partial(config: &Configuration) -> Result::new( - grandpa_block_import.clone(), client.clone(), - ); - let slot_duration = sc_consensus_aura::slot_duration(&*client)?.slot_duration(); let import_queue = sc_consensus_aura::import_queue::( ImportQueueParams { - block_import: aura_block_import.clone(), + block_import: grandpa_block_import.clone(), justification_import: Some(Box::new(grandpa_block_import.clone())), client: client.clone(), create_inherent_data_providers: move |_, ()| async move { @@ -122,7 +113,7 @@ pub fn new_partial(config: &Configuration) -> Result Result telemetry.as_ref().map(|x| x.handle()), )?; - let aura_block_import = sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new( - grandpa_block_import.clone(), - client.clone(), - ); - let slot_duration = sc_consensus_aura::slot_duration(&*client)?.slot_duration(); let import_queue = sc_consensus_aura::import_queue::( ImportQueueParams { - block_import: aura_block_import.clone(), + block_import: grandpa_block_import.clone(), justification_import: Some(Box::new(grandpa_block_import.clone())), client: client.clone(), create_inherent_data_providers: move |_, ()| async move { diff --git a/substrate/client/consensus/aura/src/import_queue.rs b/substrate/client/consensus/aura/src/import_queue.rs index 6bf9f69722..8034fd08a7 100644 --- a/substrate/client/consensus/aura/src/import_queue.rs +++ b/substrate/client/consensus/aura/src/import_queue.rs @@ -20,23 +20,23 @@ use crate::{AuthorityId, find_pre_digest, slot_author, aura_err, Error, authorities}; use std::{ - sync::Arc, marker::PhantomData, hash::Hash, fmt::Debug, collections::HashMap, + sync::Arc, marker::PhantomData, hash::Hash, fmt::Debug, }; use log::{debug, info, trace}; use prometheus_endpoint::Registry; use codec::{Encode, Decode, Codec}; use sp_consensus::{ BlockImport, CanAuthorWith, ForkChoiceStrategy, BlockImportParams, - BlockOrigin, Error as ConsensusError, BlockCheckParams, ImportResult, + BlockOrigin, Error as ConsensusError, import_queue::{ Verifier, BasicQueue, DefaultImportQueue, BoxJustificationImport, }, }; -use sc_client_api::{backend::AuxStore, BlockOf}; +use sc_client_api::{BlockOf, UsageProvider, backend::AuxStore}; use sp_blockchain::{well_known_cache_keys::{self, Id as CacheKeyId}, ProvideCache, HeaderBackend}; use sp_block_builder::BlockBuilder as BlockBuilderApi; use sp_runtime::{generic::{BlockId, OpaqueDigestItemId}, Justifications}; -use sp_runtime::traits::{Block as BlockT, Header, DigestItemFor, Zero}; +use sp_runtime::traits::{Block as BlockT, Header, DigestItemFor}; use sp_api::ProvideRuntimeApi; use sp_core::crypto::Pair; use sp_inherents::{CreateInherentDataProviders, InherentDataProvider as _}; @@ -113,19 +113,19 @@ fn check_header( } /// A verifier for Aura blocks. -pub struct AuraVerifier { +pub struct AuraVerifier { client: Arc, phantom: PhantomData

, - create_inherent_data_providers: IDP, + create_inherent_data_providers: CIDP, can_author_with: CAW, check_for_equivocation: CheckForEquivocation, telemetry: Option, } -impl AuraVerifier { +impl AuraVerifier { pub(crate) fn new( client: Arc, - create_inherent_data_providers: IDP, + create_inherent_data_providers: CIDP, can_author_with: CAW, check_for_equivocation: CheckForEquivocation, telemetry: Option, @@ -141,21 +141,21 @@ impl AuraVerifier { } } -impl AuraVerifier where +impl AuraVerifier where P: Send + Sync + 'static, CAW: Send + Sync + 'static, - IDP: Send, + CIDP: Send, { async fn check_inherents( &self, block: B, block_id: BlockId, inherent_data: sp_inherents::InherentData, - create_inherent_data_providers: IDP::InherentDataProviders, + create_inherent_data_providers: CIDP::InherentDataProviders, ) -> Result<(), Error> where C: ProvideRuntimeApi, C::Api: BlockBuilderApi, CAW: CanAuthorWith, - IDP: CreateInherentDataProviders, + CIDP: CreateInherentDataProviders, { if let Err(e) = self.can_author_with.can_author_with(&block_id) { debug!( @@ -187,7 +187,7 @@ impl AuraVerifier where } #[async_trait::async_trait] -impl Verifier for AuraVerifier where +impl Verifier for AuraVerifier where C: ProvideRuntimeApi + Send + Sync + @@ -200,8 +200,8 @@ impl Verifier for AuraVerifier whe P::Public: Send + Sync + Hash + Eq + Clone + Decode + Encode + Debug + 'static, P::Signature: Encode + Decode, CAW: CanAuthorWith + Send + Sync + 'static, - IDP: CreateInherentDataProviders + Send + Sync, - IDP::InherentDataProviders: InherentDataProviderExt + Send + Sync, + CIDP: CreateInherentDataProviders + Send + Sync, + CIDP::InherentDataProviders: InherentDataProviderExt + Send + Sync, { async fn verify( &mut self, @@ -320,7 +320,7 @@ impl Verifier for AuraVerifier whe fn initialize_authorities_cache(client: &C) -> Result<(), ConsensusError> where A: Codec + Debug, B: BlockT, - C: ProvideRuntimeApi + BlockOf + ProvideCache, + C: ProvideRuntimeApi + BlockOf + ProvideCache + UsageProvider, C::Api: AuraApi, { // no cache => no initialization @@ -329,6 +329,8 @@ fn initialize_authorities_cache(client: &C) -> Result<(), ConsensusErro None => return Ok(()), }; + let best_hash = client.usage_info().chain.best_hash; + // check if we already have initialized the cache let map_err = |error| sp_consensus::Error::from(sp_consensus::Error::ClientImport( format!( @@ -336,107 +338,22 @@ fn initialize_authorities_cache(client: &C) -> Result<(), ConsensusErro error, ))); - let genesis_id = BlockId::Number(Zero::zero()); - let genesis_authorities: Option> = cache - .get_at(&well_known_cache_keys::AUTHORITIES, &genesis_id) + let block_id = BlockId::hash(best_hash); + let authorities: Option> = cache + .get_at(&well_known_cache_keys::AUTHORITIES, &block_id) .unwrap_or(None) .and_then(|(_, _, v)| Decode::decode(&mut &v[..]).ok()); - if genesis_authorities.is_some() { + if authorities.is_some() { return Ok(()); } - let genesis_authorities = authorities(client, &genesis_id)?; - cache.initialize(&well_known_cache_keys::AUTHORITIES, genesis_authorities.encode()) + let authorities = crate::authorities(client, &block_id)?; + cache.initialize(&well_known_cache_keys::AUTHORITIES, authorities.encode()) .map_err(map_err)?; Ok(()) } -/// A block-import handler for Aura. -pub struct AuraBlockImport, P> { - inner: I, - client: Arc, - _phantom: PhantomData<(Block, P)>, -} - -impl, P> Clone for AuraBlockImport { - fn clone(&self) -> Self { - AuraBlockImport { - inner: self.inner.clone(), - client: self.client.clone(), - _phantom: PhantomData, - } - } -} - -impl, P> AuraBlockImport { - /// New aura block import. - pub fn new( - inner: I, - client: Arc, - ) -> Self { - Self { - inner, - client, - _phantom: PhantomData, - } - } -} - -#[async_trait::async_trait] -impl BlockImport for AuraBlockImport where - I: BlockImport> + Send + Sync, - I::Error: Into, - C: HeaderBackend + ProvideRuntimeApi, - P: Pair + Send + Sync + 'static, - P::Public: Clone + Eq + Send + Sync + Hash + Debug + Encode + Decode, - P::Signature: Encode + Decode, - sp_api::TransactionFor: Send + 'static, -{ - type Error = ConsensusError; - type Transaction = sp_api::TransactionFor; - - async fn check_block( - &mut self, - block: BlockCheckParams, - ) -> Result { - self.inner.check_block(block).await.map_err(Into::into) - } - - async fn import_block( - &mut self, - block: BlockImportParams, - new_cache: HashMap>, - ) -> Result { - let hash = block.post_hash(); - let slot = find_pre_digest::(&block.header) - .expect("valid Aura headers must contain a predigest; \ - header has been already verified; qed"); - - let parent_hash = *block.header.parent_hash(); - let parent_header = self.client.header(BlockId::Hash(parent_hash)) - .map_err(|e| ConsensusError::ChainLookup(e.to_string()))? - .ok_or_else(|| ConsensusError::ChainLookup(aura_err( - Error::::ParentUnavailable(parent_hash, hash) - ).into()))?; - - let parent_slot = find_pre_digest::(&parent_header) - .expect("valid Aura headers contain a pre-digest; \ - parent header has already been verified; qed"); - - // make sure that slot number is strictly increasing - if slot <= parent_slot { - return Err( - ConsensusError::ClientImport(aura_err( - Error::::SlotMustIncrease(parent_slot, slot) - ).into()) - ); - } - - self.inner.import_block(block, new_cache).await.map_err(Into::into) - } -} - /// Should we check for equivocation of a block author? #[derive(Debug, Clone, Copy)] pub enum CheckForEquivocation { @@ -506,6 +423,7 @@ pub fn import_queue<'a, P, Block, I, C, S, CAW, CIDP>( + Send + Sync + AuxStore + + UsageProvider + HeaderBackend, I: BlockImport> + Send @@ -522,12 +440,14 @@ pub fn import_queue<'a, P, Block, I, C, S, CAW, CIDP>( { initialize_authorities_cache(&*client)?; - let verifier = AuraVerifier::<_, P, _, _>::new( - client, - create_inherent_data_providers, - can_author_with, - check_for_equivocation, - telemetry, + let verifier = build_verifier::( + BuildVerifierParams { + client, + create_inherent_data_providers, + can_author_with, + check_for_equivocation, + telemetry, + }, ); Ok(BasicQueue::new( @@ -538,3 +458,36 @@ pub fn import_queue<'a, P, Block, I, C, S, CAW, CIDP>( registry, )) } + +/// Parameters of [`build_verifier`]. +pub struct BuildVerifierParams { + /// The client to interact with the chain. + pub client: Arc, + /// Something that can create the inherent data providers. + pub create_inherent_data_providers: CIDP, + /// Can we author with the current node? + pub can_author_with: CAW, + /// Should we check for equivocation? + pub check_for_equivocation: CheckForEquivocation, + /// Telemetry instance used to report telemetry metrics. + pub telemetry: Option, +} + +/// Build the [`AuraVerifier`] +pub fn build_verifier( + BuildVerifierParams { + client, + create_inherent_data_providers, + can_author_with, + check_for_equivocation, + telemetry, + }: BuildVerifierParams +) -> AuraVerifier { + AuraVerifier::<_, P, _, _>::new( + client, + create_inherent_data_providers, + can_author_with, + check_for_equivocation, + telemetry, + ) +} diff --git a/substrate/client/consensus/aura/src/lib.rs b/substrate/client/consensus/aura/src/lib.rs index ce254799d6..623096cd5c 100644 --- a/substrate/client/consensus/aura/src/lib.rs +++ b/substrate/client/consensus/aura/src/lib.rs @@ -44,7 +44,7 @@ use sp_consensus::{ BlockImport, Environment, Proposer, CanAuthorWith, ForkChoiceStrategy, BlockImportParams, BlockOrigin, Error as ConsensusError, SelectChain, }; -use sc_client_api::{backend::AuxStore, BlockOf}; +use sc_client_api::{backend::AuxStore, BlockOf, UsageProvider}; use sp_blockchain::{Result as CResult, well_known_cache_keys, ProvideCache, HeaderBackend}; use sp_core::crypto::Public; use sp_application_crypto::{AppKey, AppPublic}; @@ -70,7 +70,10 @@ pub use sp_consensus_aura::{ }, }; pub use sp_consensus::SyncOracle; -pub use import_queue::{ImportQueueParams, import_queue, AuraBlockImport, CheckForEquivocation}; +pub use import_queue::{ + ImportQueueParams, import_queue, CheckForEquivocation, + build_verifier, BuildVerifierParams, AuraVerifier, +}; pub use sc_consensus_slots::SlotProportion; type AuthorityId

=

::Public; @@ -82,7 +85,7 @@ pub type SlotDuration = sc_consensus_slots::SlotDuration(client: &C) -> CResult where A: Codec, B: BlockT, - C: AuxStore + ProvideRuntimeApi, + C: AuxStore + ProvideRuntimeApi + UsageProvider, C::Api: AuraApi, { SlotDuration::get_or_compute(client, |a, b| a.slot_duration(b).map_err(Into::into)) @@ -491,10 +494,6 @@ enum Error { #[display(fmt = "Bad signature on {:?}", _0)] BadSignature(B::Hash), Client(sp_blockchain::Error), - #[display(fmt = "Slot number must increase: parent slot: {}, this slot: {}", _0, _1)] - SlotMustIncrease(Slot, Slot), - #[display(fmt = "Parent ({}) of {} unavailable. Cannot import", _0, _1)] - ParentUnavailable(B::Hash, B::Hash), #[display(fmt = "Unknown inherent error for identifier: {}", "String::from_utf8_lossy(_0)")] UnknownInherentError(sp_inherents::InherentIdentifier), #[display(fmt = "Inherent error: {}", _0)] diff --git a/substrate/client/consensus/babe/src/lib.rs b/substrate/client/consensus/babe/src/lib.rs index 3bdeaabf61..0b02bbbe14 100644 --- a/substrate/client/consensus/babe/src/lib.rs +++ b/substrate/client/consensus/babe/src/lib.rs @@ -98,7 +98,7 @@ use sp_consensus::{ }; use sp_consensus_babe::inherents::BabeInherentData; use sc_client_api::{ - backend::AuxStore, BlockchainEvents, ProvideUncles, + backend::AuxStore, BlockchainEvents, ProvideUncles, UsageProvider }; use sp_block_builder::BlockBuilder as BlockBuilderApi; use futures::channel::mpsc::{channel, Sender, Receiver}; @@ -317,7 +317,7 @@ impl Config { /// Either fetch the slot duration from disk or compute it from the genesis /// state. pub fn get_or_compute(client: &C) -> ClientResult where - C: AuxStore + ProvideRuntimeApi, C::Api: BabeApi, + C: AuxStore + ProvideRuntimeApi + UsageProvider, C::Api: BabeApi, { trace!(target: "babe", "Getting slot duration"); match sc_consensus_slots::SlotDuration::get_or_compute(client, |a, b| { diff --git a/substrate/client/consensus/manual-seal/src/consensus/babe.rs b/substrate/client/consensus/manual-seal/src/consensus/babe.rs index 29fea05d83..69590c6a1e 100644 --- a/substrate/client/consensus/manual-seal/src/consensus/babe.rs +++ b/substrate/client/consensus/manual-seal/src/consensus/babe.rs @@ -22,7 +22,7 @@ use super::ConsensusDataProvider; use crate::Error; use codec::Encode; use std::{borrow::Cow, sync::{Arc, atomic}, time::SystemTime}; -use sc_client_api::AuxStore; +use sc_client_api::{AuxStore, UsageProvider}; use sc_consensus_babe::{ Config, Epoch, authorship, CompatibleDigestItem, BabeIntermediate, INTERMEDIATE_KEY, find_pre_digest, @@ -67,7 +67,11 @@ pub struct BabeConsensusDataProvider { impl BabeConsensusDataProvider where B: BlockT, - C: AuxStore + HeaderBackend + ProvideRuntimeApi + HeaderMetadata, + C: AuxStore + + HeaderBackend + + ProvideRuntimeApi + + HeaderMetadata + + UsageProvider, C::Api: BabeApi, { pub fn new( @@ -120,7 +124,11 @@ impl BabeConsensusDataProvider impl ConsensusDataProvider for BabeConsensusDataProvider where B: BlockT, - C: AuxStore + HeaderBackend + HeaderMetadata + ProvideRuntimeApi, + C: AuxStore + + HeaderBackend + + HeaderMetadata + + UsageProvider + + ProvideRuntimeApi, C::Api: BabeApi, { type Transaction = TransactionFor; @@ -252,7 +260,7 @@ impl SlotTimestampProvider { pub fn new(client: Arc) -> Result where B: BlockT, - C: AuxStore + HeaderBackend + ProvideRuntimeApi, + C: AuxStore + HeaderBackend + ProvideRuntimeApi + UsageProvider, C::Api: BabeApi, { let slot_duration = Config::get_or_compute(&*client)?.slot_duration; diff --git a/substrate/client/consensus/slots/src/lib.rs b/substrate/client/consensus/slots/src/lib.rs index 4ef0093a18..2ea5e101c3 100644 --- a/substrate/client/consensus/slots/src/lib.rs +++ b/substrate/client/consensus/slots/src/lib.rs @@ -584,7 +584,7 @@ impl SlotDuration { /// `slot_key` is marked as `'static`, as it should really be a /// compile-time constant. pub fn get_or_compute(client: &C, cb: CB) -> sp_blockchain::Result where - C: sc_client_api::backend::AuxStore, + C: sc_client_api::backend::AuxStore + sc_client_api::UsageProvider, C: ProvideRuntimeApi, CB: FnOnce(ApiRef, &BlockId) -> sp_blockchain::Result, T: SlotData + Encode + Decode + Debug, @@ -599,19 +599,20 @@ impl SlotDuration { }) }), None => { - use sp_runtime::traits::Zero; - let genesis_slot_duration = - cb(client.runtime_api(), &BlockId::number(Zero::zero()))?; + let best_hash = client.usage_info().chain.best_hash; + let slot_duration = + cb(client.runtime_api(), &BlockId::hash(best_hash))?; info!( - "⏱ Loaded block-time = {:?} from genesis on first-launch", - genesis_slot_duration.slot_duration() + "⏱ Loaded block-time = {:?} from block {:?}", + slot_duration.slot_duration(), + best_hash, ); - genesis_slot_duration + slot_duration .using_encoded(|s| client.insert_aux(&[(T::SLOT_KEY, &s[..])], &[]))?; - Ok(SlotDuration(genesis_slot_duration)) + Ok(SlotDuration(slot_duration)) } }?;