Skip to content

Commit

Permalink
chore: add receipt conversion fns (#1949)
Browse files Browse the repository at this point in the history
* chore: add receipt conversion fns

* rustmft

* docs
  • Loading branch information
mattsse authored Jan 27, 2025
1 parent 0c75536 commit f21cfd6
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 1 deletion.
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

0 comments on commit f21cfd6

Please sign in to comment.