From 26c0bd82b0120a62d59a3e328b61203c47167c49 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sun, 22 Dec 2024 08:20:39 +0100 Subject: [PATCH 1/5] chore: use alloy block --- crates/primitives/src/block.rs | 577 +++++++++++++++++---------------- 1 file changed, 291 insertions(+), 286 deletions(-) diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 36d1b382a33c..f68bb734f8b5 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -13,151 +13,156 @@ pub use reth_primitives_traits::test_utils::{generate_valid_header, valid_header use reth_primitives_traits::{BlockBody as _, InMemorySize, SignedTransaction, Transaction}; use serde::{Deserialize, Serialize}; -/// Ethereum full block. -/// -/// Withdrawals can be optionally included at the end of the RLP encoded message. -#[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(rlp, 25))] -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Deref)] -pub struct Block { - /// Block header. - #[deref] - pub header: Header, - /// Block body. - pub body: BlockBody, -} - -impl Default for Block { - fn default() -> Self { - Self { header: Default::default(), body: Default::default() } - } -} - -impl reth_primitives_traits::Block for Block -where - T: SignedTransaction, -{ - type Header = Header; - type Body = BlockBody; - - fn new(header: Self::Header, body: Self::Body) -> Self { - Self { header, body } - } - - fn header(&self) -> &Self::Header { - &self.header - } - - fn body(&self) -> &Self::Body { - &self.body - } - - fn split(self) -> (Self::Header, Self::Body) { - (self.header, self.body) - } -} - -impl InMemorySize for Block { - /// Calculates a heuristic for the in-memory size of the [`Block`]. - #[inline] - fn size(&self) -> usize { - self.header.size() + self.body.size() - } -} - -/// We need to implement RLP traits manually because we currently don't have a way to flatten -/// [`BlockBody`] into [`Block`]. -mod block_rlp { - use super::*; - - #[derive(RlpDecodable)] - #[rlp(trailing)] - struct Helper { - header: H, - transactions: Vec, - ommers: Vec
, - withdrawals: Option, - } - - #[derive(RlpEncodable)] - #[rlp(trailing)] - struct HelperRef<'a, H, T = TransactionSigned> { - header: &'a H, - transactions: &'a Vec, - ommers: &'a Vec
, - withdrawals: Option<&'a Withdrawals>, - } - - impl<'a, T> From<&'a Block> for HelperRef<'a, Header, T> { - fn from(block: &'a Block) -> Self { - let Block { header, body: BlockBody { transactions, ommers, withdrawals } } = block; - Self { header, transactions, ommers, withdrawals: withdrawals.as_ref() } - } - } - - impl<'a> From<&'a SealedBlock> for HelperRef<'a, SealedHeader> { - fn from(block: &'a SealedBlock) -> Self { - let SealedBlock { header, body: BlockBody { transactions, ommers, withdrawals } } = - block; - Self { header, transactions, ommers, withdrawals: withdrawals.as_ref() } - } - } - - impl Decodable for Block { - fn decode(b: &mut &[u8]) -> alloy_rlp::Result { - let Helper { header, transactions, ommers, withdrawals } = Helper::decode(b)?; - Ok(Self { header, body: BlockBody { transactions, ommers, withdrawals } }) - } - } - - impl Decodable for SealedBlock { - fn decode(b: &mut &[u8]) -> alloy_rlp::Result { - let Helper { header, transactions, ommers, withdrawals } = Helper::decode(b)?; - Ok(Self { header, body: BlockBody { transactions, ommers, withdrawals } }) - } - } - - impl Encodable for Block { - fn encode(&self, out: &mut dyn bytes::BufMut) { - let helper: HelperRef<'_, _, _> = self.into(); - helper.encode(out) - } - - fn length(&self) -> usize { - let helper: HelperRef<'_, _, _> = self.into(); - helper.length() - } - } - - impl Encodable for SealedBlock { - fn encode(&self, out: &mut dyn bytes::BufMut) { - let helper: HelperRef<'_, _, _> = self.into(); - helper.encode(out) - } - - fn length(&self) -> usize { - let helper: HelperRef<'_, _, _> = self.into(); - helper.length() - } - } -} - -#[cfg(any(test, feature = "arbitrary"))] -impl<'a> arbitrary::Arbitrary<'a> for Block { - fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { - // first generate up to 100 txs - let transactions = (0..100) - .map(|_| TransactionSigned::arbitrary(u)) - .collect::>>()?; - - // then generate up to 2 ommers - let ommers = (0..2).map(|_| Header::arbitrary(u)).collect::>>()?; - - Ok(Self { - header: u.arbitrary()?, - body: BlockBody { transactions, ommers, withdrawals: u.arbitrary()? }, - }) - } -} +pub type Block = alloy_consensus::Block; + +pub type BlockBody = alloy_consensus::BlockBody; + + +// /// Ethereum full block. +// /// +// /// Withdrawals can be optionally included at the end of the RLP encoded message. +// #[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(rlp, 25))] +// #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Deref)] +// pub struct Block { +// /// Block header. +// #[deref] +// pub header: Header, +// /// Block body. +// pub body: BlockBody, +// } +// +// impl Default for Block { +// fn default() -> Self { +// Self { header: Default::default(), body: Default::default() } +// } +// } +// +// impl reth_primitives_traits::Block for Block +// where +// T: SignedTransaction, +// { +// type Header = Header; +// type Body = BlockBody; +// +// fn new(header: Self::Header, body: Self::Body) -> Self { +// Self { header, body } +// } +// +// fn header(&self) -> &Self::Header { +// &self.header +// } +// +// fn body(&self) -> &Self::Body { +// &self.body +// } +// +// fn split(self) -> (Self::Header, Self::Body) { +// (self.header, self.body) +// } +// } +// +// impl InMemorySize for Block { +// /// Calculates a heuristic for the in-memory size of the [`Block`]. +// #[inline] +// fn size(&self) -> usize { +// self.header.size() + self.body.size() +// } +// } + +// /// We need to implement RLP traits manually because we currently don't have a way to flatten +// /// [`BlockBody`] into [`Block`]. +// mod block_rlp { +// use super::*; +// +// #[derive(RlpDecodable)] +// #[rlp(trailing)] +// struct Helper { +// header: H, +// transactions: Vec, +// ommers: Vec
, +// withdrawals: Option, +// } +// +// #[derive(RlpEncodable)] +// #[rlp(trailing)] +// struct HelperRef<'a, H, T = TransactionSigned> { +// header: &'a H, +// transactions: &'a Vec, +// ommers: &'a Vec
, +// withdrawals: Option<&'a Withdrawals>, +// } +// +// impl<'a, T> From<&'a Block> for HelperRef<'a, Header, T> { +// fn from(block: &'a Block) -> Self { +// let Block { header, body: BlockBody { transactions, ommers, withdrawals } } = block; +// Self { header, transactions, ommers, withdrawals: withdrawals.as_ref() } +// } +// } +// +// impl<'a> From<&'a SealedBlock> for HelperRef<'a, SealedHeader> { +// fn from(block: &'a SealedBlock) -> Self { +// let SealedBlock { header, body: BlockBody { transactions, ommers, withdrawals } } = +// block; +// Self { header, transactions, ommers, withdrawals: withdrawals.as_ref() } +// } +// } +// +// impl Decodable for Block { +// fn decode(b: &mut &[u8]) -> alloy_rlp::Result { +// let Helper { header, transactions, ommers, withdrawals } = Helper::decode(b)?; +// Ok(Self { header, body: BlockBody { transactions, ommers, withdrawals } }) +// } +// } +// +// impl Decodable for SealedBlock { +// fn decode(b: &mut &[u8]) -> alloy_rlp::Result { +// let Helper { header, transactions, ommers, withdrawals } = Helper::decode(b)?; +// Ok(Self { header, body: BlockBody { transactions, ommers, withdrawals } }) +// } +// } +// +// impl Encodable for Block { +// fn encode(&self, out: &mut dyn bytes::BufMut) { +// let helper: HelperRef<'_, _, _> = self.into(); +// helper.encode(out) +// } +// +// fn length(&self) -> usize { +// let helper: HelperRef<'_, _, _> = self.into(); +// helper.length() +// } +// } +// +// impl Encodable for SealedBlock { +// fn encode(&self, out: &mut dyn bytes::BufMut) { +// let helper: HelperRef<'_, _, _> = self.into(); +// helper.encode(out) +// } +// +// fn length(&self) -> usize { +// let helper: HelperRef<'_, _, _> = self.into(); +// helper.length() +// } +// } +// } +// +// #[cfg(any(test, feature = "arbitrary"))] +// impl<'a> arbitrary::Arbitrary<'a> for Block { +// fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { +// // first generate up to 100 txs +// let transactions = (0..100) +// .map(|_| TransactionSigned::arbitrary(u)) +// .collect::>>()?; +// +// // then generate up to 2 ommers +// let ommers = (0..2).map(|_| Header::arbitrary(u)).collect::>>()?; +// +// Ok(Self { +// header: u.arbitrary()?, +// body: BlockBody { transactions, ommers, withdrawals: u.arbitrary()? }, +// }) +// } +// } /// Sealed block with senders recovered from transactions. #[derive(Debug, Clone, PartialEq, Eq, Default, Deref, DerefMut)] @@ -564,147 +569,147 @@ impl<'a> arbitrary::Arbitrary<'a> for SealedBlockWithSenders { } } -/// A response to `GetBlockBodies`, containing bodies if any bodies were found. -/// -/// Withdrawals can be optionally included at the end of the RLP encoded message. -#[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(rlp, 10))] -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, RlpEncodable, RlpDecodable)] -#[rlp(trailing)] -pub struct BlockBody { - /// Transactions in the block - pub transactions: Vec, - /// Uncle headers for the given block - pub ommers: Vec
, - /// Withdrawals in the block. - pub withdrawals: Option, -} - -impl Default for BlockBody { - fn default() -> Self { - Self { - transactions: Default::default(), - ommers: Default::default(), - withdrawals: Default::default(), - } - } -} - -impl BlockBody { - /// Create a [`Block`] from the body and its header. - pub const fn into_block(self, header: Header) -> Block { - Block { header, body: self } - } - - /// Returns an iterator over all blob versioned hashes from the block body. - #[inline] - pub fn blob_versioned_hashes_iter(&self) -> impl Iterator + '_ { - self.eip4844_transactions_iter() - .filter_map(|tx| tx.as_eip4844().map(|blob_tx| &blob_tx.blob_versioned_hashes)) - .flatten() - } -} - -impl BlockBody { - /// Calculate the ommers root for the block body. - pub fn calculate_ommers_root(&self) -> B256 { - crate::proofs::calculate_ommers_root(&self.ommers) - } - - /// Calculate the withdrawals root for the block body, if withdrawals exist. If there are no - /// withdrawals, this will return `None`. - pub fn calculate_withdrawals_root(&self) -> Option { - self.withdrawals.as_ref().map(|w| crate::proofs::calculate_withdrawals_root(w)) - } -} - -impl BlockBody { - /// Returns whether or not the block body contains any blob transactions. - #[inline] - pub fn has_eip4844_transactions(&self) -> bool { - self.transactions.iter().any(|tx| tx.is_eip4844()) - } - - /// Returns whether or not the block body contains any EIP-7702 transactions. - #[inline] - pub fn has_eip7702_transactions(&self) -> bool { - self.transactions.iter().any(|tx| tx.is_eip7702()) - } - - /// Returns an iterator over all blob transactions of the block - #[inline] - pub fn eip4844_transactions_iter(&self) -> impl Iterator + '_ { - self.transactions.iter().filter(|tx| tx.is_eip4844()) - } -} - -impl InMemorySize for BlockBody { - /// Calculates a heuristic for the in-memory size of the [`BlockBody`]. - #[inline] - fn size(&self) -> usize { - self.transactions.iter().map(T::size).sum::() + - self.transactions.capacity() * core::mem::size_of::() + - self.ommers.iter().map(Header::size).sum::() + - self.ommers.capacity() * core::mem::size_of::
() + - self.withdrawals - .as_ref() - .map_or(core::mem::size_of::>(), Withdrawals::total_size) - } -} - -impl reth_primitives_traits::BlockBody for BlockBody -where - T: SignedTransaction, -{ - type Transaction = T; - type OmmerHeader = Header; - - fn transactions(&self) -> &[Self::Transaction] { - &self.transactions - } - - fn into_transactions(self) -> Vec { - self.transactions - } - - fn withdrawals(&self) -> Option<&Withdrawals> { - self.withdrawals.as_ref() - } - - fn ommers(&self) -> Option<&[Self::OmmerHeader]> { - Some(&self.ommers) - } -} - -impl From for BlockBody { - fn from(block: Block) -> Self { - Self { - transactions: block.body.transactions, - ommers: block.body.ommers, - withdrawals: block.body.withdrawals, - } - } -} - -#[cfg(any(test, feature = "arbitrary"))] -impl<'a> arbitrary::Arbitrary<'a> for BlockBody { - fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { - // first generate up to 100 txs - let transactions = (0..100) - .map(|_| TransactionSigned::arbitrary(u)) - .collect::>>()?; - - // then generate up to 2 ommers - let ommers = (0..2) - .map(|_| { - let header = Header::arbitrary(u)?; - - Ok(header) - }) - .collect::>>()?; - - Ok(Self { transactions, ommers, withdrawals: u.arbitrary()? }) - } -} +// /// A response to `GetBlockBodies`, containing bodies if any bodies were found. +// /// +// /// Withdrawals can be optionally included at the end of the RLP encoded message. +// #[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(rlp, 10))] +// #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, RlpEncodable, RlpDecodable)] +// #[rlp(trailing)] +// pub struct BlockBody { +// /// Transactions in the block +// pub transactions: Vec, +// /// Uncle headers for the given block +// pub ommers: Vec
, +// /// Withdrawals in the block. +// pub withdrawals: Option, +// } +// +// impl Default for BlockBody { +// fn default() -> Self { +// Self { +// transactions: Default::default(), +// ommers: Default::default(), +// withdrawals: Default::default(), +// } +// } +// } +// +// impl BlockBody { +// /// Create a [`Block`] from the body and its header. +// pub const fn into_block(self, header: Header) -> Block { +// Block { header, body: self } +// } +// +// /// Returns an iterator over all blob versioned hashes from the block body. +// #[inline] +// pub fn blob_versioned_hashes_iter(&self) -> impl Iterator + '_ { +// self.eip4844_transactions_iter() +// .filter_map(|tx| tx.as_eip4844().map(|blob_tx| &blob_tx.blob_versioned_hashes)) +// .flatten() +// } +// } +// +// impl BlockBody { +// /// Calculate the ommers root for the block body. +// pub fn calculate_ommers_root(&self) -> B256 { +// crate::proofs::calculate_ommers_root(&self.ommers) +// } +// +// /// Calculate the withdrawals root for the block body, if withdrawals exist. If there are no +// /// withdrawals, this will return `None`. +// pub fn calculate_withdrawals_root(&self) -> Option { +// self.withdrawals.as_ref().map(|w| crate::proofs::calculate_withdrawals_root(w)) +// } +// } +// +// impl BlockBody { +// /// Returns whether or not the block body contains any blob transactions. +// #[inline] +// pub fn has_eip4844_transactions(&self) -> bool { +// self.transactions.iter().any(|tx| tx.is_eip4844()) +// } +// +// /// Returns whether or not the block body contains any EIP-7702 transactions. +// #[inline] +// pub fn has_eip7702_transactions(&self) -> bool { +// self.transactions.iter().any(|tx| tx.is_eip7702()) +// } +// +// /// Returns an iterator over all blob transactions of the block +// #[inline] +// pub fn eip4844_transactions_iter(&self) -> impl Iterator + '_ { +// self.transactions.iter().filter(|tx| tx.is_eip4844()) +// } +// } +// +// impl InMemorySize for BlockBody { +// /// Calculates a heuristic for the in-memory size of the [`BlockBody`]. +// #[inline] +// fn size(&self) -> usize { +// self.transactions.iter().map(T::size).sum::() + +// self.transactions.capacity() * core::mem::size_of::() + +// self.ommers.iter().map(Header::size).sum::() + +// self.ommers.capacity() * core::mem::size_of::
() + +// self.withdrawals +// .as_ref() +// .map_or(core::mem::size_of::>(), Withdrawals::total_size) +// } +// } +// +// impl reth_primitives_traits::BlockBody for BlockBody +// where +// T: SignedTransaction, +// { +// type Transaction = T; +// type OmmerHeader = Header; +// +// fn transactions(&self) -> &[Self::Transaction] { +// &self.transactions +// } +// +// fn into_transactions(self) -> Vec { +// self.transactions +// } +// +// fn withdrawals(&self) -> Option<&Withdrawals> { +// self.withdrawals.as_ref() +// } +// +// fn ommers(&self) -> Option<&[Self::OmmerHeader]> { +// Some(&self.ommers) +// } +// } +// +// impl From for BlockBody { +// fn from(block: Block) -> Self { +// Self { +// transactions: block.body.transactions, +// ommers: block.body.ommers, +// withdrawals: block.body.withdrawals, +// } +// } +// } +// +// #[cfg(any(test, feature = "arbitrary"))] +// impl<'a> arbitrary::Arbitrary<'a> for BlockBody { +// fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { +// // first generate up to 100 txs +// let transactions = (0..100) +// .map(|_| TransactionSigned::arbitrary(u)) +// .collect::>>()?; +// +// // then generate up to 2 ommers +// let ommers = (0..2) +// .map(|_| { +// let header = Header::arbitrary(u)?; +// +// Ok(header) +// }) +// .collect::>>()?; +// +// Ok(Self { transactions, ommers, withdrawals: u.arbitrary()? }) +// } +// } /// Bincode-compatible block type serde implementations. #[cfg(feature = "serde-bincode-compat")] From a13cc2d8096feb2d690f522879ee8a74e05ff093 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 30 Dec 2024 22:56:56 +0100 Subject: [PATCH 2/5] chore: add bincode compat --- .../src/serde_bincode_compat.rs | 82 ++++++++- crates/primitives/src/alloy_compat.rs | 172 +++++++++--------- crates/primitives/src/block.rs | 73 +------- 3 files changed, 171 insertions(+), 156 deletions(-) diff --git a/crates/primitives-traits/src/serde_bincode_compat.rs b/crates/primitives-traits/src/serde_bincode_compat.rs index a1f7d42569e8..4b77a126eaaa 100644 --- a/crates/primitives-traits/src/serde_bincode_compat.rs +++ b/crates/primitives-traits/src/serde_bincode_compat.rs @@ -1,7 +1,8 @@ use core::fmt::Debug; +use serde::{de::DeserializeOwned, Serialize}; pub use super::header::{serde_bincode_compat as header, serde_bincode_compat::*}; -use serde::{de::DeserializeOwned, Serialize}; +pub use block_bincode::BlockBody; /// Trait for types that can be serialized and deserialized using bincode. pub trait SerdeBincodeCompat: Sized + 'static { @@ -12,3 +13,82 @@ pub trait SerdeBincodeCompat: Sized + 'static { impl SerdeBincodeCompat for alloy_consensus::Header { type BincodeRepr<'a> = alloy_consensus::serde_bincode_compat::Header<'a>; } + +mod block_bincode { + use crate::serde_bincode_compat::SerdeBincodeCompat; + use alloc::{borrow::Cow, vec::Vec}; + use alloy_consensus::serde_bincode_compat::Header; + use alloy_eips::eip4895::Withdrawals; + use serde::{Deserialize, Deserializer, Serialize, Serializer}; + use serde_with::{DeserializeAs, SerializeAs}; + + /// Bincode-compatible [`alloy_consensus::BlockBody`] serde implementation. + /// + /// Intended to use with the [`serde_with::serde_as`] macro in the following way: + /// ```rust + /// use reth_primitives_traits::serde_bincode_compat; + /// use serde::{Deserialize, Serialize}; + /// use serde_with::serde_as; + /// + /// #[serde_as] + /// #[derive(Serialize, Deserialize)] + /// struct Data { + /// #[serde_as(as = "serde_bincode_compat::BlockBody")] + /// body: alloy_consensus::BlockBody, + /// } + /// ``` + #[derive(derive_more::Debug, Serialize, Deserialize)] + #[debug(bound())] + pub struct BlockBody<'a, T: SerdeBincodeCompat> { + transactions: Vec>, + ommers: Vec>, + withdrawals: Cow<'a, Option>, + } + + impl<'a, T: SerdeBincodeCompat> From<&'a alloy_consensus::BlockBody> for BlockBody<'a, T> { + fn from(value: &'a alloy_consensus::BlockBody) -> Self { + Self { + transactions: value.transactions.iter().map(Into::into).collect(), + ommers: value.ommers.iter().map(Into::into).collect(), + withdrawals: Cow::Borrowed(&value.withdrawals), + } + } + } + + impl<'a, T: SerdeBincodeCompat> From> for alloy_consensus::BlockBody { + fn from(value: BlockBody<'a, T>) -> Self { + Self { + transactions: value.transactions.into_iter().map(Into::into).collect(), + ommers: value.ommers.into_iter().map(Into::into).collect(), + withdrawals: value.withdrawals.into_owned(), + } + } + } + + impl SerializeAs> for BlockBody<'_, T> { + fn serialize_as( + source: &alloy_consensus::BlockBody, + serializer: S, + ) -> Result + where + S: Serializer, + { + BlockBody::from(source).serialize(serializer) + } + } + + impl<'de, T: SerdeBincodeCompat> DeserializeAs<'de, alloy_consensus::BlockBody> + for BlockBody<'de, T> + { + fn deserialize_as(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + BlockBody::deserialize(deserializer).map(Into::into) + } + } + + impl SerdeBincodeCompat for alloy_consensus::BlockBody { + type BincodeRepr<'a> = BlockBody<'a, T>; + } +} diff --git a/crates/primitives/src/alloy_compat.rs b/crates/primitives/src/alloy_compat.rs index a3338568ef61..c3b9d7e8a61f 100644 --- a/crates/primitives/src/alloy_compat.rs +++ b/crates/primitives/src/alloy_compat.rs @@ -7,92 +7,92 @@ use alloy_network::{AnyHeader, AnyRpcBlock, AnyRpcTransaction, AnyTxEnvelope}; use alloy_serde::WithOtherFields; use op_alloy_rpc_types as _; -impl TryFrom for Block { - type Error = alloy_rpc_types::ConversionError; - - fn try_from(block: AnyRpcBlock) -> Result { - use alloy_rpc_types::ConversionError; - - let block = block.inner; - - let transactions = { - let transactions: Result, ConversionError> = match block - .transactions - { - alloy_rpc_types::BlockTransactions::Full(transactions) => { - transactions.into_iter().map(|tx| tx.try_into()).collect() - } - alloy_rpc_types::BlockTransactions::Hashes(_) | - alloy_rpc_types::BlockTransactions::Uncle => { - // alloy deserializes empty blocks into `BlockTransactions::Hashes`, if the tx - // root is the empty root then we can just return an empty vec. - if block.header.transactions_root == EMPTY_TRANSACTIONS { - Ok(Vec::new()) - } else { - Err(ConversionError::Custom("missing transactions".to_string())) - } - } - }; - transactions? - }; - - let AnyHeader { - parent_hash, - ommers_hash, - beneficiary, - state_root, - transactions_root, - receipts_root, - logs_bloom, - difficulty, - number, - gas_limit, - gas_used, - timestamp, - extra_data, - mix_hash, - nonce, - base_fee_per_gas, - withdrawals_root, - blob_gas_used, - excess_blob_gas, - parent_beacon_block_root, - requests_hash, - } = block.header.inner; - - Ok(Self { - header: Header { - parent_hash, - ommers_hash, - beneficiary, - state_root, - transactions_root, - receipts_root, - logs_bloom, - difficulty, - number, - gas_limit, - gas_used, - timestamp, - extra_data, - mix_hash: mix_hash - .ok_or_else(|| ConversionError::Custom("missing mixHash".to_string()))?, - nonce: nonce.ok_or_else(|| ConversionError::Custom("missing nonce".to_string()))?, - base_fee_per_gas, - withdrawals_root, - blob_gas_used, - excess_blob_gas, - parent_beacon_block_root, - requests_hash, - }, - body: BlockBody { - transactions, - ommers: Default::default(), - withdrawals: block.withdrawals.map(|w| w.into_inner().into()), - }, - }) - } -} +// impl TryFrom for Block { +// type Error = alloy_rpc_types::ConversionError; +// +// fn try_from(block: AnyRpcBlock) -> Result { +// use alloy_rpc_types::ConversionError; +// +// let block = block.inner; +// +// let transactions = { +// let transactions: Result, ConversionError> = match block +// .transactions +// { +// alloy_rpc_types::BlockTransactions::Full(transactions) => { +// transactions.into_iter().map(|tx| tx.try_into()).collect() +// } +// alloy_rpc_types::BlockTransactions::Hashes(_) | +// alloy_rpc_types::BlockTransactions::Uncle => { +// // alloy deserializes empty blocks into `BlockTransactions::Hashes`, if the +// tx // root is the empty root then we can just return an empty vec. +// if block.header.transactions_root == EMPTY_TRANSACTIONS { +// Ok(Vec::new()) +// } else { +// Err(ConversionError::Custom("missing transactions".to_string())) +// } +// } +// }; +// transactions? +// }; +// +// let AnyHeader { +// parent_hash, +// ommers_hash, +// beneficiary, +// state_root, +// transactions_root, +// receipts_root, +// logs_bloom, +// difficulty, +// number, +// gas_limit, +// gas_used, +// timestamp, +// extra_data, +// mix_hash, +// nonce, +// base_fee_per_gas, +// withdrawals_root, +// blob_gas_used, +// excess_blob_gas, +// parent_beacon_block_root, +// requests_hash, +// } = block.header.inner; +// +// Ok(Self { +// header: Header { +// parent_hash, +// ommers_hash, +// beneficiary, +// state_root, +// transactions_root, +// receipts_root, +// logs_bloom, +// difficulty, +// number, +// gas_limit, +// gas_used, +// timestamp, +// extra_data, +// mix_hash: mix_hash +// .ok_or_else(|| ConversionError::Custom("missing mixHash".to_string()))?, +// nonce: nonce.ok_or_else(|| ConversionError::Custom("missing +// nonce".to_string()))?, base_fee_per_gas, +// withdrawals_root, +// blob_gas_used, +// excess_blob_gas, +// parent_beacon_block_root, +// requests_hash, +// }, +// body: BlockBody { +// transactions, +// ommers: Default::default(), +// withdrawals: block.withdrawals.map(|w| w.into_inner().into()), +// }, +// }) +// } +// } impl TryFrom for TransactionSigned { type Error = alloy_rpc_types::ConversionError; diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index d5e6ae3decf2..2be17fbd2afe 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -17,7 +17,6 @@ pub type Block = alloy_consensus::Block; pub type BlockBody = alloy_consensus::BlockBody; - // /// Ethereum full block. // /// // /// Withdrawals can be optionally included at the end of the RLP encoded message. @@ -155,7 +154,8 @@ pub type BlockBody = alloy_consensus::BlockBody; // .collect::>>()?; // // // then generate up to 2 ommers -// let ommers = (0..2).map(|_| Header::arbitrary(u)).collect::>>()?; +// let ommers = (0..2).map(|_| +// Header::arbitrary(u)).collect::>>()?; // // Ok(Self { // header: u.arbitrary()?, @@ -716,8 +716,6 @@ impl<'a> arbitrary::Arbitrary<'a> for SealedBlockWithSenders { #[cfg(feature = "serde-bincode-compat")] pub(super) mod serde_bincode_compat { use alloc::{borrow::Cow, vec::Vec}; - use alloy_consensus::serde_bincode_compat::Header; - use alloy_eips::eip4895::Withdrawals; use alloy_primitives::Address; use reth_primitives_traits::{ serde_bincode_compat::{SealedHeader, SerdeBincodeCompat}, @@ -726,70 +724,8 @@ pub(super) mod serde_bincode_compat { use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_with::{DeserializeAs, SerializeAs}; - /// Bincode-compatible [`super::BlockBody`] serde implementation. - /// - /// Intended to use with the [`serde_with::serde_as`] macro in the following way: - /// ```rust - /// use reth_primitives::{serde_bincode_compat, BlockBody}; - /// use serde::{Deserialize, Serialize}; - /// use serde_with::serde_as; - /// - /// #[serde_as] - /// #[derive(Serialize, Deserialize)] - /// struct Data { - /// #[serde_as(as = "serde_bincode_compat::BlockBody")] - /// body: BlockBody, - /// } - /// ``` - #[derive(derive_more::Debug, Serialize, Deserialize)] - #[debug(bound())] - pub struct BlockBody<'a, T: SerdeBincodeCompat = super::TransactionSigned> { - transactions: Vec>, - ommers: Vec>, - withdrawals: Cow<'a, Option>, - } - - impl<'a, T: SerdeBincodeCompat> From<&'a super::BlockBody> for BlockBody<'a, T> { - fn from(value: &'a super::BlockBody) -> Self { - Self { - transactions: value.transactions.iter().map(Into::into).collect(), - ommers: value.ommers.iter().map(Into::into).collect(), - withdrawals: Cow::Borrowed(&value.withdrawals), - } - } - } - - impl<'a, T: SerdeBincodeCompat> From> for super::BlockBody { - fn from(value: BlockBody<'a, T>) -> Self { - Self { - transactions: value.transactions.into_iter().map(Into::into).collect(), - ommers: value.ommers.into_iter().map(Into::into).collect(), - withdrawals: value.withdrawals.into_owned(), - } - } - } - - impl SerializeAs for BlockBody<'_> { - fn serialize_as(source: &super::BlockBody, serializer: S) -> Result - where - S: Serializer, - { - BlockBody::from(source).serialize(serializer) - } - } - - impl<'de> DeserializeAs<'de, super::BlockBody> for BlockBody<'de> { - fn deserialize_as(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - BlockBody::deserialize(deserializer).map(Into::into) - } - } - - impl SerdeBincodeCompat for super::BlockBody { - type BincodeRepr<'a> = BlockBody<'a, T>; - } + pub type BlockBody<'a, T = super::TransactionSigned> = + reth_primitives_traits::serde_bincode_compat::BlockBody<'a, T>; /// Bincode-compatible [`super::SealedBlock`] serde implementation. /// @@ -923,7 +859,6 @@ pub(super) mod serde_bincode_compat { #[cfg(test)] mod tests { use super::super::{serde_bincode_compat, BlockBody, SealedBlock, SealedBlockWithSenders}; - use arbitrary::Arbitrary; use rand::Rng; use reth_testing_utils::generators; From 9eff0210bfb00dfce46446c415867e9213f2f152 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 30 Dec 2024 23:00:29 +0100 Subject: [PATCH 3/5] update header access --- crates/optimism/consensus/src/validation.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/optimism/consensus/src/validation.rs b/crates/optimism/consensus/src/validation.rs index aa2edd229334..9335917ddf9d 100644 --- a/crates/optimism/consensus/src/validation.rs +++ b/crates/optimism/consensus/src/validation.rs @@ -25,7 +25,7 @@ pub fn validate_block_post_execution( block.header.logs_bloom, receipts, chain_spec, - block.timestamp, + block.header.timestamp, ) { tracing::debug!(%error, ?receipts, "receipts verification failed"); return Err(error) @@ -35,9 +35,9 @@ pub fn validate_block_post_execution( // Check if gas used matches the value set in header. let cumulative_gas_used = receipts.last().map(|receipt| receipt.cumulative_gas_used()).unwrap_or(0); - if block.gas_used != cumulative_gas_used { + if block.header.gas_used != cumulative_gas_used { return Err(ConsensusError::BlockGasUsed { - gas: GotExpected { got: cumulative_gas_used, expected: block.gas_used }, + gas: GotExpected { got: cumulative_gas_used, expected: block.header.gas_used }, gas_spent_by_tx: gas_spent_by_transactions(receipts), }) } From 95192572f1e8f6a0ad9cb2095ec4beec18425837 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 31 Dec 2024 08:13:24 +0100 Subject: [PATCH 4/5] make it compile --- bin/reth-bench/src/bench/new_payload_fcu.rs | 5 +- bin/reth-bench/src/bench/new_payload_only.rs | 5 +- crates/primitives/src/alloy_compat.rs | 113 ++---- crates/primitives/src/block.rs | 356 ++++-------------- crates/prune/prune/src/segments/mod.rs | 10 +- .../src/providers/blockchain_provider.rs | 2 +- 6 files changed, 97 insertions(+), 394 deletions(-) diff --git a/bin/reth-bench/src/bench/new_payload_fcu.rs b/bin/reth-bench/src/bench/new_payload_fcu.rs index c08cb3b2a295..baa940437e1d 100644 --- a/bin/reth-bench/src/bench/new_payload_fcu.rs +++ b/bin/reth-bench/src/bench/new_payload_fcu.rs @@ -18,7 +18,7 @@ use clap::Parser; use csv::Writer; use reth_cli_runner::CliContext; use reth_node_core::args::BenchmarkArgs; -use reth_primitives::{Block, BlockExt}; +use reth_primitives::SealedBlock; use reth_rpc_types_compat::engine::payload::block_to_payload; use std::time::Instant; use tracing::{debug, info}; @@ -46,8 +46,7 @@ impl Command { let block_res = block_provider.get_block_by_number(next_block.into(), true.into()).await; let block = block_res.unwrap().unwrap(); - let block_hash = block.header.hash; - let block = Block::try_from(block).unwrap().seal(block_hash); + let block: SealedBlock = block.try_into().unwrap(); let head_block_hash = block.hash(); let safe_block_hash = block_provider .get_block_by_number(block.number.saturating_sub(32).into(), false.into()); diff --git a/bin/reth-bench/src/bench/new_payload_only.rs b/bin/reth-bench/src/bench/new_payload_only.rs index 339ba0f63928..020164109c22 100644 --- a/bin/reth-bench/src/bench/new_payload_only.rs +++ b/bin/reth-bench/src/bench/new_payload_only.rs @@ -16,7 +16,7 @@ use clap::Parser; use csv::Writer; use reth_cli_runner::CliContext; use reth_node_core::args::BenchmarkArgs; -use reth_primitives::{Block, BlockExt}; +use reth_primitives::SealedBlock; use reth_rpc_types_compat::engine::payload::block_to_payload; use std::time::Instant; use tracing::{debug, info}; @@ -46,8 +46,7 @@ impl Command { let block_res = block_provider.get_block_by_number(next_block.into(), true.into()).await; let block = block_res.unwrap().unwrap(); - let block_hash = block.header.hash; - let block = Block::try_from(block).unwrap().seal(block_hash); + let block: SealedBlock = block.try_into().unwrap(); next_block += 1; sender.send(block).await.unwrap(); diff --git a/crates/primitives/src/alloy_compat.rs b/crates/primitives/src/alloy_compat.rs index c3b9d7e8a61f..2409c535cd3b 100644 --- a/crates/primitives/src/alloy_compat.rs +++ b/crates/primitives/src/alloy_compat.rs @@ -1,98 +1,31 @@ //! Common conversions from alloy types. -use crate::{Block, BlockBody, Transaction, TransactionSigned}; -use alloc::{string::ToString, vec::Vec}; -use alloy_consensus::{constants::EMPTY_TRANSACTIONS, Header, TxEnvelope}; -use alloy_network::{AnyHeader, AnyRpcBlock, AnyRpcTransaction, AnyTxEnvelope}; +use crate::{BlockBody, SealedBlock, Transaction, TransactionSigned}; +use alloc::string::ToString; +use alloy_consensus::TxEnvelope; +use alloy_network::{AnyRpcBlock, AnyRpcTransaction, AnyTxEnvelope}; use alloy_serde::WithOtherFields; use op_alloy_rpc_types as _; +use reth_primitives_traits::SealedHeader; -// impl TryFrom for Block { -// type Error = alloy_rpc_types::ConversionError; -// -// fn try_from(block: AnyRpcBlock) -> Result { -// use alloy_rpc_types::ConversionError; -// -// let block = block.inner; -// -// let transactions = { -// let transactions: Result, ConversionError> = match block -// .transactions -// { -// alloy_rpc_types::BlockTransactions::Full(transactions) => { -// transactions.into_iter().map(|tx| tx.try_into()).collect() -// } -// alloy_rpc_types::BlockTransactions::Hashes(_) | -// alloy_rpc_types::BlockTransactions::Uncle => { -// // alloy deserializes empty blocks into `BlockTransactions::Hashes`, if the -// tx // root is the empty root then we can just return an empty vec. -// if block.header.transactions_root == EMPTY_TRANSACTIONS { -// Ok(Vec::new()) -// } else { -// Err(ConversionError::Custom("missing transactions".to_string())) -// } -// } -// }; -// transactions? -// }; -// -// let AnyHeader { -// parent_hash, -// ommers_hash, -// beneficiary, -// state_root, -// transactions_root, -// receipts_root, -// logs_bloom, -// difficulty, -// number, -// gas_limit, -// gas_used, -// timestamp, -// extra_data, -// mix_hash, -// nonce, -// base_fee_per_gas, -// withdrawals_root, -// blob_gas_used, -// excess_blob_gas, -// parent_beacon_block_root, -// requests_hash, -// } = block.header.inner; -// -// Ok(Self { -// header: Header { -// parent_hash, -// ommers_hash, -// beneficiary, -// state_root, -// transactions_root, -// receipts_root, -// logs_bloom, -// difficulty, -// number, -// gas_limit, -// gas_used, -// timestamp, -// extra_data, -// mix_hash: mix_hash -// .ok_or_else(|| ConversionError::Custom("missing mixHash".to_string()))?, -// nonce: nonce.ok_or_else(|| ConversionError::Custom("missing -// nonce".to_string()))?, base_fee_per_gas, -// withdrawals_root, -// blob_gas_used, -// excess_blob_gas, -// parent_beacon_block_root, -// requests_hash, -// }, -// body: BlockBody { -// transactions, -// ommers: Default::default(), -// withdrawals: block.withdrawals.map(|w| w.into_inner().into()), -// }, -// }) -// } -// } +impl TryFrom for SealedBlock { + type Error = alloy_rpc_types::ConversionError; + + fn try_from(block: AnyRpcBlock) -> Result { + let block = block.inner; + let block_hash = block.header.hash; + let block = block.try_map_transactions(|tx| tx.try_into())?; + + Ok(Self { + header: SealedHeader::new(block.header.inner.into_header_with_defaults(), block_hash), + body: BlockBody { + transactions: block.transactions.into_transactions().collect(), + ommers: Default::default(), + withdrawals: block.withdrawals.map(|w| w.into_inner().into()), + }, + }) + } +} impl TryFrom for TransactionSigned { type Error = alloy_rpc_types::ConversionError; diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 2be17fbd2afe..399ebaa24af9 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -3,166 +3,83 @@ use crate::{ RecoveredTx, SealedHeader, TransactionSigned, }; use alloc::vec::Vec; -use alloy_consensus::{Header, Typed2718}; +use alloy_consensus::Header; use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawals}; use alloy_primitives::{Address, Bytes, B256}; use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable}; use derive_more::{Deref, DerefMut}; #[cfg(any(test, feature = "arbitrary"))] pub use reth_primitives_traits::test_utils::{generate_valid_header, valid_header_strategy}; -use reth_primitives_traits::{BlockBody as _, InMemorySize, SignedTransaction, Transaction}; +use reth_primitives_traits::{BlockBody as _, InMemorySize, SignedTransaction}; use serde::{Deserialize, Serialize}; +/// Ethereum full block. +/// +/// Withdrawals can be optionally included at the end of the RLP encoded message. pub type Block = alloy_consensus::Block; +/// A response to `GetBlockBodies`, containing bodies if any bodies were found. +/// +/// Withdrawals can be optionally included at the end of the RLP encoded message. pub type BlockBody = alloy_consensus::BlockBody; -// /// Ethereum full block. -// /// -// /// Withdrawals can be optionally included at the end of the RLP encoded message. -// #[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(rlp, 25))] -// #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Deref)] -// pub struct Block { -// /// Block header. -// #[deref] -// pub header: Header, -// /// Block body. -// pub body: BlockBody, -// } -// -// impl Default for Block { -// fn default() -> Self { -// Self { header: Default::default(), body: Default::default() } -// } -// } -// -// impl reth_primitives_traits::Block for Block -// where -// T: SignedTransaction, -// { -// type Header = Header; -// type Body = BlockBody; -// -// fn new(header: Self::Header, body: Self::Body) -> Self { -// Self { header, body } -// } -// -// fn header(&self) -> &Self::Header { -// &self.header -// } -// -// fn body(&self) -> &Self::Body { -// &self.body -// } -// -// fn split(self) -> (Self::Header, Self::Body) { -// (self.header, self.body) -// } -// } -// -// impl InMemorySize for Block { -// /// Calculates a heuristic for the in-memory size of the [`Block`]. -// #[inline] -// fn size(&self) -> usize { -// self.header.size() + self.body.size() -// } -// } - -// /// We need to implement RLP traits manually because we currently don't have a way to flatten -// /// [`BlockBody`] into [`Block`]. -// mod block_rlp { -// use super::*; -// -// #[derive(RlpDecodable)] -// #[rlp(trailing)] -// struct Helper { -// header: H, -// transactions: Vec, -// ommers: Vec
, -// withdrawals: Option, -// } -// -// #[derive(RlpEncodable)] -// #[rlp(trailing)] -// struct HelperRef<'a, H, T = TransactionSigned> { -// header: &'a H, -// transactions: &'a Vec, -// ommers: &'a Vec
, -// withdrawals: Option<&'a Withdrawals>, -// } -// -// impl<'a, T> From<&'a Block> for HelperRef<'a, Header, T> { -// fn from(block: &'a Block) -> Self { -// let Block { header, body: BlockBody { transactions, ommers, withdrawals } } = block; -// Self { header, transactions, ommers, withdrawals: withdrawals.as_ref() } -// } -// } -// -// impl<'a> From<&'a SealedBlock> for HelperRef<'a, SealedHeader> { -// fn from(block: &'a SealedBlock) -> Self { -// let SealedBlock { header, body: BlockBody { transactions, ommers, withdrawals } } = -// block; -// Self { header, transactions, ommers, withdrawals: withdrawals.as_ref() } -// } -// } -// -// impl Decodable for Block { -// fn decode(b: &mut &[u8]) -> alloy_rlp::Result { -// let Helper { header, transactions, ommers, withdrawals } = Helper::decode(b)?; -// Ok(Self { header, body: BlockBody { transactions, ommers, withdrawals } }) -// } -// } -// -// impl Decodable for SealedBlock { -// fn decode(b: &mut &[u8]) -> alloy_rlp::Result { -// let Helper { header, transactions, ommers, withdrawals } = Helper::decode(b)?; -// Ok(Self { header, body: BlockBody { transactions, ommers, withdrawals } }) -// } -// } -// -// impl Encodable for Block { -// fn encode(&self, out: &mut dyn bytes::BufMut) { -// let helper: HelperRef<'_, _, _> = self.into(); -// helper.encode(out) -// } -// -// fn length(&self) -> usize { -// let helper: HelperRef<'_, _, _> = self.into(); -// helper.length() -// } -// } -// -// impl Encodable for SealedBlock { -// fn encode(&self, out: &mut dyn bytes::BufMut) { -// let helper: HelperRef<'_, _, _> = self.into(); -// helper.encode(out) -// } -// -// fn length(&self) -> usize { -// let helper: HelperRef<'_, _, _> = self.into(); -// helper.length() -// } -// } -// } -// -// #[cfg(any(test, feature = "arbitrary"))] -// impl<'a> arbitrary::Arbitrary<'a> for Block { -// fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { -// // first generate up to 100 txs -// let transactions = (0..100) -// .map(|_| TransactionSigned::arbitrary(u)) -// .collect::>>()?; -// -// // then generate up to 2 ommers -// let ommers = (0..2).map(|_| -// Header::arbitrary(u)).collect::>>()?; -// -// Ok(Self { -// header: u.arbitrary()?, -// body: BlockBody { transactions, ommers, withdrawals: u.arbitrary()? }, -// }) -// } -// } +/// We need to implement RLP traits manually because we currently don't have a way to flatten +/// [`BlockBody`] into [`Block`]. +mod block_rlp { + use super::*; + + #[derive(RlpDecodable)] + #[rlp(trailing)] + struct Helper { + header: H, + transactions: Vec, + ommers: Vec
, + withdrawals: Option, + } + + #[derive(RlpEncodable)] + #[rlp(trailing)] + struct HelperRef<'a, H, T = TransactionSigned> { + header: &'a H, + transactions: &'a Vec, + ommers: &'a Vec
, + withdrawals: Option<&'a Withdrawals>, + } + + impl<'a, T> From<&'a Block> for HelperRef<'a, Header, T> { + fn from(block: &'a Block) -> Self { + let Block { header, body: BlockBody { transactions, ommers, withdrawals } } = block; + Self { header, transactions, ommers, withdrawals: withdrawals.as_ref() } + } + } + + impl<'a> From<&'a SealedBlock> for HelperRef<'a, SealedHeader> { + fn from(block: &'a SealedBlock) -> Self { + let SealedBlock { header, body: BlockBody { transactions, ommers, withdrawals } } = + block; + Self { header, transactions, ommers, withdrawals: withdrawals.as_ref() } + } + } + + impl Decodable for SealedBlock { + fn decode(b: &mut &[u8]) -> alloy_rlp::Result { + let Helper { header, transactions, ommers, withdrawals } = Helper::decode(b)?; + Ok(Self { header, body: BlockBody { transactions, ommers, withdrawals } }) + } + } + + impl Encodable for SealedBlock { + fn encode(&self, out: &mut dyn bytes::BufMut) { + let helper: HelperRef<'_, _, _> = self.into(); + helper.encode(out) + } + + fn length(&self) -> usize { + let helper: HelperRef<'_, _, _> = self.into(); + helper.length() + } + } +} /// Sealed block with senders recovered from transactions. #[derive(Debug, Clone, PartialEq, Eq, Default, Deref, DerefMut)] @@ -570,148 +487,6 @@ impl<'a> arbitrary::Arbitrary<'a> for SealedBlockWithSenders { } } -// /// A response to `GetBlockBodies`, containing bodies if any bodies were found. -// /// -// /// Withdrawals can be optionally included at the end of the RLP encoded message. -// #[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(rlp, 10))] -// #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, RlpEncodable, RlpDecodable)] -// #[rlp(trailing)] -// pub struct BlockBody { -// /// Transactions in the block -// pub transactions: Vec, -// /// Uncle headers for the given block -// pub ommers: Vec
, -// /// Withdrawals in the block. -// pub withdrawals: Option, -// } -// -// impl Default for BlockBody { -// fn default() -> Self { -// Self { -// transactions: Default::default(), -// ommers: Default::default(), -// withdrawals: Default::default(), -// } -// } -// } -// -// impl BlockBody { -// /// Create a [`Block`] from the body and its header. -// pub const fn into_block(self, header: Header) -> Block { -// Block { header, body: self } -// } -// -// /// Returns an iterator over all blob versioned hashes from the block body. -// #[inline] -// pub fn blob_versioned_hashes_iter(&self) -> impl Iterator + '_ { -// self.eip4844_transactions_iter() -// .filter_map(|tx| tx.as_eip4844().map(|blob_tx| &blob_tx.blob_versioned_hashes)) -// .flatten() -// } -// } -// -// impl BlockBody { -// /// Calculate the ommers root for the block body. -// pub fn calculate_ommers_root(&self) -> B256 { -// crate::proofs::calculate_ommers_root(&self.ommers) -// } -// -// /// Calculate the withdrawals root for the block body, if withdrawals exist. If there are no -// /// withdrawals, this will return `None`. -// pub fn calculate_withdrawals_root(&self) -> Option { -// self.withdrawals.as_ref().map(|w| crate::proofs::calculate_withdrawals_root(w)) -// } -// } -// -// impl BlockBody { -// /// Returns whether or not the block body contains any blob transactions. -// #[inline] -// pub fn has_eip4844_transactions(&self) -> bool { -// self.transactions.iter().any(|tx| tx.is_eip4844()) -// } -// -// /// Returns whether or not the block body contains any EIP-7702 transactions. -// #[inline] -// pub fn has_eip7702_transactions(&self) -> bool { -// self.transactions.iter().any(|tx| tx.is_eip7702()) -// } -// -// /// Returns an iterator over all blob transactions of the block -// #[inline] -// pub fn eip4844_transactions_iter(&self) -> impl Iterator + '_ { -// self.transactions.iter().filter(|tx| tx.is_eip4844()) -// } -// } -// -// impl InMemorySize for BlockBody { -// /// Calculates a heuristic for the in-memory size of the [`BlockBody`]. -// #[inline] -// fn size(&self) -> usize { -// self.transactions.iter().map(T::size).sum::() + -// self.transactions.capacity() * core::mem::size_of::() + -// self.ommers.iter().map(Header::size).sum::() + -// self.ommers.capacity() * core::mem::size_of::
() + -// self.withdrawals -// .as_ref() -// .map_or(core::mem::size_of::>(), Withdrawals::total_size) -// } -// } -// -// impl reth_primitives_traits::BlockBody for BlockBody -// where -// T: SignedTransaction, -// { -// type Transaction = T; -// type OmmerHeader = Header; -// -// fn transactions(&self) -> &[Self::Transaction] { -// &self.transactions -// } -// -// fn into_transactions(self) -> Vec { -// self.transactions -// } -// -// fn withdrawals(&self) -> Option<&Withdrawals> { -// self.withdrawals.as_ref() -// } -// -// fn ommers(&self) -> Option<&[Self::OmmerHeader]> { -// Some(&self.ommers) -// } -// } -// -// impl From for BlockBody { -// fn from(block: Block) -> Self { -// Self { -// transactions: block.body.transactions, -// ommers: block.body.ommers, -// withdrawals: block.body.withdrawals, -// } -// } -// } -// -// #[cfg(any(test, feature = "arbitrary"))] -// impl<'a> arbitrary::Arbitrary<'a> for BlockBody { -// fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { -// // first generate up to 100 txs -// let transactions = (0..100) -// .map(|_| TransactionSigned::arbitrary(u)) -// .collect::>>()?; -// -// // then generate up to 2 ommers -// let ommers = (0..2) -// .map(|_| { -// let header = Header::arbitrary(u)?; -// -// Ok(header) -// }) -// .collect::>>()?; -// -// Ok(Self { transactions, ommers, withdrawals: u.arbitrary()? }) -// } -// } - /// Bincode-compatible block type serde implementations. #[cfg(feature = "serde-bincode-compat")] pub(super) mod serde_bincode_compat { @@ -724,6 +499,7 @@ pub(super) mod serde_bincode_compat { use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_with::{DeserializeAs, SerializeAs}; + /// Bincode-compatible [`super::BlockBody`] serde implementation. pub type BlockBody<'a, T = super::TransactionSigned> = reth_primitives_traits::serde_bincode_compat::BlockBody<'a, T>; diff --git a/crates/prune/prune/src/segments/mod.rs b/crates/prune/prune/src/segments/mod.rs index ae18bcb3c6ee..1dc907732894 100644 --- a/crates/prune/prune/src/segments/mod.rs +++ b/crates/prune/prune/src/segments/mod.rs @@ -146,7 +146,6 @@ impl PruneInput { mod tests { use super::*; use alloy_primitives::B256; - use reth_primitives_traits::BlockBody; use reth_provider::{ providers::BlockchainProvider2, test_utils::{create_test_provider_factory, MockEthProvider}, @@ -243,8 +242,7 @@ mod tests { let range = input.get_next_tx_num_range(&provider).expect("Expected range").unwrap(); // Calculate the total number of transactions - let num_txs = - blocks.iter().map(|block| block.body.transactions().len() as u64).sum::(); + let num_txs = blocks.iter().map(|block| block.body.transactions.len() as u64).sum::(); assert_eq!(range, 0..=num_txs - 1); } @@ -290,8 +288,7 @@ mod tests { let range = input.get_next_tx_num_range(&provider).expect("Expected range").unwrap(); // Calculate the total number of transactions - let num_txs = - blocks.iter().map(|block| block.body.transactions().len() as u64).sum::(); + let num_txs = blocks.iter().map(|block| block.body.transactions.len() as u64).sum::(); assert_eq!(range, 0..=num_txs - 1,); } @@ -325,8 +322,7 @@ mod tests { // Get the last tx number // Calculate the total number of transactions - let num_txs = - blocks.iter().map(|block| block.body.transactions().len() as u64).sum::(); + let num_txs = blocks.iter().map(|block| block.body.transactions.len() as u64).sum::(); let max_range = num_txs - 1; // Create a prune input with a previous checkpoint that is the last tx number diff --git a/crates/storage/provider/src/providers/blockchain_provider.rs b/crates/storage/provider/src/providers/blockchain_provider.rs index dd23128cb1c4..c147c45348f5 100644 --- a/crates/storage/provider/src/providers/blockchain_provider.rs +++ b/crates/storage/provider/src/providers/blockchain_provider.rs @@ -907,7 +907,7 @@ mod tests { transactions_writer.increment_block(block.number)?; receipts_writer.increment_block(block.number)?; - for (tx, receipt) in block.body.transactions().iter().zip(receipts) { + for (tx, receipt) in block.body().transactions().zip(receipts) { transactions_writer.append_transaction(tx_num, tx)?; receipts_writer.append_receipt(tx_num, receipt)?; tx_num += 1; From 1288d8667d03f9da176cf400d5db6bd741cbd287 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 31 Dec 2024 08:23:47 +0100 Subject: [PATCH 5/5] fix docs --- crates/primitives-traits/src/serde_bincode_compat.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/primitives-traits/src/serde_bincode_compat.rs b/crates/primitives-traits/src/serde_bincode_compat.rs index 4b77a126eaaa..705898e6da97 100644 --- a/crates/primitives-traits/src/serde_bincode_compat.rs +++ b/crates/primitives-traits/src/serde_bincode_compat.rs @@ -26,14 +26,14 @@ mod block_bincode { /// /// Intended to use with the [`serde_with::serde_as`] macro in the following way: /// ```rust - /// use reth_primitives_traits::serde_bincode_compat; + /// use reth_primitives_traits::serde_bincode_compat::{self, SerdeBincodeCompat}; /// use serde::{Deserialize, Serialize}; /// use serde_with::serde_as; /// /// #[serde_as] /// #[derive(Serialize, Deserialize)] - /// struct Data { - /// #[serde_as(as = "serde_bincode_compat::BlockBody")] + /// struct Data { + /// #[serde_as(as = "serde_bincode_compat::BlockBody<'_, T>")] /// body: alloy_consensus::BlockBody, /// } /// ```