use super::*;
use crate::errors::{BlockProcessResult, RuleError};
use crate::model::services::reachability::ReachabilityService;
use crate::processes::window::WindowManager;
use kaspa_consensus_core::header::Header;
impl HeaderProcessor {
pub(super) fn pre_pow_validation(&self, ctx: &mut HeaderProcessingContext, header: &Header) -> BlockProcessResult<()> {
self.check_pruning_violation(ctx)?;
self.check_difficulty_and_daa_score(ctx, header)?;
Ok(())
}
fn check_pruning_violation(&self, ctx: &HeaderProcessingContext) -> BlockProcessResult<()> {
let known_parents = ctx.direct_known_parents();
if !self.reachability_service.is_dag_ancestor_of_any(ctx.pruning_point(), &mut known_parents.iter().copied()) {
return Err(RuleError::PruningViolation(ctx.pruning_point()));
}
Ok(())
}
fn check_difficulty_and_daa_score(&self, ctx: &mut HeaderProcessingContext, header: &Header) -> BlockProcessResult<()> {
let ghostdag_data = ctx.ghostdag_data();
let daa_window = self.window_manager.block_daa_window(ghostdag_data)?;
if daa_window.daa_score != header.daa_score {
return Err(RuleError::UnexpectedHeaderDaaScore(daa_window.daa_score, header.daa_score));
}
let expected_bits = self.window_manager.calculate_difficulty_bits(ghostdag_data, &daa_window);
ctx.mergeset_non_daa = Some(daa_window.mergeset_non_daa);
if header.bits != expected_bits {
return Err(RuleError::UnexpectedDifficulty(header.bits, expected_bits));
}
ctx.block_window_for_difficulty = Some(daa_window.window);
Ok(())
}
}