mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat(engine): invalid block event (#14365)
This commit is contained in:
@ -10,7 +10,7 @@ use core::{
|
||||
time::Duration,
|
||||
};
|
||||
use reth_chain_state::ExecutedBlockWithTrieUpdates;
|
||||
use reth_primitives::EthPrimitives;
|
||||
use reth_primitives::{EthPrimitives, SealedBlock};
|
||||
use reth_primitives_traits::{NodePrimitives, SealedHeader};
|
||||
|
||||
/// Events emitted by the consensus engine.
|
||||
@ -24,6 +24,8 @@ pub enum BeaconConsensusEngineEvent<N: NodePrimitives = EthPrimitives> {
|
||||
CanonicalBlockAdded(ExecutedBlockWithTrieUpdates<N>, Duration),
|
||||
/// A canonical chain was committed, and the elapsed time committing the data
|
||||
CanonicalChainCommitted(Box<SealedHeader<N::BlockHeader>>, Duration),
|
||||
/// The consensus engine processed an invalid block.
|
||||
InvalidBlock(Box<SealedBlock<N::Block>>),
|
||||
/// The consensus engine is involved in live sync, and has specific progress
|
||||
LiveSyncProgress(ConsensusEngineLiveSyncProgress),
|
||||
}
|
||||
@ -61,6 +63,9 @@ where
|
||||
Self::CanonicalChainCommitted(block, duration) => {
|
||||
write!(f, "CanonicalChainCommitted({:?}, {duration:?})", block.num_hash())
|
||||
}
|
||||
Self::InvalidBlock(block) => {
|
||||
write!(f, "InvalidBlock({:?})", block.num_hash())
|
||||
}
|
||||
Self::LiveSyncProgress(progress) => {
|
||||
write!(f, "LiveSyncProgress({progress:?})")
|
||||
}
|
||||
|
||||
@ -912,7 +912,7 @@ where
|
||||
|
||||
// now check the block itself
|
||||
if let Some(status) =
|
||||
self.check_invalid_ancestor_with_head(lowest_buffered_ancestor, block_hash)?
|
||||
self.check_invalid_ancestor_with_head(lowest_buffered_ancestor, &block)?
|
||||
{
|
||||
return Ok(TreeOutcome::new(status))
|
||||
}
|
||||
@ -1887,7 +1887,7 @@ where
|
||||
fn check_invalid_ancestor_with_head(
|
||||
&mut self,
|
||||
check: B256,
|
||||
head: B256,
|
||||
head: &SealedBlock<N::Block>,
|
||||
) -> ProviderResult<Option<PayloadStatus>> {
|
||||
// check if the check hash was previously marked as invalid
|
||||
let Some(header) = self.state.invalid_headers.get(&check) else { return Ok(None) };
|
||||
@ -1896,7 +1896,8 @@ where
|
||||
let status = self.prepare_invalid_response(header.parent)?;
|
||||
|
||||
// insert the head block into the invalid header cache
|
||||
self.state.invalid_headers.insert_with_invalid_ancestor(head, header);
|
||||
self.state.invalid_headers.insert_with_invalid_ancestor(head.hash(), header);
|
||||
self.emit_event(BeaconConsensusEngineEvent::InvalidBlock(Box::new(head.clone())));
|
||||
|
||||
Ok(Some(status))
|
||||
}
|
||||
@ -2276,7 +2277,7 @@ where
|
||||
let block_num_hash = block.num_hash();
|
||||
let lowest_buffered_ancestor = self.lowest_buffered_ancestor_or(block_num_hash.hash);
|
||||
if self
|
||||
.check_invalid_ancestor_with_head(lowest_buffered_ancestor, block_num_hash.hash)?
|
||||
.check_invalid_ancestor_with_head(lowest_buffered_ancestor, block.sealed_block())?
|
||||
.is_some()
|
||||
{
|
||||
return Ok(None)
|
||||
@ -2841,6 +2842,9 @@ where
|
||||
|
||||
// keep track of the invalid header
|
||||
self.state.invalid_headers.insert(block.block_with_parent());
|
||||
self.emit_event(EngineApiEvent::BeaconConsensus(BeaconConsensusEngineEvent::InvalidBlock(
|
||||
Box::new(block),
|
||||
)));
|
||||
Ok(PayloadStatus::new(
|
||||
PayloadStatusEnum::Invalid { validation_error: validation_err.to_string() },
|
||||
latest_valid_hash,
|
||||
@ -3554,6 +3558,18 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
async fn check_invalid_block(&mut self, expected_hash: B256) {
|
||||
let event = self.from_tree_rx.recv().await.unwrap();
|
||||
match event {
|
||||
EngineApiEvent::BeaconConsensus(BeaconConsensusEngineEvent::InvalidBlock(
|
||||
block,
|
||||
)) => {
|
||||
assert_eq!(block.hash(), expected_hash);
|
||||
}
|
||||
_ => panic!("Unexpected event: {:#?}", event),
|
||||
}
|
||||
}
|
||||
|
||||
fn persist_blocks(&self, blocks: Vec<RecoveredBlock<reth_ethereum_primitives::Block>>) {
|
||||
let mut block_data: Vec<(B256, Block)> = Vec::with_capacity(blocks.len());
|
||||
let mut headers_data: Vec<(B256, Header)> = Vec::with_capacity(blocks.len());
|
||||
@ -4765,6 +4781,9 @@ mod tests {
|
||||
chain_a[..chain_a.len() - invalid_index - 1].iter().cloned(),
|
||||
)
|
||||
.await;
|
||||
for block in &chain_a[chain_a.len() - invalid_index - 1..] {
|
||||
test_harness.check_invalid_block(block.hash()).await;
|
||||
}
|
||||
|
||||
// send FCU to make the tip of chain A, expect invalid
|
||||
let chain_a_tip_hash = chain_a.last().unwrap().hash();
|
||||
|
||||
Reference in New Issue
Block a user