diff --git a/crates/primitives-traits/src/block.rs b/crates/primitives-traits/src/block.rs deleted file mode 100644 index 02f581801..000000000 --- a/crates/primitives-traits/src/block.rs +++ /dev/null @@ -1,99 +0,0 @@ -//! Block abstraction. - -pub mod body; - -use alloc::fmt; -use core::ops; - -use alloy_consensus::BlockHeader; -use alloy_primitives::{Address, Sealable, B256}; - -use crate::{traits::BlockBody, BlockWithSenders, SealedBlock, SealedHeader}; - -/// Abstraction of block data type. -pub trait Block: - fmt::Debug - + Clone - + PartialEq - + Eq - + Default - + serde::Serialize - + for<'a> serde::Deserialize<'a> - + From<(Self::Header, Self::Body)> - + Into<(Self::Header, Self::Body)> -{ - /// Header part of the block. - type Header: BlockHeader + Sealable; - - /// The block's body contains the transactions in the block. - type Body: BlockBody; - - /// A block and block hash. - type SealedBlock; - - /// A block and addresses of senders of transactions in it. - type BlockWithSenders; - - /// Returns reference to [`BlockHeader`] type. - fn header(&self) -> &Self::Header; - - /// Returns reference to [`BlockBody`] type. - fn body(&self) -> &Self::Body; - - /// Calculate the header hash and seal the block so that it can't be changed. - // todo: can be default impl if sealed block type is made generic over header and body and - // migrated to alloy - fn seal_slow(self) -> Self::SealedBlock; - - /// Seal the block with a known hash. - /// - /// WARNING: This method does not perform validation whether the hash is correct. - // todo: can be default impl if sealed block type is made generic over header and body and - // migrated to alloy - fn seal(self, hash: B256) -> Self::SealedBlock; - - /// Expensive operation that recovers transaction signer. See - /// [`SealedBlockWithSenders`](reth_primitives::SealedBlockWithSenders). - fn senders(&self) -> Option> { - self.body().recover_signers() - } - - /// Transform into a [`BlockWithSenders`]. - /// - /// # Panics - /// - /// If the number of senders does not match the number of transactions in the block - /// and the signer recovery for one of the transactions fails. - /// - /// Note: this is expected to be called with blocks read from disk. - #[track_caller] - fn with_senders_unchecked(self, senders: Vec
) -> Self::BlockWithSenders { - self.try_with_senders_unchecked(senders).expect("stored block is valid") - } - - /// Transform into a [`BlockWithSenders`] using the given senders. - /// - /// If the number of senders does not match the number of transactions in the block, this falls - /// back to manually recovery, but _without ensuring that the signature has a low `s` value_. - /// See also [`TransactionSigned::recover_signer_unchecked`] - /// - /// Returns an error if a signature is invalid. - // todo: can be default impl if block with senders type is made generic over block and migrated - // to alloy - #[track_caller] - fn try_with_senders_unchecked( - self, - senders: Vec
, - ) -> Result; - - /// **Expensive**. Transform into a [`BlockWithSenders`] by recovering senders in the contained - /// transactions. - /// - /// Returns `None` if a transaction is invalid. - // todo: can be default impl if sealed block type is made generic over header and body and - // migrated to alloy - fn with_recovered_senders(self) -> Option; - - /// Calculates a heuristic for the in-memory size of the [`Block`]. - fn size(&self) -> usize; -} diff --git a/crates/primitives-traits/src/block/body.rs b/crates/primitives-traits/src/block/body.rs index 03246c68b..85eeda166 100644 --- a/crates/primitives-traits/src/block/body.rs +++ b/crates/primitives-traits/src/block/body.rs @@ -1,11 +1,10 @@ //! Block body abstraction. -use alloc::fmt; -use core::ops; +use alloc::{fmt, vec::Vec}; -use alloy_consensus::{BlockHeader,Request, Transaction, TxType}; +use alloy_consensus::{BlockHeader, Request, Transaction, TxType}; +use alloy_eips::eip4895::Withdrawal; use alloy_primitives::{Address, B256}; -use alloy_eips::eip1559::Withdrawal; use crate::Block; @@ -37,7 +36,7 @@ pub trait BlockBody: /// Returns reference to transactions in block. fn transactions(&self) -> &[Self::SignedTransaction]; - /// Returns [`Withdrawals`] in the block, if any. + /// Returns `Withdrawals` in the block, if any. // todo: branch out into extension trait fn withdrawals(&self) -> Option<&Self::Withdrawals>; @@ -60,13 +59,13 @@ pub trait BlockBody: /// Calculate the withdrawals root for the block body, if withdrawals exist. If there are no /// withdrawals, this will return `None`. - // todo: can be default impl if `calculate_withdrawals_root` made into a method on + // todo: can be default impl if `calculate_withdrawals_root` made into a method on // `Withdrawals` and `Withdrawals` moved to alloy fn calculate_withdrawals_root(&self) -> Option; /// Calculate the requests root for the block body, if requests exist. If there are no /// requests, this will return `None`. - // todo: can be default impl if `calculate_requests_root` made into a method on + // todo: can be default impl if `calculate_requests_root` made into a method on // `Requests` and `Requests` moved to alloy fn calculate_requests_root(&self) -> Option; @@ -75,17 +74,17 @@ pub trait BlockBody: /// Returns whether or not the block body contains any blob transactions. fn has_blob_transactions(&self) -> bool { - self.transactions().iter().any(|tx| tx.ty() as u8 == TxType::Eip4844 as u8) + self.transactions().iter().any(|tx| tx.ty() == TxType::Eip4844 as u8) } /// Returns whether or not the block body contains any EIP-7702 transactions. fn has_eip7702_transactions(&self) -> bool { - self.transactions().iter().any(|tx| tx.ty() as u8 == TxType::Eip7702 as u8) + self.transactions().iter().any(|tx| tx.ty() == TxType::Eip7702 as u8) } /// Returns an iterator over all blob transactions of the block fn blob_transactions_iter(&self) -> impl Iterator + '_ { - self.transactions().iter().filter(|tx| tx.ty() as u8 == TxType::Eip4844 as u8) + self.transactions().iter().filter(|tx| tx.ty() == TxType::Eip4844 as u8) } /// Returns only the blob transactions, if any, from the block body. @@ -104,56 +103,3 @@ pub trait BlockBody: /// Calculates a heuristic for the in-memory size of the [`BlockBody`]. fn size(&self) -> usize; } - -impl BlockBody for T -where - T: ops::Deref - + Clone - + fmt::Debug - + PartialEq - + Eq - + Default - + serde::Serialize - + for<'de> serde::Deserialize<'de> - + alloy_rlp::Encodable - + alloy_rlp::Decodable, -{ - type Header = ::Header; - type SignedTransaction = ::SignedTransaction; - - fn transactions(&self) -> &Vec { - self.deref().transactions() - } - - fn withdrawals(&self) -> Option<&Withdrawals> { - self.deref().withdrawals() - } - - fn ommers(&self) -> &Vec { - self.deref().ommers() - } - - fn requests(&self) -> Option<&Requests> { - self.deref().requests() - } - - fn calculate_tx_root(&self) -> B256 { - self.deref().calculate_tx_root() - } - - fn calculate_ommers_root(&self) -> B256 { - self.deref().calculate_ommers_root() - } - - fn recover_signers(&self) -> Option> { - self.deref().recover_signers() - } - - fn blob_versioned_hashes_iter(&self) -> impl Iterator + '_ { - self.deref().blob_versioned_hashes_iter() - } - - fn size(&self) -> usize { - self.deref().size() - } -} diff --git a/crates/primitives-traits/src/block/mod.rs b/crates/primitives-traits/src/block/mod.rs index 02f581801..395cf61df 100644 --- a/crates/primitives-traits/src/block/mod.rs +++ b/crates/primitives-traits/src/block/mod.rs @@ -2,15 +2,22 @@ pub mod body; -use alloc::fmt; -use core::ops; +use alloc::{fmt, vec::Vec}; use alloy_consensus::BlockHeader; use alloy_primitives::{Address, Sealable, B256}; -use crate::{traits::BlockBody, BlockWithSenders, SealedBlock, SealedHeader}; +use crate::BlockBody; + +/// Helper trait, unifies behaviour required of a block header. +pub trait Header: BlockHeader + Sealable {} + +impl Header for T where T: BlockHeader + Sealable {} /// Abstraction of block data type. +// todo: make sealable super-trait, depends on +// todo: make with senders extension trait, so block can be impl by block type already containing +// senders pub trait Block: fmt::Debug + Clone @@ -23,16 +30,16 @@ pub trait Block: + Into<(Self::Header, Self::Body)> { /// Header part of the block. - type Header: BlockHeader + Sealable; + type Header: Header; /// The block's body contains the transactions in the block. type Body: BlockBody; /// A block and block hash. - type SealedBlock; + type SealedBlock; /// A block and addresses of senders of transactions in it. - type BlockWithSenders; + type BlockWithSenders; /// Returns reference to [`BlockHeader`] type. fn header(&self) -> &Self::Header; @@ -41,24 +48,24 @@ pub trait Block: fn body(&self) -> &Self::Body; /// Calculate the header hash and seal the block so that it can't be changed. - // todo: can be default impl if sealed block type is made generic over header and body and + // todo: can be default impl if sealed block type is made generic over header and body and // migrated to alloy - fn seal_slow(self) -> Self::SealedBlock; + fn seal_slow(self) -> Self::SealedBlock; /// Seal the block with a known hash. /// /// WARNING: This method does not perform validation whether the hash is correct. - // todo: can be default impl if sealed block type is made generic over header and body and + // todo: can be default impl if sealed block type is made generic over header and body and // migrated to alloy - fn seal(self, hash: B256) -> Self::SealedBlock; + fn seal(self, hash: B256) -> Self::SealedBlock; /// Expensive operation that recovers transaction signer. See - /// [`SealedBlockWithSenders`](reth_primitives::SealedBlockWithSenders). + /// `SealedBlockWithSenders`. fn senders(&self) -> Option> { self.body().recover_signers() } - /// Transform into a [`BlockWithSenders`]. + /// Transform into a `BlockWithSenders`. /// /// # Panics /// @@ -67,32 +74,32 @@ pub trait Block: /// /// Note: this is expected to be called with blocks read from disk. #[track_caller] - fn with_senders_unchecked(self, senders: Vec
) -> Self::BlockWithSenders { + fn with_senders_unchecked(self, senders: Vec
) -> Self::BlockWithSenders { self.try_with_senders_unchecked(senders).expect("stored block is valid") } - /// Transform into a [`BlockWithSenders`] using the given senders. + /// Transform into a `BlockWithSenders` using the given senders. /// /// If the number of senders does not match the number of transactions in the block, this falls /// back to manually recovery, but _without ensuring that the signature has a low `s` value_. - /// See also [`TransactionSigned::recover_signer_unchecked`] + /// See also `SignedTransaction::recover_signer_unchecked`. /// /// Returns an error if a signature is invalid. - // todo: can be default impl if block with senders type is made generic over block and migrated + // todo: can be default impl if block with senders type is made generic over block and migrated // to alloy #[track_caller] fn try_with_senders_unchecked( self, senders: Vec
, - ) -> Result; + ) -> Result, Self>; - /// **Expensive**. Transform into a [`BlockWithSenders`] by recovering senders in the contained + /// **Expensive**. Transform into a `BlockWithSenders` by recovering senders in the contained /// transactions. /// /// Returns `None` if a transaction is invalid. - // todo: can be default impl if sealed block type is made generic over header and body and + // todo: can be default impl if sealed block type is made generic over header and body and // migrated to alloy - fn with_recovered_senders(self) -> Option; + fn with_recovered_senders(self) -> Option>; /// Calculates a heuristic for the in-memory size of the [`Block`]. fn size(&self) -> usize; diff --git a/crates/primitives-traits/src/lib.rs b/crates/primitives-traits/src/lib.rs index dd68607f5..8c54bd68c 100644 --- a/crates/primitives-traits/src/lib.rs +++ b/crates/primitives-traits/src/lib.rs @@ -32,6 +32,9 @@ pub use integer_list::{IntegerList, IntegerListError}; pub mod request; pub use request::{Request, Requests}; +pub mod block; +pub use block::{body::BlockBody, Block}; + mod withdrawal; pub use withdrawal::{Withdrawal, Withdrawals};