Skip to content

Commit f561724

Browse files
committed
Send NewTip event on block invalidation and resetting failure flags
1 parent 7c14cdd commit f561724

23 files changed

Lines changed: 354 additions & 74 deletions

File tree

blockprod/src/detail/job_manager/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ impl JobManager {
289289
height: _,
290290
is_initial_block_download: _,
291291
} => {
292-
_ = chainstate_sender.send(block_id.into()).log_err_pfx(
292+
_ = chainstate_sender.send(block_id).log_err_pfx(
293293
"Chainstate subscriber failed to send new tip",
294294
);
295295
}

chainstate/src/detail/block_invalidation/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,32 +328,46 @@ impl<'a, S: BlockchainStorage, V: TransactionVerificationStrategy> BlockInvalida
328328
pub enum BlockInvalidatorError {
329329
#[error("Block storage error: {0}")]
330330
StorageError(#[from] chainstate_storage::Error),
331+
331332
#[error("The block {0} is too deep to invalidate")]
332333
BlockTooDeepToInvalidate(Id<Block>),
334+
333335
#[error("Error manipulating best chain candidates: {0}")]
334336
BestChainCandidatesError(#[from] BestChainCandidatesError),
337+
335338
#[error("Error disconnecting blocks until block {disconnect_until}: {error}")]
336339
BlocksDisconnectionError {
337340
disconnect_until: Id<GenBlock>,
338341
error: Box<BlockError>,
339342
},
343+
340344
#[error("Error updating block status for block {0}: {1}")]
341345
BlockStatusUpdateError(Id<Block>, Box<BlockError>),
346+
342347
#[error("Generic error during reorg: {0}")]
343348
GenericReorgError(Box<BlockError>),
349+
344350
#[error("Failed to commit to the DB after {0} attempts: {1}, context: {2}")]
345351
DbCommitError(usize, chainstate_storage::Error, DbCommittingContext),
346352

347353
#[error("Failed to obtain best block index: {0}")]
348354
BlockIndicesForBranchQueryError(PropertyQueryError),
355+
349356
#[error("Failed to determine if the block {0} is in mainchain: {1}")]
350357
IsBlockInMainChainQueryError(Id<GenBlock>, PropertyQueryError),
358+
351359
#[error("Failed to obtain the minimum height with allowed reorgs: {0}")]
352360
MinHeightForReorgQueryError(PropertyQueryError),
361+
353362
#[error("Failed to obtain best block index: {0}")]
354363
BestBlockIndexQueryError(PropertyQueryError),
364+
365+
#[error("Failed to obtain best block id: {0}")]
366+
BestBlockIdQueryError(PropertyQueryError),
367+
355368
#[error("Failed to obtain block index for block {0}: {1}")]
356369
BlockIndexQueryError(Id<GenBlock>, PropertyQueryError),
370+
357371
#[error("Error deleting index for block {0}: {1}")]
358372
DelBlockIndexError(Id<Block>, BlockError),
359373
}

chainstate/src/detail/mod.rs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ impl<S: BlockchainStorage, V: TransactionVerificationStrategy> Chainstate<S, V>
270270

271271
fn broadcast_new_tip_event(
272272
&mut self,
273-
best_block_index: &BlockIndex,
273+
best_block_index: GenBlockIndexRef<'_>,
274274
is_initial_block_download: bool,
275275
) {
276276
let event = ChainstateEvent::NewTip {
@@ -623,7 +623,10 @@ impl<S: BlockchainStorage, V: TransactionVerificationStrategy> Chainstate<S, V>
623623

624624
if let Some(best_block_index) = &best_block_index_opt {
625625
self.update_initial_block_download_flag(GenBlockIndexRef::Block(best_block_index));
626-
self.broadcast_new_tip_event(best_block_index, self.is_initial_block_download());
626+
self.broadcast_new_tip_event(
627+
GenBlockIndexRef::Block(best_block_index),
628+
self.is_initial_block_download(),
629+
);
627630

628631
let compact_target = match best_block_index.block_header().consensus_data() {
629632
ConsensusData::None => Compact::from(Uint256::ZERO),
@@ -707,15 +710,60 @@ impl<S: BlockchainStorage, V: TransactionVerificationStrategy> Chainstate<S, V>
707710

708711
#[log_error]
709712
pub fn invalidate_block(&mut self, block_id: &Id<Block>) -> Result<(), BlockInvalidatorError> {
713+
let prev_best_block_id = self
714+
.make_db_tx_ro()?
715+
.get_best_block_id()
716+
.map_err(BlockInvalidatorError::BestBlockIdQueryError)?;
717+
710718
let result = BlockInvalidator::new(self)
711719
.invalidate_block(block_id, block_invalidation::IsExplicit::Yes);
712720
// Note: we don't ignore the result of check_consistency even though we may already have
713721
// an error to return (if the checks are enabled but couldn't be done for some reason,
714722
// we don't want to miss this).
715723
self.check_consistency()?;
724+
725+
let new_best_block_index = self
726+
.make_db_tx_ro()?
727+
.get_best_block_index()
728+
.map_err(BlockInvalidatorError::BestBlockIndexQueryError)?;
729+
730+
if new_best_block_index.block_id() != prev_best_block_id {
731+
self.broadcast_new_tip_event(
732+
new_best_block_index.as_ref(),
733+
self.is_initial_block_download(),
734+
);
735+
}
736+
716737
result
717738
}
718739

740+
#[log_error]
741+
pub fn reset_block_failure_flags(
742+
&mut self,
743+
block_id: &Id<Block>,
744+
) -> Result<(), BlockInvalidatorError> {
745+
let prev_best_block_id = self
746+
.make_db_tx_ro()?
747+
.get_best_block_id()
748+
.map_err(BlockInvalidatorError::BestBlockIdQueryError)?;
749+
750+
BlockInvalidator::new(self).reset_block_failure_flags(block_id)?;
751+
752+
let new_best_block_index = self
753+
.make_db_tx_ro()?
754+
.get_best_block_index()
755+
.map_err(BlockInvalidatorError::BestBlockIndexQueryError)?;
756+
757+
if new_best_block_index.block_id() != prev_best_block_id {
758+
self.broadcast_new_tip_event(
759+
new_best_block_index.as_ref(),
760+
self.is_initial_block_download(),
761+
);
762+
}
763+
764+
Ok(())
765+
}
766+
719767
#[log_error]
720768
fn create_pool_in_storage(
721769
&self,

chainstate/src/interface/chainstate_interface_impl.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use crate::{
2323
detail::{
2424
self,
2525
block_checking::BlockChecker,
26-
block_invalidation::BlockInvalidator,
2726
bootstrap::{export_bootstrap_stream, import_bootstrap_stream},
2827
calculate_median_time_past,
2928
tx_verification_strategy::TransactionVerificationStrategy,
@@ -108,7 +107,7 @@ where
108107

109108
#[tracing::instrument(skip_all, fields(id = %block_id))]
110109
fn reset_block_failure_flags(&mut self, block_id: &Id<Block>) -> Result<(), ChainstateError> {
111-
BlockInvalidator::new(&mut self.chainstate)
110+
self.chainstate
112111
.reset_block_failure_flags(block_id)
113112
.map_err(ChainstateError::BlockInvalidatorError)
114113
}

chainstate/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub use tx_verifier;
5252
#[derive(Debug, Clone, Eq, PartialEq)]
5353
pub enum ChainstateEvent {
5454
NewTip {
55-
id: Id<Block>,
55+
id: Id<GenBlock>,
5656
height: BlockHeight,
5757
is_initial_block_download: bool,
5858
},

chainstate/src/rpc/types/event.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// limitations under the License.
1515

1616
use common::{
17-
chain::Block,
17+
chain::GenBlock,
1818
primitives::{BlockHeight, Id},
1919
};
2020

@@ -23,7 +23,10 @@ use crate::ChainstateEvent;
2323
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, rpc::description::HasValueHint)]
2424
#[serde(tag = "type", content = "content")]
2525
pub enum RpcEvent {
26-
NewTip { id: Id<Block>, height: BlockHeight },
26+
NewTip {
27+
id: Id<GenBlock>,
28+
height: BlockHeight,
29+
},
2730
}
2831

2932
impl RpcEvent {

0 commit comments

Comments
 (0)