refactor: unify all chains confs (#747)

Co-authored-by: Bjerg <onbjerg@users.noreply.github.com>
This commit is contained in:
Aurélien
2023-01-17 16:47:34 +01:00
committed by GitHub
parent 55d1db0c1d
commit f9de425ad8
33 changed files with 28324 additions and 737 deletions

View File

@ -1,100 +0,0 @@
//! Reth block execution/validation configuration and constants
use reth_executor::{Config as ExecutorConfig, SpecUpgrades};
use reth_primitives::{BlockNumber, U256};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
/// Initial base fee as defined in: https://eips.ethereum.org/EIPS/eip-1559
pub const EIP1559_INITIAL_BASE_FEE: u64 = 1_000_000_000;
/// Base fee max change denominator as defined in: https://eips.ethereum.org/EIPS/eip-1559
pub const EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR: u64 = 8;
/// Elasticity multiplier as defined in: https://eips.ethereum.org/EIPS/eip-1559
pub const EIP1559_ELASTICITY_MULTIPLIER: u64 = 2;
/// Common configuration for consensus algorithms.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct Config {
/// Blockchain identifier introduced in EIP-155: Simple replay attack protection.
pub chain_id: u64,
/// Homestead switch block.
pub homestead_block: BlockNumber,
/// TheDAO hard-fork switch block.
pub dao_fork_block: BlockNumber,
/// Whether the node supports or opposes the DAO hard-fork
pub dao_fork_support: bool,
/// EIP150 implements gas price changes.
pub eip_150_block: BlockNumber,
/// EIP155 hard-fork block (Spurious Dragon)
pub eip_155_block: BlockNumber,
/// EIP158 hard-fork block.
pub eip_158_block: BlockNumber,
/// Byzantium switch block.
pub byzantium_block: BlockNumber,
/// Constantinople switch block.
pub constantinople_block: BlockNumber,
/// Petersburg switch block.
pub petersburg_block: BlockNumber,
/// Istanbul switch block.
pub istanbul_block: BlockNumber,
/// EIP-2728 switch block.
pub berlin_block: BlockNumber,
/// EIP-1559 switch block.
pub london_block: BlockNumber,
/// The Merge/Paris hard-fork block number.
pub paris_block: BlockNumber,
/// Terminal total difficulty after the paris hard-fork to reach before The Merge is considered
/// activated.
#[cfg_attr(feature = "serde", serde(rename = "terminalTotalDifficulty"))]
pub merge_terminal_total_difficulty: u128,
}
impl Default for Config {
fn default() -> Self {
Self {
chain_id: 1,
homestead_block: 1150000,
dao_fork_block: 1920000,
dao_fork_support: true,
eip_150_block: 2463000,
eip_155_block: 2675000,
eip_158_block: 2675000,
byzantium_block: 4370000,
constantinople_block: 7280000,
petersburg_block: 7280000,
istanbul_block: 9069000,
berlin_block: 12244000,
london_block: 12965000,
paris_block: 15537394,
merge_terminal_total_difficulty: 58750000000000000000000,
}
}
}
impl From<&Config> for ExecutorConfig {
fn from(value: &Config) -> Self {
Self {
chain_id: U256::from(value.chain_id),
spec_upgrades: SpecUpgrades {
frontier: 0,
homestead: value.homestead_block,
dao_fork: value.dao_fork_block,
tangerine_whistle: value.eip_150_block,
spurious_dragon: value.eip_158_block,
byzantium: value.byzantium_block,
petersburg: value.petersburg_block,
istanbul: value.istanbul_block,
berlin: value.berlin_block,
london: value.london_block,
paris: value.paris_block,
shanghai: u64::MAX, // TODO: change once known
},
}
}
}

View File

