reth_consensus/
test_utils.rs

1use crate::{Consensus, ConsensusError, FullConsensus, HeaderValidator, ReceiptRootBloom};
2use core::sync::atomic::{AtomicBool, Ordering};
3use reth_execution_types::BlockExecutionResult;
4use reth_primitives_traits::{Block, NodePrimitives, RecoveredBlock, SealedBlock, SealedHeader};
5
6/// Consensus engine implementation for testing
7#[derive(Debug)]
8pub struct TestConsensus {
9    /// Flag whether the header validation should purposefully fail
10    fail_validation: AtomicBool,
11    /// Separate flag for setting whether `validate_body_against_header` should fail. It is needed
12    /// for testing networking logic for which the body failing this check is getting completely
13    /// rejected while more high-level failures are handled by the sync logic.
14    fail_body_against_header: AtomicBool,
15}
16
17impl Default for TestConsensus {
18    fn default() -> Self {
19        Self {
20            fail_validation: AtomicBool::new(false),
21            fail_body_against_header: AtomicBool::new(false),
22        }
23    }
24}
25
26impl TestConsensus {
27    /// Get the failed validation flag.
28    pub fn fail_validation(&self) -> bool {
29        self.fail_validation.load(Ordering::SeqCst)
30    }
31
32    /// Update the validation flag.
33    pub fn set_fail_validation(&self, val: bool) {
34        self.fail_validation.store(val, Ordering::SeqCst);
35        self.fail_body_against_header.store(val, Ordering::SeqCst);
36    }
37
38    /// Returns the body validation flag.
39    pub fn fail_body_against_header(&self) -> bool {
40        self.fail_body_against_header.load(Ordering::SeqCst)
41    }
42
43    /// Update the body validation flag.
44    pub fn set_fail_body_against_header(&self, val: bool) {
45        self.fail_body_against_header.store(val, Ordering::SeqCst);
46    }
47}
48
49impl<N: NodePrimitives> FullConsensus<N> for TestConsensus {
50    fn validate_block_post_execution(
51        &self,
52        _block: &RecoveredBlock<N::Block>,
53        _result: &BlockExecutionResult<N::Receipt>,
54        _receipt_root_bloom: Option<ReceiptRootBloom>,
55    ) -> Result<(), ConsensusError> {
56        if self.fail_validation() {
57            Err(ConsensusError::BaseFeeMissing)
58        } else {
59            Ok(())
60        }
61    }
62}
63
64impl<B: Block> Consensus<B> for TestConsensus {
65    fn validate_body_against_header(
66        &self,
67        _body: &B::Body,
68        _header: &SealedHeader<B::Header>,
69    ) -> Result<(), ConsensusError> {
70        if self.fail_body_against_header() {
71            Err(ConsensusError::BaseFeeMissing)
72        } else {
73            Ok(())
74        }
75    }
76
77    fn validate_block_pre_execution(&self, _block: &SealedBlock<B>) -> Result<(), ConsensusError> {
78        if self.fail_validation() {
79            Err(ConsensusError::BaseFeeMissing)
80        } else {
81            Ok(())
82        }
83    }
84}
85
86impl<H> HeaderValidator<H> for TestConsensus {
87    fn validate_header(&self, _header: &SealedHeader<H>) -> Result<(), ConsensusError> {
88        if self.fail_validation() {
89            Err(ConsensusError::BaseFeeMissing)
90        } else {
91            Ok(())
92        }
93    }
94
95    fn validate_header_against_parent(
96        &self,
97        _header: &SealedHeader<H>,
98        _parent: &SealedHeader<H>,
99    ) -> Result<(), ConsensusError> {
100        if self.fail_validation() {
101            Err(ConsensusError::BaseFeeMissing)
102        } else {
103            Ok(())
104        }
105    }
106}