mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: consensus trait generic over NodePrimitives (#13026)
This commit is contained in:
@ -13,7 +13,7 @@ use reth_blockchain_tree::{
|
||||
};
|
||||
use reth_chainspec::ChainSpec;
|
||||
use reth_config::config::StageConfig;
|
||||
use reth_consensus::{test_utils::TestConsensus, Consensus};
|
||||
use reth_consensus::{test_utils::TestConsensus, FullConsensus};
|
||||
use reth_db::{test_utils::TempDatabase, DatabaseEnv as DE};
|
||||
use reth_downloaders::{
|
||||
bodies::bodies::BodiesDownloaderBuilder,
|
||||
@ -332,7 +332,7 @@ where
|
||||
let provider_factory =
|
||||
create_test_provider_factory_with_chain_spec(self.base_config.chain_spec.clone());
|
||||
|
||||
let consensus: Arc<dyn Consensus> = match self.base_config.consensus {
|
||||
let consensus: Arc<dyn FullConsensus> = match self.base_config.consensus {
|
||||
TestConsensusConfig::Real => {
|
||||
Arc::new(EthBeaconConsensus::new(Arc::clone(&self.base_config.chain_spec)))
|
||||
}
|
||||
@ -374,13 +374,17 @@ where
|
||||
.into_task();
|
||||
|
||||
let body_downloader = BodiesDownloaderBuilder::default()
|
||||
.build(client.clone(), consensus.clone(), provider_factory.clone())
|
||||
.build(
|
||||
client.clone(),
|
||||
consensus.clone().as_consensus(),
|
||||
provider_factory.clone(),
|
||||
)
|
||||
.into_task();
|
||||
|
||||
Pipeline::<MockNodeTypesWithDB>::builder().add_stages(DefaultStages::new(
|
||||
provider_factory.clone(),
|
||||
tip_rx.clone(),
|
||||
Arc::clone(&consensus),
|
||||
consensus.clone().as_consensus(),
|
||||
header_downloader,
|
||||
body_downloader,
|
||||
executor_factory.clone(),
|
||||
|
||||
@ -16,8 +16,8 @@ use alloy_consensus::Header;
|
||||
use alloy_eips::eip7685::Requests;
|
||||
use alloy_primitives::{BlockHash, BlockNumber, Bloom, B256, U256};
|
||||
use reth_primitives::{
|
||||
BlockBody, BlockWithSenders, GotExpected, GotExpectedBoxed, InvalidTransactionError, Receipt,
|
||||
SealedBlock, SealedHeader,
|
||||
BlockBody, BlockWithSenders, EthPrimitives, GotExpected, GotExpectedBoxed,
|
||||
InvalidTransactionError, NodePrimitives, Receipt, SealedBlock, SealedHeader,
|
||||
};
|
||||
use reth_primitives_traits::constants::MINIMUM_GAS_LIMIT;
|
||||
|
||||
@ -28,7 +28,7 @@ pub mod noop;
|
||||
/// test helpers for mocking consensus
|
||||
pub mod test_utils;
|
||||
|
||||
/// Post execution input passed to [`Consensus::validate_block_post_execution`].
|
||||
/// Post execution input passed to [`FullConsensus::validate_block_post_execution`].
|
||||
#[derive(Debug)]
|
||||
pub struct PostExecutionInput<'a, R = Receipt> {
|
||||
/// Receipts of the block.
|
||||
@ -44,11 +44,28 @@ impl<'a, R> PostExecutionInput<'a, R> {
|
||||
}
|
||||
}
|
||||
|
||||
/// [`Consensus`] implementation which knows full node primitives and is able to validation block's
|
||||
/// execution outcome.
|
||||
#[auto_impl::auto_impl(&, Arc)]
|
||||
pub trait FullConsensus<N: NodePrimitives = EthPrimitives>:
|
||||
AsConsensus<N::BlockHeader, N::BlockBody>
|
||||
{
|
||||
/// Validate a block considering world state, i.e. things that can not be checked before
|
||||
/// execution.
|
||||
///
|
||||
/// See the Yellow Paper sections 4.3.2 "Holistic Validity".
|
||||
///
|
||||
/// Note: validating blocks does not include other validations of the Consensus
|
||||
fn validate_block_post_execution(
|
||||
&self,
|
||||
block: &BlockWithSenders<N::Block>,
|
||||
input: PostExecutionInput<'_, N::Receipt>,
|
||||
) -> Result<(), ConsensusError>;
|
||||
}
|
||||
|
||||
/// Consensus is a protocol that chooses canonical chain.
|
||||
#[auto_impl::auto_impl(&, Arc)]
|
||||
pub trait Consensus<H = Header, B = BlockBody>:
|
||||
AsHeaderValidator<H> + HeaderValidator<H> + Debug + Send + Sync
|
||||
{
|
||||
pub trait Consensus<H = Header, B = BlockBody>: AsHeaderValidator<H> {
|
||||
/// Ensures that body field values match the header.
|
||||
fn validate_body_against_header(
|
||||
&self,
|
||||
@ -67,18 +84,6 @@ pub trait Consensus<H = Header, B = BlockBody>:
|
||||
/// Note: validating blocks does not include other validations of the Consensus
|
||||
fn validate_block_pre_execution(&self, block: &SealedBlock<H, B>)
|
||||
-> Result<(), ConsensusError>;
|
||||
|
||||
/// Validate a block considering world state, i.e. things that can not be checked before
|
||||
/// execution.
|
||||
///
|
||||
/// See the Yellow Paper sections 4.3.2 "Holistic Validity".
|
||||
///
|
||||
/// Note: validating blocks does not include other validations of the Consensus
|
||||
fn validate_block_post_execution(
|
||||
&self,
|
||||
block: &BlockWithSenders,
|
||||
input: PostExecutionInput<'_>,
|
||||
) -> Result<(), ConsensusError>;
|
||||
}
|
||||
|
||||
/// HeaderValidator is a protocol that validates headers and their relationships.
|
||||
@ -162,6 +167,23 @@ impl<T: HeaderValidator<H>, H> AsHeaderValidator<H> for T {
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper trait to cast `Arc<dyn FullConsensus>` to `Arc<dyn Consensus>`
|
||||
pub trait AsConsensus<H, B>: Consensus<H, B> {
|
||||
/// Converts the [`Arc`] of self to [`Arc`] of [`HeaderValidator`]
|
||||
fn as_consensus<'a>(self: Arc<Self>) -> Arc<dyn Consensus<H, B> + 'a>
|
||||
where
|
||||
Self: 'a;
|
||||
}
|
||||
|
||||
impl<T: Consensus<H, B>, H, B> AsConsensus<H, B> for T {
|
||||
fn as_consensus<'a>(self: Arc<Self>) -> Arc<dyn Consensus<H, B> + 'a>
|
||||
where
|
||||
Self: 'a,
|
||||
{
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Consensus Errors
|
||||
#[derive(Debug, PartialEq, Eq, Clone, derive_more::Display, derive_more::Error)]
|
||||
pub enum ConsensusError {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use crate::{Consensus, ConsensusError, HeaderValidator, PostExecutionInput};
|
||||
use crate::{Consensus, ConsensusError, FullConsensus, HeaderValidator, PostExecutionInput};
|
||||
use alloy_primitives::U256;
|
||||
use reth_primitives::{BlockWithSenders, SealedBlock, SealedHeader};
|
||||
use reth_primitives::{BlockWithSenders, NodePrimitives, SealedBlock, SealedHeader};
|
||||
|
||||
/// A Consensus implementation that does nothing.
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
@ -44,11 +44,13 @@ impl<H, B> Consensus<H, B> for NoopConsensus {
|
||||
) -> Result<(), ConsensusError> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: NodePrimitives> FullConsensus<N> for NoopConsensus {
|
||||
fn validate_block_post_execution(
|
||||
&self,
|
||||
_block: &BlockWithSenders,
|
||||
_input: PostExecutionInput<'_>,
|
||||
_block: &BlockWithSenders<N::Block>,
|
||||
_input: PostExecutionInput<'_, N::Receipt>,
|
||||
) -> Result<(), ConsensusError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::{Consensus, ConsensusError, HeaderValidator, PostExecutionInput};
|
||||
use crate::{Consensus, ConsensusError, FullConsensus, HeaderValidator, PostExecutionInput};
|
||||
use alloy_primitives::U256;
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
use reth_primitives::{BlockWithSenders, SealedBlock, SealedHeader};
|
||||
use reth_primitives::{BlockWithSenders, NodePrimitives, SealedBlock, SealedHeader};
|
||||
|
||||
/// Consensus engine implementation for testing
|
||||
#[derive(Debug)]
|
||||
@ -46,6 +46,20 @@ impl TestConsensus {
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: NodePrimitives> FullConsensus<N> for TestConsensus {
|
||||
fn validate_block_post_execution(
|
||||
&self,
|
||||
_block: &BlockWithSenders<N::Block>,
|
||||
_input: PostExecutionInput<'_, N::Receipt>,
|
||||
) -> Result<(), ConsensusError> {
|
||||
if self.fail_validation() {
|
||||
Err(ConsensusError::BaseFeeMissing)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<H, B> Consensus<H, B> for TestConsensus {
|
||||
fn validate_body_against_header(
|
||||
&self,
|
||||
@ -69,18 +83,6 @@ impl<H, B> Consensus<H, B> for TestConsensus {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_block_post_execution(
|
||||
&self,
|
||||
_block: &BlockWithSenders,
|
||||
_input: PostExecutionInput<'_>,
|
||||
) -> Result<(), ConsensusError> {
|
||||
if self.fail_validation() {
|
||||
Err(ConsensusError::BaseFeeMissing)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<H> HeaderValidator<H> for TestConsensus {
|
||||
|
||||
Reference in New Issue
Block a user