diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 0787d7faec..27066afe3c 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -4771,6 +4771,7 @@ dependencies = [ name = "substrate-consensus-aura" version = "2.0.0" dependencies = [ + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "futures-preview 0.3.0-alpha.18 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/substrate/core/consensus/aura/Cargo.toml b/substrate/core/consensus/aura/Cargo.toml index c3aaeb3d56..724b720f4f 100644 --- a/substrate/core/consensus/aura/Cargo.toml +++ b/substrate/core/consensus/aura/Cargo.toml @@ -26,6 +26,7 @@ futures01 = { package = "futures", version = "0.1" } futures-timer = "0.3" parking_lot = "0.9.0" log = "0.4" +derive_more = "0.15.0" [dev-dependencies] keyring = { package = "substrate-keyring", path = "../../keyring" } diff --git a/substrate/core/consensus/aura/src/lib.rs b/substrate/core/consensus/aura/src/lib.rs index a61eb6da72..eb2d1dba20 100644 --- a/substrate/core/consensus/aura/src/lib.rs +++ b/substrate/core/consensus/aura/src/lib.rs @@ -48,7 +48,7 @@ use sr_primitives::{generic::{BlockId, OpaqueDigestItemId}, Justification}; use sr_primitives::traits::{Block as BlockT, Header, DigestItemFor, ProvideRuntimeApi, Zero, Member}; use primitives::crypto::Pair; -use inherents::{InherentDataProviders, InherentData}; +use inherents::{InherentDataProviders, InherentData, RuntimeString}; use futures::prelude::*; use parking_lot::Mutex; @@ -308,16 +308,33 @@ impl SlotWorker for AuraWorker { - { - debug!(target: "aura", $( $i ),+); - format!($( $i ),+) - } - }; +fn aura_err(error: Error) -> Error { + debug!(target: "aura", "{}", error); + error } -fn find_pre_digest(header: &B::Header) -> Result +#[derive(derive_more::Display)] +enum Error { + #[display(fmt = "Multiple Aura pre-runtime headers")] + MultipleHeaders, + #[display(fmt = "No Aura pre-runtime digest found")] + NoDigestFound, + #[display(fmt = "Header {:?} is unsealed", _0)] + HeaderUnsealed(B::Hash), + #[display(fmt = "Header {:?} has a bad seal", _0)] + HeaderBadSeal(B::Hash), + #[display(fmt = "Slot Author not found")] + SlotAuthorNotFound, + #[display(fmt = "Bad signature on {:?}", _0)] + BadSignature(B::Hash), + #[display(fmt = "Rejecting block too far in future")] + TooFarInFuture, + Client(client::error::Error), + DataProvider(String), + Runtime(RuntimeString) +} + +fn find_pre_digest(header: &B::Header) -> Result> where DigestItemFor: CompatibleDigestItem

, P::Signature: Decode, P::Public: Encode + Decode + PartialEq + Clone, @@ -326,12 +343,12 @@ fn find_pre_digest(header: &B::Header) -> Result Err(aura_err!("Multiple AuRa pre-runtime headers, rejecting!"))?, + (Some(_), true) => Err(aura_err(Error::MultipleHeaders))?, (None, _) => trace!(target: "aura", "Ignoring digest not meant for us"), (s, false) => pre_digest = s, } } - pre_digest.ok_or_else(|| aura_err!("No AuRa pre-runtime digest found")) + pre_digest.ok_or_else(|| aura_err(Error::NoDigestFound)) } /// check a header has been signed by the right key. If the slot is too far in the future, an error will be returned. @@ -348,7 +365,7 @@ fn check_header( hash: B::Hash, authorities: &[AuthorityId

], _transaction_pool: Option<&T>, -) -> Result)>, String> where +) -> Result)>, Error> where DigestItemFor: CompatibleDigestItem

, P::Signature: Decode, C: client::backend::AuxStore, @@ -357,11 +374,11 @@ fn check_header( { let seal = match header.digest_mut().pop() { Some(x) => x, - None => return Err(format!("Header {:?} is unsealed", hash)), + None => return Err(Error::HeaderUnsealed(hash)), }; let sig = seal.as_aura_seal().ok_or_else(|| { - aura_err!("Header {:?} has a bad seal", hash) + aura_err(Error::HeaderBadSeal(hash)) })?; let slot_num = find_pre_digest::(&header)?; @@ -373,7 +390,7 @@ fn check_header( // check the signature is valid under the expected authority and // chain state. let expected_author = match slot_author::

(slot_num, &authorities) { - None => return Err("Slot Author not found".to_string()), + None => return Err(Error::SlotAuthorNotFound), Some(author) => author, }; @@ -386,7 +403,7 @@ fn check_header( slot_num, &header, expected_author, - ).map_err(|e| e.to_string())? { + ).map_err(Error::Client)? { info!( "Slot author is equivocating at slot {} with headers {:?} and {:?}", slot_num, @@ -397,7 +414,7 @@ fn check_header( Ok(CheckedHeader::Checked(header, (slot_num, seal))) } else { - Err(format!("Bad signature on {:?}", hash)) + Err(Error::BadSignature(hash)) } } } @@ -419,7 +436,7 @@ impl AuraVerifier block_id: BlockId, inherent_data: InherentData, timestamp_now: u64, - ) -> Result<(), String> + ) -> Result<(), Error> where C: ProvideRuntimeApi, C::Api: BlockBuilderApi { const MAX_TIMESTAMP_DRIFT_SECS: u64 = 60; @@ -428,7 +445,7 @@ impl AuraVerifier &block_id, block, inherent_data, - ).map_err(|e| format!("{:?}", e))?; + ).map_err(Error::Client)?; if !inherent_res.ok() { inherent_res @@ -438,7 +455,7 @@ impl AuraVerifier // halt import until timestamp is valid. // reject when too far ahead. if timestamp > timestamp_now + MAX_TIMESTAMP_DRIFT_SECS { - return Err("Rejecting block too far in future".into()); + return Err(Error::TooFarInFuture); } let diff = timestamp.saturating_sub(timestamp_now); @@ -453,8 +470,10 @@ impl AuraVerifier thread::sleep(Duration::from_secs(diff)); Ok(()) }, - Some(TIError::Other(e)) => Err(e.into()), - None => Err(self.inherent_data_providers.error_to_string(&i, &e)), + Some(TIError::Other(e)) => Err(Error::Runtime(e)), + None => Err(Error::DataProvider( + self.inherent_data_providers.error_to_string(&i, &e) + )), }) } else { Ok(()) @@ -497,7 +516,7 @@ impl Verifier for AuraVerifier where hash, &authorities[..], self.transaction_pool.as_ref().map(|x| &**x), - )?; + ).map_err(|e| e.to_string())?; match checked_header { CheckedHeader::Checked(pre_header, (slot_num, seal)) => { // if the body is passed through, we need to use the runtime @@ -518,7 +537,7 @@ impl Verifier for AuraVerifier where BlockId::Hash(parent_hash), inherent_data, timestamp_now, - )?; + ).map_err(|e| e.to_string())?; } let (_, inner_body) = block.deconstruct();