Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check block is not pruned #468

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
3 changes: 3 additions & 0 deletions consensus/core/src/errors/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ pub enum RuleError {

#[error("DAA window data has only {0} entries")]
InsufficientDaaWindowSize(usize),

#[error("cannot add block body to a pruned block")]
PrunedBlock,
}

pub type BlockProcessResult<T> = std::result::Result<T, RuleError>;
1 change: 1 addition & 0 deletions consensus/src/consensus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ impl Consensus {
storage.headers_store.clone(),
storage.block_transactions_store.clone(),
storage.body_tips_store.clone(),
storage.pruning_point_store.clone(),
services.reachability_service.clone(),
services.coinbase_manager.clone(),
services.mass_calculator.clone(),
Expand Down
22 changes: 18 additions & 4 deletions consensus/src/consensus/test_consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ impl TestConsensus {
}

pub fn build_header_with_parents(&self, hash: Hash, parents: Vec<Hash>) -> Header {
let mut header = header_from_precomputed_hash(hash, parents);
let mut header = header_from_precomputed_hash(hash, Default::default());
let parents_by_level = self.consensus.services.parents_manager.calc_block_parents(self.pruning_point(), &parents);
header.parents_by_level = parents_by_level;
let ghostdag_data = self.consensus.services.ghostdag_primary_manager.ghostdag(header.direct_parents());
header.pruning_point = self
.consensus
Expand All @@ -134,8 +136,12 @@ impl TestConsensus {
header
}

pub fn add_block_with_parents(&self, hash: Hash, parents: Vec<Hash>) -> impl Future<Output = BlockProcessResult<BlockStatus>> {
self.validate_and_insert_block(self.build_block_with_parents(hash, parents).to_immutable()).virtual_state_task
pub fn add_header_only_block_with_parents(
&self,
hash: Hash,
parents: Vec<Hash>,
) -> impl Future<Output = BlockProcessResult<BlockStatus>> {
self.validate_and_insert_block(self.build_header_only_block_with_parents(hash, parents).to_immutable()).virtual_state_task
}

pub fn add_utxo_valid_block_with_parents(
Expand All @@ -149,6 +155,14 @@ impl TestConsensus {
.virtual_state_task
}

pub fn add_empty_utxo_valid_block_with_parents(
&self,
hash: Hash,
parents: Vec<Hash>,
) -> impl Future<Output = BlockProcessResult<BlockStatus>> {
self.add_utxo_valid_block_with_parents(hash, parents, vec![])
}

pub fn build_utxo_valid_block_with_parents(
&self,
hash: Hash,
Expand Down Expand Up @@ -180,7 +194,7 @@ impl TestConsensus {
MutableBlock::new(header, txs)
}

pub fn build_block_with_parents(&self, hash: Hash, parents: Vec<Hash>) -> MutableBlock {
pub fn build_header_only_block_with_parents(&self, hash: Hash, parents: Vec<Hash>) -> MutableBlock {
MutableBlock::from_header(self.build_header_with_parents(hash, parents))
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use super::BlockBodyProcessor;
use crate::{
errors::{BlockProcessResult, RuleError},
model::stores::{ghostdag::GhostdagStoreReader, statuses::StatusesStoreReader},
model::{
services::reachability::ReachabilityService,
stores::{ghostdag::GhostdagStoreReader, pruning::PruningStoreReader, statuses::StatusesStoreReader},
},
processes::window::WindowManager,
};
use kaspa_consensus_core::block::Block;
Expand All @@ -12,16 +15,27 @@ use std::sync::Arc;

impl BlockBodyProcessor {
pub fn validate_body_in_context(self: &Arc<Self>, block: &Block) -> BlockProcessResult<()> {
self.check_block_is_not_pruned(block)?;
self.check_parent_bodies_exist(block)?;
self.check_coinbase_blue_score_and_subsidy(block)?;
self.check_block_transactions_in_context(block)?;
self.check_block_is_not_pruned(block)
self.check_block_transactions_in_context(block)
}

fn check_block_is_not_pruned(self: &Arc<Self>, _block: &Block) -> BlockProcessResult<()> {
// TODO: In kaspad code it checks that the block is not in the past of the current tips.
// We should decide what's the best indication that a block was pruned.
Ok(())
match self.statuses_store.read().get(_block.hash()).unwrap_option() {
Some(_) => {
let Some(pp) = self.pruning_point_store.read().pruning_point().unwrap_option() else {
return Ok(());
};

if self.reachability_service.is_dag_ancestor_of(_block.hash(), pp) {
Err(RuleError::PrunedBlock)
} else {
Ok(())
}
}
None => Ok(()),
}
}

fn check_block_transactions_in_context(self: &Arc<Self>, block: &Block) -> BlockProcessResult<()> {
Expand Down Expand Up @@ -111,7 +125,7 @@ mod tests {
let wait_handles = consensus.init();
let body_processor = consensus.block_body_processor();

consensus.add_block_with_parents(1.into(), vec![config.genesis.hash]).await.unwrap();
consensus.add_header_only_block_with_parents(1.into(), vec![config.genesis.hash]).await.unwrap();

{
let block = consensus.build_block_with_parents_and_transactions(2.into(), vec![1.into()], vec![]);
Expand Down
4 changes: 4 additions & 0 deletions consensus/src/pipeline/body_processor/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
block_transactions::DbBlockTransactionsStore,
ghostdag::DbGhostdagStore,
headers::DbHeadersStore,
pruning::DbPruningStore,
reachability::DbReachabilityStore,
statuses::{DbStatusesStore, StatusesStore, StatusesStoreBatchExtensions, StatusesStoreReader},
tips::{DbTipsStore, TipsStore},
Expand Down Expand Up @@ -59,6 +60,7 @@ pub struct BlockBodyProcessor {
pub(super) headers_store: Arc<DbHeadersStore>,
pub(super) block_transactions_store: Arc<DbBlockTransactionsStore>,
pub(super) body_tips_store: Arc<RwLock<DbTipsStore>>,
pub(super) pruning_point_store: Arc<RwLock<DbPruningStore>>,

// Managers and services
pub(super) reachability_service: MTReachabilityService<DbReachabilityStore>,
Expand Down Expand Up @@ -96,6 +98,7 @@ impl BlockBodyProcessor {
headers_store: Arc<DbHeadersStore>,
block_transactions_store: Arc<DbBlockTransactionsStore>,
body_tips_store: Arc<RwLock<DbTipsStore>>,
pruning_point_store: Arc<RwLock<DbPruningStore>>,

reachability_service: MTReachabilityService<DbReachabilityStore>,
coinbase_manager: CoinbaseManager,
Expand All @@ -120,6 +123,7 @@ impl BlockBodyProcessor {
headers_store,
block_transactions_store,
body_tips_store,
pruning_point_store,
coinbase_manager,
mass_calculator,
transaction_validator,
Expand Down
Loading
Loading