@ -1,7 +1,7 @@
//! Consensus for ethereum network
use crate::{verification, Config};
use crate::verification;
use reth_interfaces::consensus::{Consensus, Error, ForkchoiceState};
use reth_primitives::{BlockNumber, SealedBlock, SealedHeader, H256};
use reth_primitives::{BlockNumber, ChainSpec, SealedBlock, SealedHeader, H256};
use tokio::sync::{watch, watch::error::SendError};
/// Ethereum beacon consensus
@ -12,19 +12,19 @@ pub struct BeaconConsensus {
/// Watcher over the forkchoice state
channel: (watch::Sender<ForkchoiceState>, watch::Receiver<ForkchoiceState>),
/// Configuration
config: Config,
chain_spec: ChainSpec,
}
impl BeaconConsensus {
/// Create a new instance of [BeaconConsensus]
pub fn new(config: Config) -> Self {
pub fn new(chain_spec: ChainSpec) -> Self {
Self {
channel: watch::channel(ForkchoiceState {
head_block_hash: H256::zero(),
finalized_block_hash: H256::zero(),
safe_block_hash: H256::zero(),
}),
config,
chain_spec,
}
}
@ -43,10 +43,10 @@ impl Consensus for BeaconConsensus {
}
fn validate_header(&self, header: &SealedHeader, parent: &SealedHeader) -> Result<(), Error> {
verification::validate_header_standalone(header, &self.config)?;
verification::validate_header_regarding_parent(parent, header, &self.config)?;
verification::validate_header_standalone(header, &self.chain_spec)?;
verification::validate_header_regarding_parent(parent, header, &self.chain_spec)?;
if header.number < self.config.paris_block {
if Some(header.number) < self.chain_spec.paris_status().block_number() {
// TODO Consensus checks for old blocks:
// * difficulty, mix_hash & nonce aka PoW stuff
// low priority as syncing is done in reverse order
@ -59,6 +59,6 @@ impl Consensus for BeaconConsensus {
}
fn has_block_reward(&self, block_num: BlockNumber) -> bool {
block_num < self.config.paris_block
Some(block_num) < self.chain_spec.paris_status().block_number()
}
}

View File

@ -0,0 +1,8 @@
//! Reth block execution/validation configuration and constants
/// Initial base fee as defined in: https://eips.ethereum.org/EIPS/eip-1559
pub const EIP1559_INITIAL_BASE_FEE: u64 = 1_000_000_000;
/// Base fee max change denominator as defined in: https://eips.ethereum.org/EIPS/eip-1559
pub const EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR: u64 = 8;
/// Elasticity multiplier as defined in: https://eips.ethereum.org/EIPS/eip-1559
pub const EIP1559_ELASTICITY_MULTIPLIER: u64 = 2;

View File

@ -64,6 +64,9 @@ pub enum EngineApiError {
/// Forkchoice zero hash head received.
#[error("Received zero hash as forkchoice head")]
ForkchoiceEmptyHead,
/// Chain spec merge terminal total difficulty is not set
#[error("The merge terminal total difficulty is not known")]
UnknownMergeTerminalTotalDifficulty,
/// Encountered decoding error.
#[error(transparent)]
Decode(#[from] reth_rlp::DecodeError),

View File

@ -7,7 +7,7 @@ use reth_interfaces::consensus::ForkchoiceState;
use reth_primitives::{
proofs::{self, EMPTY_LIST_HASH},
rpc::{BlockId, H256 as EthersH256},
Header, SealedBlock, TransactionSigned, H64, U256,
ChainSpec, Header, SealedBlock, TransactionSigned, H64, U256,
};
use reth_provider::{BlockProvider, HeaderProvider, StateProvider};
use reth_rlp::Decodable;
@ -25,8 +25,6 @@ use std::{
use tokio::sync::oneshot;
use tokio_stream::wrappers::UnboundedReceiverStream;
use crate::Config;
mod error;
pub use error::{EngineApiError, EngineApiResult};
@ -80,7 +78,7 @@ pub enum EngineMessage {
pub struct EthConsensusEngine<Client> {
client: Arc<Client>,
/// Consensus configuration
config: Config,
chain_spec: ChainSpec,
rx: UnboundedReceiverStream<EngineMessage>,
// TODO: Placeholder for storing future blocks. Make cache bounded.
// Use [lru](https://crates.io/crates/lru) crate
@ -190,7 +188,7 @@ impl<Client: HeaderProvider + BlockProvider + StateProvider> ConsensusEngine
};
if let Some(parent_td) = self.client.header_td(&block.parent_hash)? {
if parent_td <= U256::from(self.config.merge_terminal_total_difficulty) {
if Some(parent_td) <= self.chain_spec.paris_status().terminal_total_difficulty() {
return Ok(PayloadStatus::from_status(PayloadStatusEnum::Invalid {
validation_error: EngineApiError::PayloadPreMerge.to_string(),
}))
@ -216,12 +214,11 @@ impl<Client: HeaderProvider + BlockProvider + StateProvider> ConsensusEngine
})
.collect::<Result<Vec<_>, EngineApiError>>()?;
let mut state_provider = SubState::new(State::new(&*self.client));
let config = (&self.config).into();
match executor::execute_and_verify_receipt(
&header,
&transactions,
&[],
&config,
&self.chain_spec,
&mut state_provider,
) {
Ok(_) => Ok(PayloadStatus::new(PayloadStatusEnum::Valid, header.hash())),
@ -272,8 +269,13 @@ impl<Client: HeaderProvider + BlockProvider + StateProvider> ConsensusEngine
terminal_block_number,
} = config;
let merge_terminal_td = self
.chain_spec
.paris_status()
.terminal_total_difficulty()
.ok_or(EngineApiError::UnknownMergeTerminalTotalDifficulty)?;
// Compare total difficulty values
let merge_terminal_td = U256::from(self.config.merge_terminal_total_difficulty);
if merge_terminal_td != terminal_total_difficulty {
return Err(EngineApiError::TerminalTD {
execution: merge_terminal_td,
@ -340,7 +342,7 @@ mod tests {
use super::*;
use bytes::{Bytes, BytesMut};
use reth_interfaces::test_utils::generators::random_header;
use reth_primitives::Block;
use reth_primitives::{Block, MAINNET};
use reth_rlp::DecodeError;
fn transform_block<F: FnOnce(Block) -> Block>(src: SealedBlock, f: F) -> SealedBlock {
@ -363,7 +365,7 @@ mod tests {
let (_tx, rx) = unbounded_channel();
let engine = EthConsensusEngine {
client: Arc::new(MockEthProvider::default()),
config: Config::default(),
chain_spec: MAINNET.clone(),
local_store: Default::default(),
rx: UnboundedReceiverStream::new(rx),
};
@ -452,7 +454,7 @@ mod tests {
let client = Arc::new(MockEthProvider::default());
let engine = EthConsensusEngine {
client: client.clone(),
config: Config::default(),
chain_spec: MAINNET.clone(),
local_store: Default::default(),
rx: UnboundedReceiverStream::new(rx),
};
@ -480,7 +482,7 @@ mod tests {
let (tx, rx) = unbounded_channel();
let engine = EthConsensusEngine {
client: Arc::new(MockEthProvider::default()),
config: Config::default(),
chain_spec: MAINNET.clone(),
local_store: Default::default(),
rx: UnboundedReceiverStream::new(rx),
};
@ -501,11 +503,11 @@ mod tests {
#[tokio::test]
async fn payload_pre_merge() {
let (tx, rx) = unbounded_channel();
let config = Config::default();
let chain_spec = MAINNET.clone();
let client = Arc::new(MockEthProvider::default());
let engine = EthConsensusEngine {
client: client.clone(),
config: config.clone(),
chain_spec: chain_spec.clone(),
local_store: Default::default(),
rx: UnboundedReceiverStream::new(rx),
};
@ -514,7 +516,8 @@ mod tests {
let (result_tx, result_rx) = oneshot::channel();
let parent = transform_block(random_block(100, None, None, Some(0)), |mut b| {
b.header.difficulty = U256::from(config.merge_terminal_total_difficulty);
b.header.difficulty =
chain_spec.paris_status().terminal_total_difficulty().unwrap();
b
});
let block = random_block(101, Some(parent.hash()), None, Some(0));
@ -535,11 +538,11 @@ mod tests {
#[tokio::test]
async fn invalid_payload_timestamp() {
let (tx, rx) = unbounded_channel();
let config = Config::default();
let chain_spec = MAINNET.clone();
let client = Arc::new(MockEthProvider::default());
let engine = EthConsensusEngine {
client: client.clone(),
config: config.clone(),
chain_spec: chain_spec.clone(),
local_store: Default::default(),
rx: UnboundedReceiverStream::new(rx),
};
@ -551,7 +554,8 @@ mod tests {
let parent_timestamp = block_timestamp + 10;
let parent = transform_block(random_block(100, None, None, Some(0)), |mut b| {
b.header.timestamp = parent_timestamp;
b.header.difficulty = U256::from(config.merge_terminal_total_difficulty + 1);
b.header.difficulty =
chain_spec.paris_status().terminal_total_difficulty().unwrap() + U256::from(1);
b
});
let block =
@ -583,6 +587,8 @@ mod tests {
// non exhaustive tests for engine_getPayload
// TODO: amend when block building is implemented
mod get_payload {
use reth_primitives::MAINNET;
use super::*;
#[tokio::test]
@ -590,7 +596,7 @@ mod tests {
let (tx, rx) = unbounded_channel();
let engine = EthConsensusEngine {
client: Arc::new(MockEthProvider::default()),
config: Config::default(),
chain_spec: MAINNET.clone(),
local_store: Default::default(),
rx: UnboundedReceiverStream::new(rx),
};
@ -609,15 +615,17 @@ mod tests {
// https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#specification-3
mod exchange_transition_configuration {
use reth_primitives::MAINNET;
use super::*;
#[tokio::test]
async fn terminal_td_mismatch() {
let (tx, rx) = unbounded_channel();
let config = Config::default();
let chain_spec = MAINNET.clone();
let engine = EthConsensusEngine {
client: Arc::new(MockEthProvider::default()),
config: config.clone(),
chain_spec: chain_spec.clone(),
local_store: Default::default(),
rx: UnboundedReceiverStream::new(rx),
};
@ -625,7 +633,11 @@ mod tests {
tokio::spawn(engine);
let transition_config = TransitionConfiguration {
terminal_total_difficulty: U256::from(config.merge_terminal_total_difficulty + 1),
terminal_total_difficulty: chain_spec
.paris_status()
.terminal_total_difficulty()
.unwrap() +
U256::from(1),
..Default::default()
};
@ -639,7 +651,7 @@ mod tests {
assert_matches!(
result_rx.await,
Ok(Err(EngineApiError::TerminalTD { execution, consensus }))
if execution == U256::from(config.merge_terminal_total_difficulty)
if execution == chain_spec.paris_status().terminal_total_difficulty().unwrap()
&& consensus == U256::from(transition_config.terminal_total_difficulty)
);
}
@ -648,10 +660,10 @@ mod tests {
async fn terminal_block_hash_mismatch() {
let (tx, rx) = unbounded_channel();
let client = Arc::new(MockEthProvider::default());
let config = Config::default();
let chain_spec = MAINNET.clone();
let engine = EthConsensusEngine {
client: client.clone(),
config: config.clone(),
chain_spec: chain_spec.clone(),
local_store: Default::default(),
rx: UnboundedReceiverStream::new(rx),
};
@ -663,7 +675,10 @@ mod tests {
let execution_terminal_block = random_block(terminal_block_number, None, None, None);
let transition_config = TransitionConfiguration {
terminal_total_difficulty: U256::from(config.merge_terminal_total_difficulty),
terminal_total_difficulty: chain_spec
.paris_status()
.terminal_total_difficulty()
.unwrap(),
terminal_block_hash: consensus_terminal_block.hash(),
terminal_block_number: terminal_block_number.into(),
};
@ -708,10 +723,10 @@ mod tests {
async fn configurations_match() {
let (tx, rx) = unbounded_channel();
let client = Arc::new(MockEthProvider::default());
let config = Config::default();
let chain_spec = MAINNET.clone();
let engine = EthConsensusEngine {
client: client.clone(),
config: config.clone(),
chain_spec: chain_spec.clone(),
local_store: Default::default(),
rx: UnboundedReceiverStream::new(rx),
};
@ -722,7 +737,10 @@ mod tests {
let terminal_block = random_block(terminal_block_number, None, None, None);
let transition_config = TransitionConfiguration {
terminal_total_difficulty: U256::from(config.merge_terminal_total_difficulty),
terminal_total_difficulty: chain_spec
.paris_status()
.terminal_total_difficulty()
.unwrap(),
terminal_block_hash: terminal_block.hash(),
terminal_block_number: terminal_block_number.into(),
};

View File

@ -9,13 +9,12 @@
//! # Features
//!
//! - `serde`: Enable serde support for configuration types.
pub mod config;
pub mod consensus;
pub mod constants;
pub mod verification;
/// Engine API module.
pub mod engine;
pub use config::Config;
pub use consensus::BeaconConsensus;
pub use reth_interfaces::consensus::Error;

View File

@ -1,9 +1,8 @@
//! ALl functions for verification of block
use crate::{config, Config};
use reth_interfaces::{consensus::Error, Result as RethResult};
use reth_primitives::{
BlockNumber, Header, SealedBlock, SealedHeader, Transaction, TransactionSignedEcRecovered,
TxEip1559, TxEip2930, TxLegacy, EMPTY_OMMER_ROOT, U256,
BlockNumber, ChainSpec, Hardfork, Header, SealedBlock, SealedHeader, Transaction,
TransactionSignedEcRecovered, TxEip1559, TxEip2930, TxLegacy, EMPTY_OMMER_ROOT, U256,
};
use reth_provider::{AccountProvider, HeaderProvider};
use std::{
@ -11,10 +10,12 @@ use std::{
time::SystemTime,
};
use crate::constants;
/// Validate header standalone
pub fn validate_header_standalone(
header: &SealedHeader,
config: &config::Config,
chain_spec: &ChainSpec,
) -> Result<(), Error> {
// Gas used needs to be less then gas limit. Gas used is going to be check after execution.
if header.gas_used > header.gas_limit {
@ -38,13 +39,14 @@ pub fn validate_header_standalone(
}
// Check if base fee is set.
if header.number >= config.london_block && header.base_fee_per_gas.is_none() {
if chain_spec.fork_active(Hardfork::London, header.number) && header.base_fee_per_gas.is_none()
{
return Err(Error::BaseFeeMissing)
}
// EIP-3675: Upgrade consensus to Proof-of-Stake:
// https://eips.ethereum.org/EIPS/eip-3675#replacing-difficulty-with-0
if header.number >= config.paris_block {
if Some(header.number) >= chain_spec.paris_status().block_number() {
if header.difficulty != U256::ZERO {
return Err(Error::TheMergeDifficultyIsNotZero)
}
@ -69,21 +71,23 @@ pub fn validate_header_standalone(
/// The only parameter from the header that affects the transaction is `base_fee`.
pub fn validate_transaction_regarding_header(
transaction: &Transaction,
config: &Config,
chain_spec: &ChainSpec,
at_block_number: BlockNumber,
base_fee: Option<u64>,
) -> Result<(), Error> {
let chain_id = match transaction {
Transaction::Legacy(TxLegacy { chain_id, .. }) => {
// EIP-155: Simple replay attack protection: https://eips.ethereum.org/EIPS/eip-155
if config.eip_155_block <= at_block_number && chain_id.is_some() {
if chain_spec.fork_active(Hardfork::SpuriousDragon, at_block_number) &&
chain_id.is_some()
{
return Err(Error::TransactionOldLegacyChainId)
}
*chain_id
}
Transaction::Eip2930(TxEip2930 { chain_id, .. }) => {
// EIP-2930: Optional access lists: https://eips.ethereum.org/EIPS/eip-2930 (New transaction type)
if config.berlin_block > at_block_number {
if !chain_spec.fork_active(Hardfork::Berlin, at_block_number) {
return Err(Error::TransactionEip2930Disabled)
}
Some(*chain_id)
@ -95,7 +99,7 @@ pub fn validate_transaction_regarding_header(
..
}) => {
// EIP-1559: Fee market change for ETH 1.0 chain https://eips.ethereum.org/EIPS/eip-1559
if config.berlin_block > at_block_number {
if !chain_spec.fork_active(Hardfork::Berlin, at_block_number) {
return Err(Error::TransactionEip1559Disabled)
}
@ -109,7 +113,7 @@ pub fn validate_transaction_regarding_header(
}
};
if let Some(chain_id) = chain_id {
if chain_id != config.chain_id {
if chain_id != chain_spec.chain().id() {
return Err(Error::TransactionChainId)
}
}
@ -133,14 +137,14 @@ pub fn validate_all_transaction_regarding_block_and_nonces<
transactions: impl Iterator<Item = &'a TransactionSignedEcRecovered>,
header: &Header,
provider: Provider,
config: &Config,
chain_spec: &ChainSpec,
) -> RethResult<()> {
let mut account_nonces = HashMap::new();
for transaction in transactions {
validate_transaction_regarding_header(
transaction,
config,
chain_spec,
header.number,
header.base_fee_per_gas,
)?;
@ -208,7 +212,7 @@ pub fn validate_block_standalone(block: &SealedBlock) -> Result<(), Error> {
/// Calculate base fee for next block. EIP-1559 spec
pub fn calculate_next_block_base_fee(gas_used: u64, gas_limit: u64, base_fee: u64) -> u64 {
let gas_target = gas_limit / config::EIP1559_ELASTICITY_MULTIPLIER;
let gas_target = gas_limit / constants::EIP1559_ELASTICITY_MULTIPLIER;
if gas_used == gas_target {
return base_fee
@ -219,14 +223,14 @@ pub fn calculate_next_block_base_fee(gas_used: u64, gas_limit: u64, base_fee: u6
1,
base_fee as u128 * gas_used_delta as u128 /
gas_target as u128 /
config::EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128,
constants::EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128,
);
base_fee + (base_fee_delta as u64)
} else {
let gas_used_delta = gas_target - gas_used;
let base_fee_per_gas_delta = base_fee as u128 * gas_used_delta as u128 /
gas_target as u128 /
config::EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128;
constants::EIP1559_BASE_FEE_MAX_CHANGE_DENOMINATOR as u128;
base_fee.saturating_sub(base_fee_per_gas_delta as u64)
}
@ -236,7 +240,7 @@ pub fn calculate_next_block_base_fee(gas_used: u64, gas_limit: u64, base_fee: u6
pub fn validate_header_regarding_parent(
parent: &SealedHeader,
child: &SealedHeader,
config: &config::Config,
chain_spec: &ChainSpec,
) -> Result<(), Error> {
// Parent number is consistent.
if parent.number + 1 != child.number {
@ -255,7 +259,7 @@ pub fn validate_header_regarding_parent(
}
// difficulty check is done by consensus.
if config.paris_block > child.number {
if chain_spec.paris_status().block_number() > Some(child.number) {
// TODO how this needs to be checked? As ice age did increment it by some formula
}
@ -263,8 +267,8 @@ pub fn validate_header_regarding_parent(
// By consensus, gas_limit is multiplied by elasticity (*2) on
// on exact block that hardfork happens.
if config.london_block == child.number {
parent_gas_limit = parent.gas_limit * config::EIP1559_ELASTICITY_MULTIPLIER;
if chain_spec.fork_block(Hardfork::London) == Some(child.number) {
parent_gas_limit = parent.gas_limit * constants::EIP1559_ELASTICITY_MULTIPLIER;
}
// Check gas limit, max diff between child/parent gas_limit should be max_diff=parent_gas/1024
@ -283,11 +287,11 @@ pub fn validate_header_regarding_parent(
}
// EIP-1559 check base fee
if child.number >= config.london_block {
if chain_spec.fork_active(Hardfork::London, child.number) {
let base_fee = child.base_fee_per_gas.ok_or(Error::BaseFeeMissing)?;
let expected_base_fee = if config.london_block == child.number {
config::EIP1559_INITIAL_BASE_FEE
let expected_base_fee = if chain_spec.fork_block(Hardfork::London) == Some(child.number) {
constants::EIP1559_INITIAL_BASE_FEE
} else {
// This BaseFeeMissing will not happen as previous blocks are checked to have them.
calculate_next_block_base_fee(
@ -335,12 +339,12 @@ pub fn validate_block_regarding_chain<PROV: HeaderProvider>(
pub fn full_validation<Provider: HeaderProvider + AccountProvider>(
block: &SealedBlock,
provider: Provider,
config: &Config,
chain_spec: &ChainSpec,
) -> RethResult<()> {
validate_header_standalone(&block.header, config)?;
validate_header_standalone(&block.header, chain_spec)?;
validate_block_standalone(block)?;
let parent = validate_block_regarding_chain(block, &provider)?;
validate_header_regarding_parent(&parent, &block.header, config)?;
validate_header_regarding_parent(&parent, &block.header, chain_spec)?;
// NOTE: depending on the need of the stages, recovery could be done in different place.
let transactions = block
@ -353,7 +357,7 @@ pub fn full_validation<Provider: HeaderProvider + AccountProvider>(
transactions.iter(),
&block.header,
provider,
config,
chain_spec,
)?;
Ok(())
}
@ -363,7 +367,7 @@ mod tests {
use reth_interfaces::Result;
use reth_primitives::{
hex_literal::hex, Account, Address, BlockHash, Bytes, Header, Signature, TransactionKind,
TransactionSigned,
TransactionSigned, MAINNET,
};
use super::*;
@ -495,19 +499,17 @@ mod tests {
fn sanity_check() {
let (block, parent) = mock_block();
let provider = Provider::new(Some(parent));
let config = Config::default();
assert_eq!(full_validation(&block, provider, &config), Ok(()), "Validation should pass");
assert_eq!(full_validation(&block, provider, &MAINNET), Ok(()), "Validation should pass");
}
#[test]
fn validate_known_block() {
let (block, _) = mock_block();
let provider = Provider::new_known();
let config = Config::default();
assert_eq!(
full_validation(&block, provider, &config),
full_validation(&block, provider, &MAINNET),
Err(Error::BlockKnown { hash: block.hash(), number: block.number }.into()),
"Should fail with error"
);
@ -519,14 +521,13 @@ mod tests {
let tx1 = mock_tx(0);
let tx2 = mock_tx(1);
let provider = Provider::new_known();
let config = Config::default();
let txs = vec![tx1, tx2];
validate_all_transaction_regarding_block_and_nonces(
txs.iter(),
&block.header,
provider,
&config,
&MAINNET,
)
.expect("To Pass");
}
@ -536,7 +537,6 @@ mod tests {
let (block, _) = mock_block();
let tx1 = mock_tx(1);
let provider = Provider::new_known();
let config = Config::default();
let txs = vec![tx1];
assert_eq!(
@ -544,7 +544,7 @@ mod tests {
txs.iter(),
&block.header,
provider,
&config,
&MAINNET,
),
Err(Error::TransactionNonceNotConsistent.into())
)
@ -556,7 +556,6 @@ mod tests {
let tx1 = mock_tx(0);
let tx2 = mock_tx(3);
let provider = Provider::new_known();
let config = Config::default();
let txs = vec![tx1, tx2];
assert_eq!(
@ -564,7 +563,7 @@ mod tests {
txs.iter(),
&block.header,
provider,
&config,
&MAINNET,
),
Err(Error::TransactionNonceNotConsistent.into())
);