diff --git a/substrate/client/consensus/aura/src/lib.rs b/substrate/client/consensus/aura/src/lib.rs index 746ee6597e..71aa7bdb7c 100644 --- a/substrate/client/consensus/aura/src/lib.rs +++ b/substrate/client/consensus/aura/src/lib.rs @@ -77,16 +77,13 @@ use sp_consensus_slots::Slot; use sp_api::ApiExt; pub use sp_consensus_aura::{ - ConsensusLog, AuraApi, AURA_ENGINE_ID, + ConsensusLog, AuraApi, AURA_ENGINE_ID, digests::CompatibleDigestItem, inherents::{ InherentType as AuraInherent, AuraInherentData, INHERENT_IDENTIFIER, InherentDataProvider, }, }; pub use sp_consensus::SyncOracle; -pub use digests::CompatibleDigestItem; - -mod digests; type AuthorityId

=

::Public; @@ -271,7 +268,7 @@ where _claim: &Self::Claim, ) -> Vec> { vec![ - as CompatibleDigestItem

>::aura_pre_digest(slot), + as CompatibleDigestItem>::aura_pre_digest(slot), ] } @@ -308,7 +305,9 @@ where signature, public ))?; - let signature_digest_item = as CompatibleDigestItem

>::aura_seal(signature); + let signature_digest_item = < + DigestItemFor as CompatibleDigestItem + >::aura_seal(signature); let mut import_block = BlockImportParams::new(BlockOrigin::Own, header); import_block.post_digests.push(signature_digest_item); @@ -326,7 +325,7 @@ where fn should_backoff(&self, slot: Slot, chain_head: &B::Header) -> bool { if let Some(ref strategy) = self.backoff_authoring_blocks { - if let Ok(chain_head_slot) = find_pre_digest::(chain_head) { + if let Ok(chain_head_slot) = find_pre_digest::(chain_head) { return strategy.should_backoff( *chain_head.number(), chain_head_slot, @@ -356,7 +355,7 @@ where ) -> Option { let slot_remaining = self.slot_remaining_duration(slot_info); - let parent_slot = match find_pre_digest::(head) { + let parent_slot = match find_pre_digest::(head) { Err(_) => return Some(slot_remaining), Ok(d) => d, }; @@ -414,11 +413,7 @@ impl std::convert::From> for String { } } -fn find_pre_digest(header: &B::Header) -> Result> - where DigestItemFor: CompatibleDigestItem

, - P::Signature: Decode, - P::Public: Encode + Decode + PartialEq + Clone, -{ +fn find_pre_digest(header: &B::Header) -> Result> { if header.number().is_zero() { return Ok(0.into()); } @@ -426,7 +421,7 @@ fn find_pre_digest(header: &B::Header) -> Result = None; for log in header.digest().logs() { trace!(target: "aura", "Checking log {:?}", log); - match (log.as_aura_pre_digest(), pre_digest.is_some()) { + match (CompatibleDigestItem::::as_aura_pre_digest(log), pre_digest.is_some()) { (Some(_), true) => Err(aura_err(Error::MultipleHeaders))?, (None, _) => trace!(target: "aura", "Ignoring digest not meant for us"), (s, false) => pre_digest = s, @@ -435,8 +430,9 @@ fn find_pre_digest(header: &B::Header) -> Result( hash: B::Hash, authorities: &[AuthorityId

], ) -> Result)>, Error> where - DigestItemFor: CompatibleDigestItem

, - P::Signature: Decode, + DigestItemFor: CompatibleDigestItem, + P::Signature: Codec, C: sc_client_api::backend::AuxStore, P::Public: Encode + Decode + PartialEq + Clone, { @@ -461,7 +457,7 @@ fn check_header( aura_err(Error::HeaderBadSeal(hash)) })?; - let slot = find_pre_digest::(&header)?; + let slot = find_pre_digest::(&header)?; if slot > slot_now { header.digest_mut().push(seal); @@ -582,7 +578,7 @@ impl Verifier for AuraVerifier where ProvideCache + BlockOf, C::Api: BlockBuilderApi + AuraApi> + ApiExt, - DigestItemFor: CompatibleDigestItem

, + DigestItemFor: CompatibleDigestItem, P: Pair + Send + Sync + 'static, P::Public: Send + Sync + Hash + Eq + Clone + Decode + Encode + Debug + 'static, P::Signature: Encode + Decode, @@ -805,7 +801,7 @@ impl BlockImport for AuraBlockImport>, ) -> Result { let hash = block.post_hash(); - let slot = find_pre_digest::(&block.header) + let slot = find_pre_digest::(&block.header) .expect("valid Aura headers must contain a predigest; \ header has been already verified; qed"); @@ -816,7 +812,7 @@ impl BlockImport for AuraBlockImport::ParentUnavailable(parent_hash, hash) ).into()))?; - let parent_slot = find_pre_digest::(&parent_header) + let parent_slot = find_pre_digest::(&parent_header) .expect("valid Aura headers contain a pre-digest; \ parent header has already been verified; qed"); @@ -848,7 +844,7 @@ pub fn import_queue( C::Api: BlockBuilderApi + AuraApi> + ApiExt, C: 'static + ProvideRuntimeApi + BlockOf + ProvideCache + Send + Sync + AuxStore + HeaderBackend, I: BlockImport> + Send + Sync + 'static, - DigestItemFor: CompatibleDigestItem

, + DigestItemFor: CompatibleDigestItem, P: Pair + Send + Sync + 'static, P::Public: Clone + Eq + Send + Sync + Hash + Debug + Encode + Decode, P::Signature: Encode + Decode, @@ -858,7 +854,7 @@ pub fn import_queue( register_aura_inherent_data_provider(&inherent_data_providers, slot_duration.get())?; initialize_authorities_cache(&*client)?; - let verifier = AuraVerifier { + let verifier = AuraVerifier::<_, P, _> { client, inherent_data_providers, phantom: PhantomData, diff --git a/substrate/client/consensus/aura/src/digests.rs b/substrate/primitives/consensus/aura/src/digests.rs similarity index 72% rename from substrate/client/consensus/aura/src/digests.rs rename to substrate/primitives/consensus/aura/src/digests.rs index bbf31136b0..e93214eeb4 100644 --- a/substrate/client/consensus/aura/src/digests.rs +++ b/substrate/primitives/consensus/aura/src/digests.rs @@ -21,22 +21,19 @@ //! This implements the digests for AuRa, to allow the private //! `CompatibleDigestItem` trait to appear in public interfaces. -use sp_core::Pair; -use sp_consensus_aura::AURA_ENGINE_ID; -use sp_runtime::generic::{DigestItem, OpaqueDigestItemId}; +use crate::AURA_ENGINE_ID; +use sp_runtime::generic::DigestItem; use sp_consensus_slots::Slot; use codec::{Encode, Codec}; -use std::fmt::Debug; - -type Signature

=

::Signature; +use sp_std::fmt::Debug; /// A digest item which is usable with aura consensus. -pub trait CompatibleDigestItem: Sized { +pub trait CompatibleDigestItem: Sized { /// Construct a digest item which contains a signature on the hash. - fn aura_seal(signature: Signature

) -> Self; + fn aura_seal(signature: Signature) -> Self; /// If this item is an Aura seal, return the signature. - fn as_aura_seal(&self) -> Option>; + fn as_aura_seal(&self) -> Option; /// Construct a digest item which contains the slot number fn aura_pre_digest(slot: Slot) -> Self; @@ -45,17 +42,16 @@ pub trait CompatibleDigestItem: Sized { fn as_aura_pre_digest(&self) -> Option; } -impl CompatibleDigestItem

for DigestItem where - P: Pair, - Signature

: Codec, +impl CompatibleDigestItem for DigestItem where + Signature: Codec, Hash: Debug + Send + Sync + Eq + Clone + Codec + 'static { - fn aura_seal(signature: Signature

) -> Self { + fn aura_seal(signature: Signature) -> Self { DigestItem::Seal(AURA_ENGINE_ID, signature.encode()) } - fn as_aura_seal(&self) -> Option> { - self.try_to(OpaqueDigestItemId::Seal(&AURA_ENGINE_ID)) + fn as_aura_seal(&self) -> Option { + self.seal_try_to(&AURA_ENGINE_ID) } fn aura_pre_digest(slot: Slot) -> Self { @@ -63,6 +59,6 @@ impl CompatibleDigestItem

for DigestItem where } fn as_aura_pre_digest(&self) -> Option { - self.try_to(OpaqueDigestItemId::PreRuntime(&AURA_ENGINE_ID)) + self.pre_runtime_try_to(&AURA_ENGINE_ID) } } diff --git a/substrate/primitives/consensus/aura/src/lib.rs b/substrate/primitives/consensus/aura/src/lib.rs index 95630fa7b5..8c9c57567c 100644 --- a/substrate/primitives/consensus/aura/src/lib.rs +++ b/substrate/primitives/consensus/aura/src/lib.rs @@ -23,6 +23,7 @@ use codec::{Encode, Decode, Codec}; use sp_std::vec::Vec; use sp_runtime::ConsensusEngineId; +pub mod digests; pub mod inherents; pub mod sr25519 { diff --git a/substrate/primitives/consensus/babe/src/digests.rs b/substrate/primitives/consensus/babe/src/digests.rs index 5a89e1fbc0..f34a38bc8b 100644 --- a/substrate/primitives/consensus/babe/src/digests.rs +++ b/substrate/primitives/consensus/babe/src/digests.rs @@ -23,7 +23,7 @@ use super::{ }; use codec::{Codec, Decode, Encode}; use sp_std::vec::Vec; -use sp_runtime::{generic::OpaqueDigestItemId, DigestItem, RuntimeDebug}; +use sp_runtime::{DigestItem, RuntimeDebug}; use sp_consensus_vrf::schnorrkel::{Randomness, VRFOutput, VRFProof}; @@ -184,7 +184,7 @@ impl CompatibleDigestItem for DigestItem where } fn as_babe_pre_digest(&self) -> Option { - self.try_to(OpaqueDigestItemId::PreRuntime(&BABE_ENGINE_ID)) + self.pre_runtime_try_to(&BABE_ENGINE_ID) } fn babe_seal(signature: AuthoritySignature) -> Self { @@ -192,11 +192,11 @@ impl CompatibleDigestItem for DigestItem where } fn as_babe_seal(&self) -> Option { - self.try_to(OpaqueDigestItemId::Seal(&BABE_ENGINE_ID)) + self.seal_try_to(&BABE_ENGINE_ID) } fn as_next_epoch_descriptor(&self) -> Option { - self.try_to(OpaqueDigestItemId::Consensus(&BABE_ENGINE_ID)) + self.consensus_try_to(&BABE_ENGINE_ID) .and_then(|x: super::ConsensusLog| match x { super::ConsensusLog::NextEpochData(n) => Some(n), _ => None, @@ -204,7 +204,7 @@ impl CompatibleDigestItem for DigestItem where } fn as_next_config_descriptor(&self) -> Option { - self.try_to(OpaqueDigestItemId::Consensus(&BABE_ENGINE_ID)) + self.consensus_try_to(&BABE_ENGINE_ID) .and_then(|x: super::ConsensusLog| match x { super::ConsensusLog::NextConfigData(n) => Some(n), _ => None, diff --git a/substrate/primitives/runtime/src/generic/digest.rs b/substrate/primitives/runtime/src/generic/digest.rs index 16bd887f04..dcdd90f4a6 100644 --- a/substrate/primitives/runtime/src/generic/digest.rs +++ b/substrate/primitives/runtime/src/generic/digest.rs @@ -62,16 +62,12 @@ impl Digest { /// Get reference to the first digest item that matches the passed predicate. pub fn log) -> Option<&T>>(&self, predicate: F) -> Option<&T> { - self.logs().iter() - .filter_map(predicate) - .next() + self.logs().iter().find_map(predicate) } /// Get a conversion of the first digest item that successfully converts using the function. pub fn convert_first) -> Option>(&self, predicate: F) -> Option { - self.logs().iter() - .filter_map(predicate) - .next() + self.logs().iter().find_map(predicate) } } @@ -251,10 +247,7 @@ impl DigestItem { /// Returns Some if `self` is a `DigestItem::Other`. pub fn as_other(&self) -> Option<&[u8]> { - match *self { - DigestItem::Other(ref v) => Some(&v[..]), - _ => None, - } + self.dref().as_other() } /// Returns the opaque data contained in the item if `Some` if this entry has the id given. @@ -267,6 +260,29 @@ impl DigestItem { pub fn try_to(&self, id: OpaqueDigestItemId) -> Option { self.dref().try_to::(id) } + + /// Try to match this to a `Self::Seal`, check `id` matches and decode it. + /// + /// Returns `None` if this isn't a seal item, the `id` doesn't match or when the decoding fails. + pub fn seal_try_to(&self, id: &ConsensusEngineId) -> Option { + self.dref().seal_try_to(id) + } + + /// Try to match this to a `Self::Consensus`, check `id` matches and decode it. + /// + /// Returns `None` if this isn't a consensus item, the `id` doesn't match or + /// when the decoding fails. + pub fn consensus_try_to(&self, id: &ConsensusEngineId) -> Option { + self.dref().consensus_try_to(id) + } + + /// Try to match this to a `Self::PreRuntime`, check `id` matches and decode it. + /// + /// Returns `None` if this isn't a pre-runtime item, the `id` doesn't match or + /// when the decoding fails. + pub fn pre_runtime_try_to(&self, id: &ConsensusEngineId) -> Option { + self.dref().pre_runtime_try_to(id) + } } impl Encode for DigestItem { @@ -374,6 +390,41 @@ impl<'a, Hash> DigestItemRef<'a, Hash> { pub fn try_to(&self, id: OpaqueDigestItemId) -> Option { self.try_as_raw(id).and_then(|mut x| Decode::decode(&mut x).ok()) } + + /// Try to match this to a `Self::Seal`, check `id` matches and decode it. + /// + /// Returns `None` if this isn't a seal item, the `id` doesn't match or when the decoding fails. + pub fn seal_try_to(&self, id: &ConsensusEngineId) -> Option { + match self { + Self::Seal(v, s) if *v == id => + Decode::decode(&mut &s[..]).ok(), + _ => None, + } + } + + /// Try to match this to a `Self::Consensus`, check `id` matches and decode it. + /// + /// Returns `None` if this isn't a consensus item, the `id` doesn't match or + /// when the decoding fails. + pub fn consensus_try_to(&self, id: &ConsensusEngineId) -> Option { + match self { + Self::Consensus(v, s) if *v == id => + Decode::decode(&mut &s[..]).ok(), + _ => None, + } + } + + /// Try to match this to a `Self::PreRuntime`, check `id` matches and decode it. + /// + /// Returns `None` if this isn't a pre-runtime item, the `id` doesn't match or + /// when the decoding fails. + pub fn pre_runtime_try_to(&self, id: &ConsensusEngineId) -> Option { + match self { + Self::PreRuntime(v, s) if *v == id => + Decode::decode(&mut &s[..]).ok(), + _ => None, + } + } } impl<'a, Hash: Encode> Encode for DigestItemRef<'a, Hash> {