Skip to content

Commit

Permalink
feat: SerdeBincodeCompat trait
Browse files Browse the repository at this point in the history
  • Loading branch information
klkvr committed Nov 28, 2024
1 parent da53d76 commit dc83dc5
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 31 deletions.
36 changes: 23 additions & 13 deletions crates/primitives-traits/src/header/sealed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,12 @@ where
/// Bincode-compatible [`SealedHeader`] serde implementation.
#[cfg(feature = "serde-bincode-compat")]
pub(super) mod serde_bincode_compat {
use alloy_consensus::serde_bincode_compat::Header;
use alloy_primitives::BlockHash;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_with::{DeserializeAs, SerializeAs};

use crate::serde_bincode_compat::SerdeBincodeCompat;

/// Bincode-compatible [`super::SealedHeader`] serde implementation.
///
/// Intended to use with the [`serde_with::serde_as`] macro in the following way:
Expand All @@ -193,42 +194,51 @@ pub(super) mod serde_bincode_compat {
/// header: SealedHeader,
/// }
/// ```
#[derive(Debug, Serialize, Deserialize)]
pub struct SealedHeader<'a> {
#[derive(derive_more::Debug, Serialize, Deserialize)]
#[debug(bound(H::BincodeRepr<'a>: core::fmt::Debug))]
pub struct SealedHeader<'a, H: SerdeBincodeCompat = super::Header> {
hash: BlockHash,
header: Header<'a>,
header: H::BincodeRepr<'a>,
}

impl<'a> From<&'a super::SealedHeader> for SealedHeader<'a> {
fn from(value: &'a super::SealedHeader) -> Self {
Self { hash: value.hash, header: Header::from(&value.header) }
impl<'a, H: SerdeBincodeCompat> From<&'a super::SealedHeader<H>> for SealedHeader<'a, H> {
fn from(value: &'a super::SealedHeader<H>) -> Self {
Self { hash: value.hash, header: (&value.header).into() }
}
}

impl<'a> From<SealedHeader<'a>> for super::SealedHeader {
fn from(value: SealedHeader<'a>) -> Self {
impl<'a, H: SerdeBincodeCompat> From<SealedHeader<'a, H>> for super::SealedHeader<H> {
fn from(value: SealedHeader<'a, H>) -> Self {
Self { hash: value.hash, header: value.header.into() }
}
}

impl SerializeAs<super::SealedHeader> for SealedHeader<'_> {
fn serialize_as<S>(source: &super::SealedHeader, serializer: S) -> Result<S::Ok, S::Error>
impl<H: SerdeBincodeCompat> SerializeAs<super::SealedHeader<H>> for SealedHeader<'_, H> {
fn serialize_as<S>(
source: &super::SealedHeader<H>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
SealedHeader::from(source).serialize(serializer)
}
}

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

impl<H: SerdeBincodeCompat> SerdeBincodeCompat for super::SealedHeader<H> {
type BincodeRepr<'a> = SealedHeader<'a, H>;
}
#[cfg(test)]
mod tests {
use super::super::{serde_bincode_compat, SealedHeader};
Expand Down
4 changes: 1 addition & 3 deletions crates/primitives-traits/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,7 @@ pub use header::{BlockWithParent, Header, HeaderError, SealedHeader};
///
/// Read more: <https://github.com/bincode-org/bincode/issues/326>
#[cfg(feature = "serde-bincode-compat")]
pub mod serde_bincode_compat {
pub use super::header::{serde_bincode_compat as header, serde_bincode_compat::*};
}
pub mod serde_bincode_compat;

/// Heuristic size trait
pub mod size;
Expand Down
14 changes: 14 additions & 0 deletions crates/primitives-traits/src/serde_bincode_compat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use core::fmt::Debug;

pub use super::header::{serde_bincode_compat as header, serde_bincode_compat::*};
use serde::{de::DeserializeOwned, Serialize};

/// Trait for types that can be serialized and deserialized using bincode.
pub trait SerdeBincodeCompat: Sized + 'static {
/// Serde representation of the type for bincode serialization.
type BincodeRepr<'a>: Debug + Serialize + DeserializeOwned + From<&'a Self> + Into<Self>;
}

impl SerdeBincodeCompat for alloy_consensus::Header {
type BincodeRepr<'a> = alloy_consensus::serde_bincode_compat::Header<'a>;
}
63 changes: 48 additions & 15 deletions crates/primitives/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ pub(super) mod serde_bincode_compat {
use alloy_consensus::serde_bincode_compat::Header;
use alloy_eips::eip4895::Withdrawals;
use alloy_primitives::Address;
use reth_primitives_traits::serde_bincode_compat::SealedHeader;
use reth_primitives_traits::serde_bincode_compat::{SealedHeader, SerdeBincodeCompat};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_with::{DeserializeAs, SerializeAs};

Expand Down Expand Up @@ -810,6 +810,10 @@ pub(super) mod serde_bincode_compat {
}
}

impl SerdeBincodeCompat for super::BlockBody {
type BincodeRepr<'a> = BlockBody<'a>;
}

/// Bincode-compatible [`super::SealedBlock`] serde implementation.
///
/// Intended to use with the [`serde_with::serde_as`] macro in the following way:
Expand All @@ -826,19 +830,34 @@ pub(super) mod serde_bincode_compat {
/// }
/// ```
#[derive(Debug, Serialize, Deserialize)]
pub struct SealedBlock<'a> {
header: SealedHeader<'a>,
body: BlockBody<'a>,
pub struct SealedBlock<
'a,
H: SerdeBincodeCompat = super::Header,
B: SerdeBincodeCompat = super::BlockBody,
> {
header: SealedHeader<'a, H>,
body: B::BincodeRepr<'a>,
}

impl<'a> From<&'a super::SealedBlock> for SealedBlock<'a> {
fn from(value: &'a super::SealedBlock) -> Self {
Self { header: SealedHeader::from(&value.header), body: BlockBody::from(&value.body) }
impl<'a, H, B> From<&'a super::SealedBlock<H, B>> for SealedBlock<'a, H, B>
where
H: SerdeBincodeCompat,
B: SerdeBincodeCompat,
{
fn from(value: &'a super::SealedBlock<H, B>) -> Self {
Self {
header: SealedHeader::from(&value.header),
body: B::BincodeRepr::from(&value.body),
}
}
}

impl<'a> From<SealedBlock<'a>> for super::SealedBlock {
fn from(value: SealedBlock<'a>) -> Self {
impl<'a, H, B> From<SealedBlock<'a, H, B>> for super::SealedBlock<H, B>
where
H: SerdeBincodeCompat,
B: SerdeBincodeCompat,
{
fn from(value: SealedBlock<'a, H, B>) -> Self {
Self { header: value.header.into(), body: value.body.into() }
}
}
Expand Down Expand Up @@ -877,19 +896,33 @@ pub(super) mod serde_bincode_compat {
/// }
/// ```
#[derive(Debug, Serialize, Deserialize)]
pub struct SealedBlockWithSenders<'a> {
block: SealedBlock<'a>,
pub struct SealedBlockWithSenders<'a, B: reth_primitives_traits::Block = super::Block>
where
B::Header: SerdeBincodeCompat,
B::Body: SerdeBincodeCompat,
{
block: SealedBlock<'a, B::Header, B::Body>,
senders: Cow<'a, Vec<Address>>,
}

impl<'a> From<&'a super::SealedBlockWithSenders> for SealedBlockWithSenders<'a> {
fn from(value: &'a super::SealedBlockWithSenders) -> Self {
impl<'a, B: reth_primitives_traits::Block> From<&'a super::SealedBlockWithSenders<B>>
for SealedBlockWithSenders<'a, B>
where
B::Header: SerdeBincodeCompat,
B::Body: SerdeBincodeCompat,
{
fn from(value: &'a super::SealedBlockWithSenders<B>) -> Self {
Self { block: SealedBlock::from(&value.block), senders: Cow::Borrowed(&value.senders) }
}
}

impl<'a> From<SealedBlockWithSenders<'a>> for super::SealedBlockWithSenders {
fn from(value: SealedBlockWithSenders<'a>) -> Self {
impl<'a, B: reth_primitives_traits::Block> From<SealedBlockWithSenders<'a, B>>
for super::SealedBlockWithSenders<B>
where
B::Header: SerdeBincodeCompat,
B::Body: SerdeBincodeCompat,
{
fn from(value: SealedBlockWithSenders<'a, B>) -> Self {
Self { block: value.block.into(), senders: value.senders.into_owned() }
}
}
Expand Down

0 comments on commit dc83dc5

Please sign in to comment.