Skip to content

Commit

Permalink
feat: use alloy block types (#13518)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsse authored Dec 31, 2024
1 parent 9a062c0 commit f163b3d
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 388 deletions.
5 changes: 2 additions & 3 deletions bin/reth-bench/src/bench/new_payload_fcu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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());
Expand Down
5 changes: 2 additions & 3 deletions bin/reth-bench/src/bench/new_payload_only.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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();
Expand Down
6 changes: 3 additions & 3 deletions crates/optimism/consensus/src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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),
})
}
Expand Down
82 changes: 81 additions & 1 deletion crates/primitives-traits/src/serde_bincode_compat.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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<T: SerdeBincodeCompat> {
/// #[serde_as(as = "serde_bincode_compat::BlockBody<'_, T>")]
/// body: alloy_consensus::BlockBody<T>,
/// }
/// ```
#[derive(derive_more::Debug, Serialize, Deserialize)]
#[debug(bound())]
pub struct BlockBody<'a, T: SerdeBincodeCompat> {
transactions: Vec<T::BincodeRepr<'a>>,
ommers: Vec<Header<'a>>,
withdrawals: Cow<'a, Option<Withdrawals>>,
}

impl<'a, T: SerdeBincodeCompat> From<&'a alloy_consensus::BlockBody<T>> for BlockBody<'a, T> {
fn from(value: &'a alloy_consensus::BlockBody<T>) -> 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<BlockBody<'a, T>> for alloy_consensus::BlockBody<T> {
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<T: SerdeBincodeCompat> SerializeAs<alloy_consensus::BlockBody<T>> for BlockBody<'_, T> {
fn serialize_as<S>(
source: &alloy_consensus::BlockBody<T>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
BlockBody::from(source).serialize(serializer)
}
}

impl<'de, T: SerdeBincodeCompat> DeserializeAs<'de, alloy_consensus::BlockBody<T>>
for BlockBody<'de, T>
{
fn deserialize_as<D>(deserializer: D) -> Result<alloy_consensus::BlockBody<T>, D::Error>
where
D: Deserializer<'de>,
{
BlockBody::deserialize(deserializer).map(Into::into)
}
}

impl<T: SerdeBincodeCompat> SerdeBincodeCompat for alloy_consensus::BlockBody<T> {
type BincodeRepr<'a> = BlockBody<'a, T>;
}
}
87 changes: 10 additions & 77 deletions crates/primitives/src/alloy_compat.rs
Original file line number Diff line number Diff line change
@@ -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<AnyRpcBlock> for Block {
impl TryFrom<AnyRpcBlock> for SealedBlock {
type Error = alloy_rpc_types::ConversionError;

fn try_from(block: AnyRpcBlock) -> Result<Self, Self::Error> {
use alloy_rpc_types::ConversionError;

let block = block.inner;

let transactions = {
let transactions: Result<Vec<TransactionSigned>, 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()),
},
Expand Down
Loading

0 comments on commit f163b3d

Please sign in to comment.