Skip to content

Commit

Permalink
pow: add access to pre-digest for algorithm verifiers (paritytech#6900)
Browse files Browse the repository at this point in the history
* pow: fetch pre-runtime digest to verifier

* Add Other error type

* Fix log target and change docs to refer to pre_runtime
  • Loading branch information
sorpaas authored Aug 17, 2020
1 parent 488b7c7 commit 287ecc2
Showing 1 changed file with 34 additions and 7 deletions.
41 changes: 34 additions & 7 deletions client/consensus/pow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,13 @@ pub enum Error<B: BlockT> {
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<B: BlockT> std::convert::From<Error<B>> for String {
Expand Down Expand Up @@ -172,6 +175,7 @@ pub trait PowAlgorithm<B: BlockT> {
&self,
parent: &BlockId<B>,
pre_hash: &B::Hash,
pre_digest: Option<&[u8]>,
seal: &Seal,
difficulty: Self::Difficulty,
) -> Result<bool, Error<B>>;
Expand All @@ -180,6 +184,7 @@ pub trait PowAlgorithm<B: BlockT> {
&self,
parent: &BlockId<B>,
pre_hash: &B::Hash,
pre_digest: Option<&[u8]>,
difficulty: Self::Difficulty,
round: u32,
) -> Result<Option<Seal>, Error<B>>;
Expand Down Expand Up @@ -368,9 +373,11 @@ impl<B, I, C, S, Algorithm, CAW> BlockImport<B> for PowBlockImport<B, I, C, S, A
};

let pre_hash = block.header.hash();
let pre_digest = find_pre_digest::<B>(&block.header)?;
if !self.algorithm.verify(
&BlockId::hash(parent_hash),
&pre_hash,
pre_digest.as_ref().map(|v| &v[..]),
&inner_seal,
difficulty,
)? {
Expand Down Expand Up @@ -519,7 +526,7 @@ pub fn import_queue<B, Transaction, Algorithm>(
/// 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
Expand All @@ -529,7 +536,7 @@ pub fn start_mine<B: BlockT, C, Algorithm, E, SO, S, CAW>(
client: Arc<C>,
algorithm: Algorithm,
mut env: E,
preruntime: Option<Vec<u8>>,
pre_runtime: Option<Vec<u8>>,
round: u32,
mut sync_oracle: SO,
build_time: std::time::Duration,
Expand Down Expand Up @@ -557,7 +564,7 @@ pub fn start_mine<B: BlockT, C, Algorithm, E, SO, S, CAW>(
client.as_ref(),
&algorithm,
&mut env,
preruntime.as_ref(),
pre_runtime.as_ref(),
round,
&mut sync_oracle,
build_time.clone(),
Expand All @@ -581,7 +588,7 @@ fn mine_loop<B: BlockT, C, Algorithm, E, SO, S, CAW>(
client: &C,
algorithm: &Algorithm,
env: &mut E,
preruntime: Option<&Vec<u8>>,
pre_runtime: Option<&Vec<u8>>,
round: u32,
sync_oracle: &mut SO,
build_time: std::time::Duration,
Expand Down Expand Up @@ -640,8 +647,8 @@ fn mine_loop<B: BlockT, C, Algorithm, E, SO, S, CAW>(
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,
Expand All @@ -658,6 +665,7 @@ fn mine_loop<B: BlockT, C, Algorithm, E, SO, S, CAW>(
let seal = algorithm.mine(
&BlockId::Hash(best_hash),
&header.hash(),
pre_runtime.map(|v| &v[..]),
difficulty,
round,
)?;
Expand Down Expand Up @@ -702,3 +710,22 @@ fn mine_loop<B: BlockT, C, Algorithm, E, SO, S, CAW>(
.map_err(|e| Error::BlockBuiltError(best_hash, e))?;
}
}

/// Find PoW pre-runtime.
fn find_pre_digest<B: BlockT>(header: &B::Header) -> Result<Option<Vec<u8>>, Error<B>> {
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)
}

0 comments on commit 287ecc2

Please sign in to comment.