diff --git a/client/consensus/pow/src/lib.rs b/client/consensus/pow/src/lib.rs index f8da1877665fc..ca1a8584e2a0b 100644 --- a/client/consensus/pow/src/lib.rs +++ b/client/consensus/pow/src/lib.rs @@ -88,10 +88,13 @@ pub enum Error { CreateInherents(sp_inherents::Error), #[display(fmt = "Checking inherents failed: {}", _0)] CheckInherents(String), + #[display(fmt = "Multiple pre-runtime digests")] + MultiplePreRuntimeDigests, Client(sp_blockchain::Error), Codec(codec::Error), Environment(String), - Runtime(RuntimeString) + Runtime(RuntimeString), + Other(String), } impl std::convert::From> for String { @@ -172,6 +175,7 @@ pub trait PowAlgorithm { &self, parent: &BlockId, pre_hash: &B::Hash, + pre_digest: Option<&[u8]>, seal: &Seal, difficulty: Self::Difficulty, ) -> Result>; @@ -180,6 +184,7 @@ pub trait PowAlgorithm { &self, parent: &BlockId, pre_hash: &B::Hash, + pre_digest: Option<&[u8]>, difficulty: Self::Difficulty, round: u32, ) -> Result, Error>; @@ -368,9 +373,11 @@ impl BlockImport for PowBlockImport(&block.header)?; if !self.algorithm.verify( &BlockId::hash(parent_hash), &pre_hash, + pre_digest.as_ref().map(|v| &v[..]), &inner_seal, difficulty, )? { @@ -519,7 +526,7 @@ pub fn import_queue( /// However, it's not recommended to use background threads in the rest of the /// codebase. /// -/// `preruntime` is a parameter that allows a custom additional pre-runtime +/// `pre_runtime` is a parameter that allows a custom additional pre-runtime /// digest to be inserted for blocks being built. This can encode authorship /// 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 @@ -529,7 +536,7 @@ pub fn start_mine( client: Arc, algorithm: Algorithm, mut env: E, - preruntime: Option>, + pre_runtime: Option>, round: u32, mut sync_oracle: SO, build_time: std::time::Duration, @@ -557,7 +564,7 @@ pub fn start_mine( client.as_ref(), &algorithm, &mut env, - preruntime.as_ref(), + pre_runtime.as_ref(), round, &mut sync_oracle, build_time.clone(), @@ -581,7 +588,7 @@ fn mine_loop( client: &C, algorithm: &Algorithm, env: &mut E, - preruntime: Option<&Vec>, + pre_runtime: Option<&Vec>, round: u32, sync_oracle: &mut SO, build_time: std::time::Duration, @@ -640,8 +647,8 @@ fn mine_loop( let inherent_data = inherent_data_providers .create_inherent_data().map_err(Error::CreateInherents)?; let mut inherent_digest = Digest::default(); - if let Some(preruntime) = &preruntime { - inherent_digest.push(DigestItem::PreRuntime(POW_ENGINE_ID, preruntime.to_vec())); + if let Some(pre_runtime) = &pre_runtime { + inherent_digest.push(DigestItem::PreRuntime(POW_ENGINE_ID, pre_runtime.to_vec())); } let proposal = futures::executor::block_on(proposer.propose( inherent_data, @@ -658,6 +665,7 @@ fn mine_loop( let seal = algorithm.mine( &BlockId::Hash(best_hash), &header.hash(), + pre_runtime.map(|v| &v[..]), difficulty, round, )?; @@ -702,3 +710,22 @@ fn mine_loop( .map_err(|e| Error::BlockBuiltError(best_hash, e))?; } } + +/// Find PoW pre-runtime. +fn find_pre_digest(header: &B::Header) -> Result>, Error> { + let mut pre_digest: Option<_> = None; + for log in header.digest().logs() { + trace!(target: "pow", "Checking log {:?}, looking for pre runtime digest", log); + match (log, pre_digest.is_some()) { + (DigestItem::PreRuntime(POW_ENGINE_ID, _), true) => { + return Err(Error::MultiplePreRuntimeDigests) + }, + (DigestItem::PreRuntime(POW_ENGINE_ID, v), false) => { + pre_digest = Some(v.clone()); + }, + (_, _) => trace!(target: "pow", "Ignoring digest not meant for us"), + } + } + + Ok(pre_digest) +}