mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-04-30 03:01:58 -04:00
feat: Consensus crate and verification functions. (#152)
* wip executor * wip * Cleanup added some checks and structure to executor * adding additional block/header checks * add basefee calculation and check * some cleanup * Sanity check test * Test for sanity check * move verification to consensus crate * cleanup * Better Error handling
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
use async_trait::async_trait;
|
||||
use reth_primitives::Header;
|
||||
use thiserror::Error;
|
||||
use reth_primitives::{BlockHash, BlockNumber, HeaderLocked, H256};
|
||||
use tokio::sync::watch::Receiver;
|
||||
|
||||
/// Re-export forkchoice state
|
||||
@@ -15,13 +14,40 @@ pub trait Consensus: Send + Sync {
|
||||
fn fork_choice_state(&self) -> Receiver<ForkchoiceState>;
|
||||
|
||||
/// Validate if header is correct and follows consensus specification
|
||||
fn validate_header(&self, header: &Header, parent: &Header) -> Result<(), Error>;
|
||||
fn validate_header(&self, header: &HeaderLocked, parent: &HeaderLocked) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
/// Consensus errors (TODO)
|
||||
#[derive(Error, Debug)]
|
||||
/// Consensus Errors
|
||||
#[allow(missing_docs)]
|
||||
#[derive(thiserror::Error, Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Error {
|
||||
/// Explanatory
|
||||
#[error("Example of consensus error")]
|
||||
ConsensusError,
|
||||
#[error("Block used gas ({gas_used:?}) is greater then gas limit ({gas_limit:?})")]
|
||||
HeaderGasUsedExceedsGasLimit { gas_used: u64, gas_limit: u64 },
|
||||
#[error("Block ommner hash ({got:?}) is different then expected: ({expected:?})")]
|
||||
BodyOmmnersHashDiff { got: H256, expected: H256 },
|
||||
#[error("Block transaction root ({got:?}) is different then expected: ({expected:?})")]
|
||||
BodyTransactionRootDiff { got: H256, expected: H256 },
|
||||
#[error("Block receipts root ({got:?}) is different then expected: ({expected:?})")]
|
||||
BodyReceiptsRootDiff { got: H256, expected: H256 },
|
||||
#[error("Block with [hash:{hash:?},number: {number:}] is already known")]
|
||||
BlockKnown { hash: BlockHash, number: BlockNumber },
|
||||
#[error("Block parent [hash:{hash:?}] is not known")]
|
||||
ParentUnknown { hash: BlockHash },
|
||||
#[error("Block number {block_number:?} is missmatch with parent block number {parent_block_number:?}")]
|
||||
ParentBlockNumberMissmatch { parent_block_number: BlockNumber, block_number: BlockNumber },
|
||||
#[error(
|
||||
"Block timestamp {timestamp:?} is in past in comparison with parent timestamp {parent_timestamp:?}"
|
||||
)]
|
||||
TimestampIsInPast { parent_timestamp: u64, timestamp: u64 },
|
||||
#[error("Block timestamp {timestamp:?} is in future in comparison of our clock time {present_timestamp:?}")]
|
||||
TimestampIsInFuture { timestamp: u64, present_timestamp: u64 },
|
||||
// TODO make better error msg :)
|
||||
#[error("Child gas_limit {child_gas_limit:?} max increase is {parent_gas_limit}/1024")]
|
||||
GasLimitInvalidIncrease { parent_gas_limit: u64, child_gas_limit: u64 },
|
||||
#[error("Child gas_limit {child_gas_limit:?} max decrease is {parent_gas_limit}/1024")]
|
||||
GasLimitInvalidDecrease { parent_gas_limit: u64, child_gas_limit: u64 },
|
||||
#[error("Base fee missing")]
|
||||
BaseFeeMissing,
|
||||
#[error("Block base fee ({got:?}) is different then expected: ({expected:?})")]
|
||||
BaseFeeDiff { expected: u64, got: u64 },
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
/// Core error variants possible when interacting with the blockchain
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, Clone, PartialEq, Eq)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum Error {
|
||||
#[error(transparent)]
|
||||
|
||||
@@ -14,7 +14,7 @@ pub trait BlockExecutor {
|
||||
}
|
||||
|
||||
/// BlockExecutor Errors
|
||||
#[derive(Error, Debug, Clone)]
|
||||
#[derive(Error, Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Error {
|
||||
/// Example of error
|
||||
#[error("Example of error.")]
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
use crate::Result;
|
||||
use auto_impl::auto_impl;
|
||||
use reth_primitives::{
|
||||
rpc::{BlockId, BlockNumber},
|
||||
Block, H256, U256,
|
||||
Block, BlockHash, Header, H256, U256,
|
||||
};
|
||||
|
||||
/// Client trait for fetching `Header` related data.
|
||||
#[auto_impl(&)]
|
||||
pub trait HeaderProvider: Send + Sync + 'static {
|
||||
/// Check if block is known
|
||||
fn is_known(&self, block_hash: &BlockHash) -> Result<bool> {
|
||||
self.header(block_hash).map(|header| header.is_some())
|
||||
}
|
||||
|
||||
/// Get header by block hash
|
||||
fn header(&self, block_hash: &BlockHash) -> Result<Option<Header>>;
|
||||
}
|
||||
|
||||
/// Client trait for fetching `Block` related data.
|
||||
pub trait BlockProvider: Send + Sync + 'static {
|
||||
/// Returns the current info for the chain.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
mod block;
|
||||
mod storage;
|
||||
|
||||
pub use block::BlockProvider;
|
||||
pub use block::{BlockProvider, HeaderProvider};
|
||||
pub use storage::StorageProvider;
|
||||
|
||||
@@ -155,9 +155,13 @@ impl Consensus for TestConsensus {
|
||||
self.channel.1.clone()
|
||||
}
|
||||
|
||||
fn validate_header(&self, _header: &Header, _parent: &Header) -> Result<(), consensus::Error> {
|
||||
fn validate_header(
|
||||
&self,
|
||||
_header: &HeaderLocked,
|
||||
_parent: &HeaderLocked,
|
||||
) -> Result<(), consensus::Error> {
|
||||
if self.fail_validation {
|
||||
Err(consensus::Error::ConsensusError)
|
||||
Err(consensus::Error::BaseFeeMissing)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user