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

fix: add more generics to any and receipt with bloom #559

Merged
merged 1 commit into from
Apr 17, 2024
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
19 changes: 12 additions & 7 deletions crates/consensus/src/receipt/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,10 @@ pub struct AnyReceiptEnvelope<T = Log> {
pub r#type: u8,
}

impl AnyReceiptEnvelope {
/// Returns whether this is a legacy receipt (type 0)
pub const fn is_legacy(&self) -> bool {
self.r#type == 0
}

impl<T> AnyReceiptEnvelope<T>
where
T: Encodable,
{
/// Calculate the length of the rlp payload of the network encoded receipt.
pub fn rlp_payload_length(&self) -> usize {
let length = self.inner.length();
Expand All @@ -39,6 +37,13 @@ impl AnyReceiptEnvelope {
length + 1
}
}
}

impl<T> AnyReceiptEnvelope<T> {
/// Returns whether this is a legacy receipt (type 0)
pub const fn is_legacy(&self) -> bool {
self.r#type == 0
}

/// Return true if the transaction was successful.
pub const fn is_success(&self) -> bool {
Expand All @@ -56,7 +61,7 @@ impl AnyReceiptEnvelope {
}

/// Return the receipt logs.
pub fn logs(&self) -> &[Log] {
pub fn logs(&self) -> &[T] {
&self.inner.receipt.logs
}

Expand Down
77 changes: 45 additions & 32 deletions crates/consensus/src/receipt/receipts.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::borrow::Borrow;

use super::TxReceipt;
use alloy_primitives::{Bloom, Log};
use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable};
Expand All @@ -23,16 +25,19 @@ pub struct Receipt<T = Log> {
pub logs: Vec<T>,
}

impl Receipt {
impl<T> Receipt<T>
where
T: Borrow<Log>,
{
/// Calculates [`Log`]'s bloom filter. this is slow operation and [ReceiptWithBloom] can
/// be used to cache this value.
pub fn bloom_slow(&self) -> Bloom {
self.logs.iter().collect()
self.logs.iter().map(Borrow::borrow).collect()
}

/// Calculates the bloom filter for the receipt and returns the [ReceiptWithBloom] container
/// type.
pub fn with_bloom(self) -> ReceiptWithBloom {
pub fn with_bloom(self) -> ReceiptWithBloom<T> {
self.into()
}
}
Expand Down Expand Up @@ -94,29 +99,29 @@ impl TxReceipt for ReceiptWithBloom {
}
}

impl From<Receipt> for ReceiptWithBloom {
fn from(receipt: Receipt) -> Self {
impl<T> From<Receipt<T>> for ReceiptWithBloom<T>
where
T: Borrow<Log>,
{
fn from(receipt: Receipt<T>) -> Self {
let bloom = receipt.bloom_slow();
ReceiptWithBloom { receipt, logs_bloom: bloom }
}
}

impl ReceiptWithBloom {
/// Create new [ReceiptWithBloom]
pub const fn new(receipt: Receipt, bloom: Bloom) -> Self {
Self { receipt, logs_bloom: bloom }
}

/// Consume the structure, returning only the receipt
#[allow(clippy::missing_const_for_fn)] // false positive
pub fn into_receipt(self) -> Receipt {
self.receipt
impl<T: Encodable> ReceiptWithBloom<T> {
/// Returns the rlp header for the receipt payload.
fn receipt_rlp_header(&self) -> alloy_rlp::Header {
alloy_rlp::Header { list: true, payload_length: self.payload_len() }
}

/// Consume the structure, returning the receipt and the bloom filter
#[allow(clippy::missing_const_for_fn)] // false positive
pub fn into_components(self) -> (Receipt, Bloom) {
(self.receipt, self.logs_bloom)
/// Encodes the receipt data.
fn encode_fields(&self, out: &mut dyn BufMut) {
self.receipt_rlp_header().encode(out);
self.receipt.status.encode(out);
self.receipt.cumulative_gas_used.encode(out);
self.logs_bloom.encode(out);
self.receipt.logs.encode(out);
}

fn payload_len(&self) -> usize {
Expand All @@ -125,23 +130,31 @@ impl ReceiptWithBloom {
+ self.logs_bloom.length()
+ self.receipt.logs.length()
}
}

/// Returns the rlp header for the receipt payload.
fn receipt_rlp_header(&self) -> alloy_rlp::Header {
alloy_rlp::Header { list: true, payload_length: self.payload_len() }
impl<T> ReceiptWithBloom<T> {
/// Create new [ReceiptWithBloom]
pub const fn new(receipt: Receipt<T>, bloom: Bloom) -> Self {
Self { receipt, logs_bloom: bloom }
}

/// Encodes the receipt data.
fn encode_fields(&self, out: &mut dyn BufMut) {
self.receipt_rlp_header().encode(out);
self.receipt.status.encode(out);
self.receipt.cumulative_gas_used.encode(out);
self.logs_bloom.encode(out);
self.receipt.logs.encode(out);
/// Consume the structure, returning only the receipt
#[allow(clippy::missing_const_for_fn)] // false positive
pub fn into_receipt(self) -> Receipt<T> {
self.receipt
}

/// Consume the structure, returning the receipt and the bloom filter
#[allow(clippy::missing_const_for_fn)] // false positive
pub fn into_components(self) -> (Receipt<T>, Bloom) {
(self.receipt, self.logs_bloom)
}

/// Decodes the receipt payload
fn decode_receipt(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
fn decode_receipt(buf: &mut &[u8]) -> alloy_rlp::Result<Self>
where
T: Decodable,
{
let b: &mut &[u8] = &mut &**buf;
let rlp_head = alloy_rlp::Header::decode(b)?;
if !rlp_head.list {
Expand Down Expand Up @@ -169,7 +182,7 @@ impl ReceiptWithBloom {
}
}

impl alloy_rlp::Encodable for ReceiptWithBloom {
impl<T: Encodable> Encodable for ReceiptWithBloom<T> {
fn encode(&self, out: &mut dyn BufMut) {
self.encode_fields(out);
}
Expand All @@ -183,7 +196,7 @@ impl alloy_rlp::Encodable for ReceiptWithBloom {
}
}

impl alloy_rlp::Decodable for ReceiptWithBloom {
impl<T: Decodable> Decodable for ReceiptWithBloom<T> {
fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
Self::decode_receipt(buf)
}
Expand Down
27 changes: 22 additions & 5 deletions crates/rpc-types/src/eth/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,34 @@ impl Log<LogData> {
}
}

impl<T> alloy_rlp::Encodable for Log<T>
where
for<'a> &'a T: Into<LogData>,
{
fn encode(&self, out: &mut dyn alloy_rlp::BufMut) {
self.reserialize_inner().encode(out)
}

fn length(&self) -> usize {
self.reserialize_inner().length()
}
}

impl<T> Log<T>
where
for<'a> &'a T: Into<LogData>,
{
/// Reserialize the data.
/// Reserialize the inner data, returning an [`alloy_primitives::Log`].
pub fn reserialize_inner(&self) -> alloy_primitives::Log {
alloy_primitives::Log { address: self.inner.address, data: (&self.inner.data).into() }
}

/// Reserialize the data, returning a new `Log` object wrapping an
/// [`alloy_primitives::Log`]. this copies the log metadata, preserving
/// the original object.
pub fn reserialize(&self) -> Log<LogData> {
Log {
inner: alloy_primitives::Log {
address: self.inner.address,
data: (&self.inner.data).into(),
},
inner: self.reserialize_inner(),
block_hash: self.block_hash,
block_number: self.block_number,
block_timestamp: self.block_timestamp,
Expand Down
Loading