mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore: relax more consensus functions (#13236)
This commit is contained in:
@ -13,8 +13,8 @@ workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
# reth
|
# reth
|
||||||
reth-chainspec.workspace = true
|
reth-chainspec.workspace = true
|
||||||
reth-primitives.workspace = true
|
|
||||||
reth-consensus.workspace = true
|
reth-consensus.workspace = true
|
||||||
|
reth-primitives.workspace = true
|
||||||
|
|
||||||
# ethereum
|
# ethereum
|
||||||
alloy-primitives.workspace = true
|
alloy-primitives.workspace = true
|
||||||
@ -24,8 +24,8 @@ alloy-consensus.workspace = true
|
|||||||
alloy-eips.workspace = true
|
alloy-eips.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
alloy-consensus.workspace = true
|
||||||
reth-storage-api.workspace = true
|
reth-storage-api.workspace = true
|
||||||
rand.workspace = true
|
rand.workspace = true
|
||||||
mockall = "0.13"
|
mockall = "0.13"
|
||||||
|
|
||||||
alloy-consensus.workspace = true
|
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
//! Collection of methods for block validation.
|
//! Collection of methods for block validation.
|
||||||
|
|
||||||
use alloy_consensus::{constants::MAXIMUM_EXTRA_DATA_SIZE, BlockHeader};
|
use alloy_consensus::{constants::MAXIMUM_EXTRA_DATA_SIZE, BlockHeader, EMPTY_OMMER_ROOT_HASH};
|
||||||
use alloy_eips::{
|
use alloy_eips::{
|
||||||
calc_next_block_base_fee,
|
calc_next_block_base_fee,
|
||||||
eip4844::{DATA_GAS_PER_BLOB, MAX_DATA_GAS_PER_BLOCK},
|
eip4844::{DATA_GAS_PER_BLOB, MAX_DATA_GAS_PER_BLOCK},
|
||||||
};
|
};
|
||||||
use reth_chainspec::{EthChainSpec, EthereumHardforks};
|
use reth_chainspec::{EthChainSpec, EthereumHardfork, EthereumHardforks};
|
||||||
use reth_consensus::ConsensusError;
|
use reth_consensus::ConsensusError;
|
||||||
use reth_primitives::{BlockBody, EthereumHardfork, GotExpected, SealedBlock, SealedHeader};
|
use reth_primitives::SealedBlock;
|
||||||
use reth_primitives_traits::BlockBody as _;
|
use reth_primitives_traits::{BlockBody, GotExpected, SealedHeader};
|
||||||
use revm_primitives::calc_excess_blob_gas;
|
use revm_primitives::calc_excess_blob_gas;
|
||||||
|
|
||||||
/// Gas used needs to be less than gas limit. Gas used is going to be checked after execution.
|
/// Gas used needs to be less than gas limit. Gas used is going to be checked after execution.
|
||||||
@ -43,11 +43,11 @@ pub fn validate_header_base_fee<H: BlockHeader, ChainSpec: EthereumHardforks>(
|
|||||||
///
|
///
|
||||||
/// [EIP-4895]: https://eips.ethereum.org/EIPS/eip-4895
|
/// [EIP-4895]: https://eips.ethereum.org/EIPS/eip-4895
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn validate_shanghai_withdrawals<H: BlockHeader, B: reth_primitives_traits::BlockBody>(
|
pub fn validate_shanghai_withdrawals<H: BlockHeader, B: BlockBody>(
|
||||||
block: &SealedBlock<H, B>,
|
block: &SealedBlock<H, B>,
|
||||||
) -> Result<(), ConsensusError> {
|
) -> Result<(), ConsensusError> {
|
||||||
let withdrawals = block.body.withdrawals().ok_or(ConsensusError::BodyWithdrawalsMissing)?;
|
let withdrawals = block.body.withdrawals().ok_or(ConsensusError::BodyWithdrawalsMissing)?;
|
||||||
let withdrawals_root = reth_primitives::proofs::calculate_withdrawals_root(withdrawals);
|
let withdrawals_root = alloy_consensus::proofs::calculate_withdrawals_root(withdrawals);
|
||||||
let header_withdrawals_root =
|
let header_withdrawals_root =
|
||||||
block.withdrawals_root().ok_or(ConsensusError::WithdrawalsRootMissing)?;
|
block.withdrawals_root().ok_or(ConsensusError::WithdrawalsRootMissing)?;
|
||||||
if withdrawals_root != *header_withdrawals_root {
|
if withdrawals_root != *header_withdrawals_root {
|
||||||
@ -64,7 +64,7 @@ pub fn validate_shanghai_withdrawals<H: BlockHeader, B: reth_primitives_traits::
|
|||||||
///
|
///
|
||||||
/// [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844
|
/// [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn validate_cancun_gas<H: BlockHeader, B: reth_primitives_traits::BlockBody>(
|
pub fn validate_cancun_gas<H: BlockHeader, B: BlockBody>(
|
||||||
block: &SealedBlock<H, B>,
|
block: &SealedBlock<H, B>,
|
||||||
) -> Result<(), ConsensusError> {
|
) -> Result<(), ConsensusError> {
|
||||||
// Check that the blob gas used in the header matches the sum of the blob gas used by each
|
// Check that the blob gas used in the header matches the sum of the blob gas used by each
|
||||||
@ -87,28 +87,31 @@ pub fn validate_cancun_gas<H: BlockHeader, B: reth_primitives_traits::BlockBody>
|
|||||||
/// - ommer hash
|
/// - ommer hash
|
||||||
/// - transaction root
|
/// - transaction root
|
||||||
/// - withdrawals root
|
/// - withdrawals root
|
||||||
pub fn validate_body_against_header(
|
pub fn validate_body_against_header<B, H>(body: &B, header: &H) -> Result<(), ConsensusError>
|
||||||
body: &BlockBody,
|
where
|
||||||
header: &SealedHeader,
|
B: BlockBody,
|
||||||
) -> Result<(), ConsensusError> {
|
H: BlockHeader,
|
||||||
|
{
|
||||||
let ommers_hash = body.calculate_ommers_root();
|
let ommers_hash = body.calculate_ommers_root();
|
||||||
if header.ommers_hash != ommers_hash {
|
if Some(header.ommers_hash()) != ommers_hash {
|
||||||
return Err(ConsensusError::BodyOmmersHashDiff(
|
return Err(ConsensusError::BodyOmmersHashDiff(
|
||||||
GotExpected { got: ommers_hash, expected: header.ommers_hash }.into(),
|
GotExpected {
|
||||||
|
got: ommers_hash.unwrap_or(EMPTY_OMMER_ROOT_HASH),
|
||||||
|
expected: header.ommers_hash(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
let tx_root = body.calculate_tx_root();
|
let tx_root = body.calculate_tx_root();
|
||||||
if header.transactions_root != tx_root {
|
if header.transactions_root() != tx_root {
|
||||||
return Err(ConsensusError::BodyTransactionRootDiff(
|
return Err(ConsensusError::BodyTransactionRootDiff(
|
||||||
GotExpected { got: tx_root, expected: header.transactions_root }.into(),
|
GotExpected { got: tx_root, expected: header.transactions_root() }.into(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
match (header.withdrawals_root, &body.withdrawals) {
|
match (header.withdrawals_root(), body.calculate_withdrawals_root()) {
|
||||||
(Some(header_withdrawals_root), Some(withdrawals)) => {
|
(Some(header_withdrawals_root), Some(withdrawals_root)) => {
|
||||||
let withdrawals = withdrawals.as_slice();
|
|
||||||
let withdrawals_root = reth_primitives::proofs::calculate_withdrawals_root(withdrawals);
|
|
||||||
if withdrawals_root != header_withdrawals_root {
|
if withdrawals_root != header_withdrawals_root {
|
||||||
return Err(ConsensusError::BodyWithdrawalsRootDiff(
|
return Err(ConsensusError::BodyWithdrawalsRootDiff(
|
||||||
GotExpected { got: withdrawals_root, expected: header_withdrawals_root }.into(),
|
GotExpected { got: withdrawals_root, expected: header_withdrawals_root }.into(),
|
||||||
@ -130,15 +133,24 @@ pub fn validate_body_against_header(
|
|||||||
/// - Compares the transactions root in the block header to the block body
|
/// - Compares the transactions root in the block header to the block body
|
||||||
/// - Pre-execution transaction validation
|
/// - Pre-execution transaction validation
|
||||||
/// - (Optionally) Compares the receipts root in the block header to the block body
|
/// - (Optionally) Compares the receipts root in the block header to the block body
|
||||||
pub fn validate_block_pre_execution<ChainSpec: EthereumHardforks>(
|
pub fn validate_block_pre_execution<H, B, ChainSpec>(
|
||||||
block: &SealedBlock,
|
block: &SealedBlock<H, B>,
|
||||||
chain_spec: &ChainSpec,
|
chain_spec: &ChainSpec,
|
||||||
) -> Result<(), ConsensusError> {
|
) -> Result<(), ConsensusError>
|
||||||
|
where
|
||||||
|
H: BlockHeader,
|
||||||
|
B: BlockBody,
|
||||||
|
ChainSpec: EthereumHardforks,
|
||||||
|
{
|
||||||
// Check ommers hash
|
// Check ommers hash
|
||||||
let ommers_hash = block.body.calculate_ommers_root();
|
let ommers_hash = block.body.calculate_ommers_root();
|
||||||
if block.header.ommers_hash != ommers_hash {
|
if Some(block.header.ommers_hash()) != ommers_hash {
|
||||||
return Err(ConsensusError::BodyOmmersHashDiff(
|
return Err(ConsensusError::BodyOmmersHashDiff(
|
||||||
GotExpected { got: ommers_hash, expected: block.header.ommers_hash }.into(),
|
GotExpected {
|
||||||
|
got: ommers_hash.unwrap_or(EMPTY_OMMER_ROOT_HASH),
|
||||||
|
expected: block.header.ommers_hash(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,11 +160,11 @@ pub fn validate_block_pre_execution<ChainSpec: EthereumHardforks>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EIP-4895: Beacon chain push withdrawals as operations
|
// EIP-4895: Beacon chain push withdrawals as operations
|
||||||
if chain_spec.is_shanghai_active_at_timestamp(block.timestamp) {
|
if chain_spec.is_shanghai_active_at_timestamp(block.timestamp()) {
|
||||||
validate_shanghai_withdrawals(block)?;
|
validate_shanghai_withdrawals(block)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if chain_spec.is_cancun_active_at_timestamp(block.timestamp) {
|
if chain_spec.is_cancun_active_at_timestamp(block.timestamp()) {
|
||||||
validate_cancun_gas(block)?;
|
validate_cancun_gas(block)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,12 +234,12 @@ pub fn validate_header_extradata<H: BlockHeader>(header: &H) -> Result<(), Conse
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn validate_against_parent_hash_number<H: BlockHeader>(
|
pub fn validate_against_parent_hash_number<H: BlockHeader>(
|
||||||
header: &H,
|
header: &H,
|
||||||
parent: &SealedHeader,
|
parent: &SealedHeader<H>,
|
||||||
) -> Result<(), ConsensusError> {
|
) -> Result<(), ConsensusError> {
|
||||||
// Parent number is consistent.
|
// Parent number is consistent.
|
||||||
if parent.number + 1 != header.number() {
|
if parent.number() + 1 != header.number() {
|
||||||
return Err(ConsensusError::ParentBlockNumberMismatch {
|
return Err(ConsensusError::ParentBlockNumberMismatch {
|
||||||
parent_block_number: parent.number,
|
parent_block_number: parent.number(),
|
||||||
block_number: header.number(),
|
block_number: header.number(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -121,7 +121,7 @@ impl<ChainSpec: Send + Sync + EthChainSpec + EthereumHardforks + Debug> Consensu
|
|||||||
body: &BlockBody,
|
body: &BlockBody,
|
||||||
header: &SealedHeader,
|
header: &SealedHeader,
|
||||||
) -> Result<(), ConsensusError> {
|
) -> Result<(), ConsensusError> {
|
||||||
validate_body_against_header(body, header)
|
validate_body_against_header(body, header.header())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), ConsensusError> {
|
fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), ConsensusError> {
|
||||||
|
|||||||
@ -65,7 +65,7 @@ impl Consensus for OpBeaconConsensus {
|
|||||||
body: &BlockBody,
|
body: &BlockBody,
|
||||||
header: &SealedHeader,
|
header: &SealedHeader,
|
||||||
) -> Result<(), ConsensusError> {
|
) -> Result<(), ConsensusError> {
|
||||||
validate_body_against_header(body, header)
|
validate_body_against_header(body, header.header())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), ConsensusError> {
|
fn validate_block_pre_execution(&self, block: &SealedBlock) -> Result<(), ConsensusError> {
|
||||||
|
|||||||
@ -296,6 +296,40 @@ impl SealedBlock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<H, B> SealedBlock<H, B>
|
||||||
|
where
|
||||||
|
H: alloy_consensus::BlockHeader,
|
||||||
|
B: reth_primitives_traits::BlockBody,
|
||||||
|
{
|
||||||
|
/// Ensures that the transaction root in the block header is valid.
|
||||||
|
///
|
||||||
|
/// The transaction root is the Keccak 256-bit hash of the root node of the trie structure
|
||||||
|
/// populated with each transaction in the transactions list portion of the block.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// Returns `Ok(())` if the calculated transaction root matches the one stored in the header,
|
||||||
|
/// indicating that the transactions in the block are correctly represented in the trie.
|
||||||
|
///
|
||||||
|
/// Returns `Err(error)` if the transaction root validation fails, providing a `GotExpected`
|
||||||
|
/// error containing the calculated and expected roots.
|
||||||
|
pub fn ensure_transaction_root_valid(&self) -> Result<(), GotExpected<B256>>
|
||||||
|
where
|
||||||
|
B::Transaction: Encodable2718,
|
||||||
|
{
|
||||||
|
let calculated_root = self.body.calculate_tx_root();
|
||||||
|
|
||||||
|
if self.header.transactions_root() != calculated_root {
|
||||||
|
return Err(GotExpected {
|
||||||
|
got: calculated_root,
|
||||||
|
expected: self.header.transactions_root(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<H, B> SealedBlock<H, B>
|
impl<H, B> SealedBlock<H, B>
|
||||||
where
|
where
|
||||||
H: reth_primitives_traits::BlockHeader,
|
H: reth_primitives_traits::BlockHeader,
|
||||||
@ -385,34 +419,6 @@ where
|
|||||||
Block::new(self.header.unseal(), self.body)
|
Block::new(self.header.unseal(), self.body)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensures that the transaction root in the block header is valid.
|
|
||||||
///
|
|
||||||
/// The transaction root is the Keccak 256-bit hash of the root node of the trie structure
|
|
||||||
/// populated with each transaction in the transactions list portion of the block.
|
|
||||||
///
|
|
||||||
/// # Returns
|
|
||||||
///
|
|
||||||
/// Returns `Ok(())` if the calculated transaction root matches the one stored in the header,
|
|
||||||
/// indicating that the transactions in the block are correctly represented in the trie.
|
|
||||||
///
|
|
||||||
/// Returns `Err(error)` if the transaction root validation fails, providing a `GotExpected`
|
|
||||||
/// error containing the calculated and expected roots.
|
|
||||||
pub fn ensure_transaction_root_valid(&self) -> Result<(), GotExpected<B256>>
|
|
||||||
where
|
|
||||||
B::Transaction: Encodable2718,
|
|
||||||
{
|
|
||||||
let calculated_root = self.body.calculate_tx_root();
|
|
||||||
|
|
||||||
if self.header.transactions_root() != calculated_root {
|
|
||||||
return Err(GotExpected {
|
|
||||||
got: calculated_root,
|
|
||||||
expected: self.header.transactions_root(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a vector of encoded 2718 transactions.
|
/// Returns a vector of encoded 2718 transactions.
|
||||||
///
|
///
|
||||||
/// This is also known as `raw transactions`.
|
/// This is also known as `raw transactions`.
|
||||||
|
|||||||
Reference in New Issue
Block a user