Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add receipt conversion fns #1949

Merged
merged 3 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions crates/consensus/src/receipt/envelope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,31 @@ pub enum ReceiptEnvelope<T = Log> {
}

impl<T> ReceiptEnvelope<T> {
/// Converts the receipt's log type by applying a function to each log.
///
/// Returns the receipt with the new log type.
pub fn map_logs<U>(self, f: impl FnMut(T) -> U) -> ReceiptEnvelope<U> {
match self {
Self::Legacy(r) => ReceiptEnvelope::Legacy(r.map_logs(f)),
Self::Eip2930(r) => ReceiptEnvelope::Eip2930(r.map_logs(f)),
Self::Eip1559(r) => ReceiptEnvelope::Eip1559(r.map_logs(f)),
Self::Eip4844(r) => ReceiptEnvelope::Eip4844(r.map_logs(f)),
Self::Eip7702(r) => ReceiptEnvelope::Eip7702(r.map_logs(f)),
}
}

/// Converts a [`ReceiptEnvelope`] with a custom log type into a [`ReceiptEnvelope`] with the
/// primitives [`Log`] type by converting the logs.
///
/// This is useful if log types that embed the primitives log type, e.g. the log receipt rpc
/// type.
pub fn into_primitives_receipt(self) -> ReceiptEnvelope<Log>
where
T: Into<Log>,
{
self.map_logs(Into::into)
}

/// Return the [`TxType`] of the inner receipt.
#[doc(alias = "transaction_type")]
pub const fn tx_type(&self) -> TxType {
Expand Down
54 changes: 54 additions & 0 deletions crates/consensus/src/receipt/receipts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ pub struct Receipt<T = Log> {
pub logs: Vec<T>,
}

impl<T> Receipt<T> {
/// Converts the receipt's log type by applying a function to each log.
///
/// Returns the receipt with the new log type
pub fn map_logs<U>(self, f: impl FnMut(T) -> U) -> Receipt<U> {
let Self { status, cumulative_gas_used, logs } = self;
Receipt { status, cumulative_gas_used, logs: logs.into_iter().map(f).collect() }
}
}

impl<T> Receipt<T>
where
T: AsRef<Log>,
Expand All @@ -44,6 +54,20 @@ where
}
}

impl<T> Receipt<T>
where
T: Into<Log>,
{
/// Converts a [`Receipt`] with a custom log type into a [`Receipt`] with the primitives [`Log`]
/// type by converting the logs.
///
/// This is useful if log types that embed the primitives log type, e.g. the log receipt rpc
/// type.
pub fn into_primitives_receipt(self) -> Receipt<Log> {
self.map_logs(Into::into)
}
}

impl<T> TxReceipt for Receipt<T>
where
T: AsRef<Log> + Clone + fmt::Debug + PartialEq + Eq + Send + Sync,
Expand Down Expand Up @@ -275,6 +299,14 @@ where
}

impl<R> ReceiptWithBloom<R> {
/// Converts the receipt type by applying the given closure to it.
///
/// Returns the type with the new receipt type.
pub fn map_receipt<U>(self, f: impl FnOnce(R) -> U) -> ReceiptWithBloom<U> {
let Self { receipt, logs_bloom } = self;
ReceiptWithBloom { receipt: f(receipt), logs_bloom }
}

/// Create new [ReceiptWithBloom]
pub const fn new(receipt: R, logs_bloom: Bloom) -> Self {
Self { receipt, logs_bloom }
Expand All @@ -286,6 +318,28 @@ impl<R> ReceiptWithBloom<R> {
}
}

impl<L> ReceiptWithBloom<Receipt<L>> {
/// Converts the receipt's log type by applying a function to each log.
///
/// Returns the receipt with the new log type.
pub fn map_logs<U>(self, f: impl FnMut(L) -> U) -> ReceiptWithBloom<Receipt<U>> {
let Self { receipt, logs_bloom } = self;
ReceiptWithBloom { receipt: receipt.map_logs(f), logs_bloom }
}

/// Converts a [`ReceiptWithBloom`] with a custom log type into a [`ReceiptWithBloom`] with the
/// primitives [`Log`] type by converting the logs.
///
/// This is useful if log types that embed the primitives log type, e.g. the log receipt rpc
/// type.
pub fn into_primitives_receipt(self) -> ReceiptWithBloom<Receipt<Log>>
where
L: Into<Log>,
{
self.map_logs(Into::into)
}
}

impl<R: RlpEncodableReceipt> Encodable for ReceiptWithBloom<R> {
fn encode(&self, out: &mut dyn BufMut) {
self.receipt.rlp_encode_with_bloom(&self.logs_bloom, out);
Expand Down
11 changes: 11 additions & 0 deletions crates/rpc-types-eth/src/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ impl<T> Log<T> {
pub const fn data(&self) -> &T {
&self.inner.data
}

/// Consumes the type and returns the wrapped [`alloy_primitives::Log`]
pub fn into_inner(self) -> alloy_primitives::Log<T> {
self.inner
}
}

impl Log<LogData> {
Expand Down Expand Up @@ -151,6 +156,12 @@ impl<T> AsMut<T> for Log<T> {
}
}

impl<L> From<Log<L>> for alloy_primitives::Log<L> {
fn from(value: Log<L>) -> Self {
value.into_inner()
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
34 changes: 33 additions & 1 deletion crates/rpc-types-eth/src/transaction/receipt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use alloy_primitives::{Address, BlockHash, TxHash, B256};
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
#[doc(alias = "TxReceipt")]
pub struct TransactionReceipt<T = ReceiptEnvelope<Log>> {
/// The receipt envelope, which contains the consensus receipt data..
/// The receipt envelope, which contains the consensus receipt data.
#[cfg_attr(feature = "serde", serde(flatten))]
pub inner: T,
/// Transaction Hash.
Expand Down Expand Up @@ -124,6 +124,32 @@ impl<T> TransactionReceipt<T> {
contract_address: self.contract_address,
}
}

/// Consumes the type and returns the wrapped receipt.
pub fn into_inner(self) -> T {
self.inner
}
}

impl<L> TransactionReceipt<ReceiptEnvelope<L>> {
/// Converts the receipt's log type by applying a function to each log.
///
/// Returns the receipt with the new log type.
pub fn map_logs<U>(self, f: impl FnMut(L) -> U) -> TransactionReceipt<ReceiptEnvelope<U>> {
self.map_inner(|inner| inner.map_logs(f))
}

/// Converts the transaction receipt's [`ReceiptEnvelope`] with a custom log type into a
/// [`ReceiptEnvelope`] with the primitives [`alloy_primitives::Log`] type by converting the
/// logs.
pub fn into_primitives_receipt(
self,
) -> TransactionReceipt<ReceiptEnvelope<alloy_primitives::Log>>
where
L: Into<alloy_primitives::Log>,
{
self.map_logs(Into::into)
}
}

impl<T: TxReceipt<Log = Log>> ReceiptResponse for TransactionReceipt<T> {
Expand Down Expand Up @@ -184,6 +210,12 @@ impl<T: TxReceipt<Log = Log>> ReceiptResponse for TransactionReceipt<T> {
}
}

impl From<TransactionReceipt> for TransactionReceipt<ReceiptEnvelope<alloy_primitives::Log>> {
fn from(value: TransactionReceipt) -> Self {
value.into_primitives_receipt()
}
}

#[cfg(test)]
mod test {
use super::*;
Expand Down
Loading