Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 38 additions & 24 deletions client/consensus/pow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ pub enum Error<B: BlockT> {
HeaderUnsealed(B::Hash),
#[display(fmt = "PoW validation error: invalid seal")]
InvalidSeal,
#[display(fmt = "PoW validation error: invalid difficulty")]
InvalidDifficulty,
#[display(fmt = "PoW validation error: preliminary verification failed")]
FailedPreliminaryVerify,
#[display(fmt = "Rejecting block too far in future")]
TooFarInFuture,
#[display(fmt = "Fetching best header failed using select chain: {:?}", _0)]
Expand Down Expand Up @@ -154,18 +154,23 @@ pub trait PowAlgorithm<B: BlockT> {
/// This function will be called twice during the import process, so the implementation
/// should be properly cached.
fn difficulty(&self, parent: &BlockId<B>) -> Result<Self::Difficulty, Error<B>>;
/// Verify that the seal is valid against given pre hash.
fn verify_seal(
/// Verify that the seal is valid against given pre hash when parent block is not yet imported.
///
/// None means that preliminary verify is not available for this algorithm.
fn preliminary_verify(
&self,
pre_hash: &B::Hash,
seal: &Seal,
) -> Result<bool, Error<B>>;
_pre_hash: &B::Hash,
_seal: &Seal,
) -> Result<Option<bool>, Error<B>> {
Ok(None)
}
/// Verify that the difficulty is valid against given seal.
fn verify_difficulty(
fn verify(
&self,
difficulty: Self::Difficulty,
parent: &BlockId<B>,
pre_hash: &B::Hash,
seal: &Seal,
difficulty: Self::Difficulty,
) -> Result<bool, Error<B>>;
/// Mine a seal that satisfies the given difficulty.
fn mine(
Expand All @@ -187,6 +192,19 @@ pub struct PowBlockImport<B: BlockT, I, C, S, Algorithm> {
check_inherents_after: <<B as BlockT>::Header as HeaderT>::Number,
}

impl<B: BlockT, I: Clone, C, S: Clone, Algorithm: Clone> Clone for PowBlockImport<B, I, C, S, Algorithm> {
fn clone(&self) -> Self {
Self {
algorithm: self.algorithm.clone(),
inner: self.inner.clone(),
select_chain: self.select_chain.clone(),
client: self.client.clone(),
inherent_data_providers: self.inherent_data_providers.clone(),
check_inherents_after: self.check_inherents_after.clone(),
}
}
}

impl<B, I, C, S, Algorithm> PowBlockImport<B, I, C, S, Algorithm> where
B: BlockT,
I: BlockImport<B, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync,
Expand Down Expand Up @@ -322,12 +340,14 @@ impl<B, I, C, S, Algorithm> BlockImport<B> for PowBlockImport<B, I, C, S, Algori
None => self.algorithm.difficulty(&BlockId::hash(parent_hash))?,
};

if !self.algorithm.verify_difficulty(
difficulty,
let pre_hash = block.header.hash();
if !self.algorithm.verify(
&BlockId::hash(parent_hash),
&pre_hash,
&inner_seal,
difficulty,
)? {
return Err(Error::<B>::InvalidDifficulty.into())
return Err(Error::<B>::InvalidSeal.into())
}

aux.difficulty = difficulty;
Expand Down Expand Up @@ -379,11 +399,8 @@ impl<B: BlockT, Algorithm> PowVerifier<B, Algorithm> {

let pre_hash = header.hash();

if !self.algorithm.verify_seal(
&pre_hash,
&inner_seal,
)? {
return Err(Error::InvalidSeal);
if !self.algorithm.preliminary_verify(&pre_hash, &inner_seal)?.unwrap_or(true) {
return Err(Error::FailedPreliminaryVerify);
}

Ok((header, seal))
Expand Down Expand Up @@ -450,20 +467,17 @@ pub fn register_pow_inherent_data_provider(
pub type PowImportQueue<B, Transaction> = BasicQueue<B, Transaction>;

/// Import queue for PoW engine.
pub fn import_queue<B, C, S, Algorithm>(
block_import: BoxBlockImport<B, sp_api::TransactionFor<C, B>>,
pub fn import_queue<B, Transaction, Algorithm>(
block_import: BoxBlockImport<B, Transaction>,
algorithm: Algorithm,
inherent_data_providers: InherentDataProviders,
) -> Result<
PowImportQueue<B, sp_api::TransactionFor<C, B>>,
PowImportQueue<B, Transaction>,
sp_consensus::Error
> where
B: BlockT,
C: ProvideRuntimeApi<B> + HeaderBackend<B> + BlockOf + ProvideCache<B> + AuxStore,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how many of those generic bounds never get deleted elsewhere

C: Send + Sync + AuxStore + 'static,
C::Api: BlockBuilderApi<B, Error = sp_blockchain::Error>,
Transaction: Send + Sync + 'static,
Algorithm: PowAlgorithm<B> + Clone + Send + Sync + 'static,
S: SelectChain<B> + 'static,
{
register_pow_inherent_data_provider(&inherent_data_providers)?;

Expand Down