reth_engine_primitives/
invalid_block_hook.rs

1use alloc::{boxed::Box, fmt, vec::Vec};
2use alloy_primitives::B256;
3use reth_execution_types::BlockExecutionOutput;
4use reth_primitives_traits::{NodePrimitives, RecoveredBlock, SealedHeader};
5use reth_trie_common::updates::TrieUpdates;
6
7/// An invalid block hook.
8pub trait InvalidBlockHook<N: NodePrimitives>: Send + Sync {
9    /// Invoked when an invalid block is encountered.
10    fn on_invalid_block(
11        &self,
12        parent_header: &SealedHeader<N::BlockHeader>,
13        block: &RecoveredBlock<N::Block>,
14        output: &BlockExecutionOutput<N::Receipt>,
15        trie_updates: Option<(&TrieUpdates, B256)>,
16    );
17}
18
19impl<F, N> InvalidBlockHook<N> for F
20where
21    N: NodePrimitives,
22    F: Fn(
23            &SealedHeader<N::BlockHeader>,
24            &RecoveredBlock<N::Block>,
25            &BlockExecutionOutput<N::Receipt>,
26            Option<(&TrieUpdates, B256)>,
27        ) + Send
28        + Sync,
29{
30    fn on_invalid_block(
31        &self,
32        parent_header: &SealedHeader<N::BlockHeader>,
33        block: &RecoveredBlock<N::Block>,
34        output: &BlockExecutionOutput<N::Receipt>,
35        trie_updates: Option<(&TrieUpdates, B256)>,
36    ) {
37        self(parent_header, block, output, trie_updates)
38    }
39}
40
41/// A no-op [`InvalidBlockHook`] that does nothing.
42#[derive(Debug, Default)]
43#[non_exhaustive]
44pub struct NoopInvalidBlockHook;
45
46impl<N: NodePrimitives> InvalidBlockHook<N> for NoopInvalidBlockHook {
47    fn on_invalid_block(
48        &self,
49        _parent_header: &SealedHeader<N::BlockHeader>,
50        _block: &RecoveredBlock<N::Block>,
51        _output: &BlockExecutionOutput<N::Receipt>,
52        _trie_updates: Option<(&TrieUpdates, B256)>,
53    ) {
54    }
55}
56
57/// Multiple [`InvalidBlockHook`]s that are executed in order.
58pub struct InvalidBlockHooks<N: NodePrimitives>(pub Vec<Box<dyn InvalidBlockHook<N>>>);
59
60impl<N: NodePrimitives> fmt::Debug for InvalidBlockHooks<N> {
61    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62        f.debug_struct("InvalidBlockHooks").field("len", &self.0.len()).finish()
63    }
64}
65
66impl<N: NodePrimitives> InvalidBlockHook<N> for InvalidBlockHooks<N> {
67    fn on_invalid_block(
68        &self,
69        parent_header: &SealedHeader<N::BlockHeader>,
70        block: &RecoveredBlock<N::Block>,
71        output: &BlockExecutionOutput<N::Receipt>,
72        trie_updates: Option<(&TrieUpdates, B256)>,
73    ) {
74        for hook in &self.0 {
75            hook.on_invalid_block(parent_header, block, output, trie_updates);
76        }
77    }
78}