From f163b3d3f948241e29bf0c81a3f57d946bd1b875 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 31 Dec 2024 10:30:15 +0100 Subject: [PATCH] feat: use alloy block types (#13518) --- bin/reth-bench/src/bench/new_payload_fcu.rs | 5 +- bin/reth-bench/src/bench/new_payload_only.rs | 5 +- crates/optimism/consensus/src/validation.rs | 6 +- .../src/serde_bincode_compat.rs | 82 ++++- crates/primitives/src/alloy_compat.rs | 87 +---- crates/primitives/src/block.rs | 302 +----------------- crates/prune/prune/src/segments/mod.rs | 10 +- .../src/providers/blockchain_provider.rs | 2 +- 8 files changed, 111 insertions(+), 388 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/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), }) } diff --git a/crates/primitives-traits/src/serde_bincode_compat.rs b/crates/primitives-traits/src/serde_bincode_compat.rs index a1f7d42569e8..705898e6da97 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::{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<'_, T>")] + /// 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..2409c535cd3b 100644 --- a/crates/primitives/src/alloy_compat.rs +++ b/crates/primitives/src/alloy_compat.rs @@ -1,92 +1,25 @@ //! 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 { +impl TryFrom for SealedBlock { 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; + let block_hash = block.header.hash; + let block = block.try_map_transactions(|tx| tx.try_into())?; 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, - }, + header: SealedHeader::new(block.header.inner.into_header_with_defaults(), block_hash), body: BlockBody { - transactions, + transactions: block.transactions.into_transactions().collect(), ommers: Default::default(), withdrawals: block.withdrawals.map(|w| w.into_inner().into()), }, diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index dbfe1365d3d6..399ebaa24af9 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -3,66 +3,25 @@ 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. -#[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) - } -} +pub type Block = alloy_consensus::Block; -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() - } -} +/// 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; /// We need to implement RLP traits manually because we currently don't have a way to flatten /// [`BlockBody`] into [`Block`]. @@ -102,13 +61,6 @@ mod block_rlp { } } - 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)?; @@ -116,18 +68,6 @@ mod block_rlp { } } - 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(); @@ -141,24 +81,6 @@ mod block_rlp { } } -#[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)] pub struct BlockWithSenders { @@ -565,154 +487,10 @@ 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 { 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}, @@ -722,69 +500,8 @@ pub(super) mod serde_bincode_compat { 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. /// @@ -918,7 +635,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; 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;