Skip to content

Commit

Permalink
feat: receipt root fn (#1708)
Browse files Browse the repository at this point in the history
* wip: receipt root

* wip

* add auto_impl

---------

Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
  • Loading branch information
mattsse and klkvr authored Dec 2, 2024
1 parent 7b4db9e commit 01e0081
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 0 deletions.
100 changes: 100 additions & 0 deletions crates/consensus/src/proofs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,103 @@ pub fn calculate_ommers_root(ommers: &[Header]) -> B256 {
alloy_rlp::encode_list(ommers, &mut ommers_rlp);
keccak256(ommers_rlp)
}

/// Calculates the receipt root.
pub fn calculate_receipt_root<T>(receipts: &[T]) -> B256
where
T: Encodable2718,
{
ordered_trie_root_with_encoder(receipts, |r, buf| r.encode_2718(buf))
}

#[cfg(test)]
mod tests {
use super::*;
use crate::{
Eip2718EncodableReceipt, Eip658Value, Receipt, ReceiptWithBloom, RlpEncodableReceipt,
TxType, Typed2718,
};
use alloy_primitives::{b256, bloom, Address, Log, LogData};

struct TypedReceipt {
ty: TxType,
receipt: Receipt,
}

impl RlpEncodableReceipt for TypedReceipt {
fn rlp_encoded_length_with_bloom(&self, bloom: &alloy_primitives::Bloom) -> usize {
let mut payload_length = self.eip2718_encoded_length_with_bloom(bloom);

if !self.ty.is_legacy() {
payload_length += alloy_rlp::Header {
list: false,
payload_length: self.eip2718_encoded_length_with_bloom(bloom),
}
.length();
}

payload_length
}

fn rlp_encode_with_bloom(
&self,
bloom: &alloy_primitives::Bloom,
out: &mut dyn alloy_rlp::BufMut,
) {
if !self.ty.is_legacy() {
alloy_rlp::Header {
list: false,
payload_length: self.eip2718_encoded_length_with_bloom(bloom),
}
.encode(out)
}
self.eip2718_encode_with_bloom(bloom, out);
}
}

impl Eip2718EncodableReceipt for TypedReceipt {
fn eip2718_encode_with_bloom(
&self,
bloom: &alloy_primitives::Bloom,
out: &mut dyn alloy_rlp::BufMut,
) {
if !self.ty.is_legacy() {
out.put_u8(self.ty.ty());
}
self.receipt.rlp_encode_with_bloom(bloom, out);
}

fn eip2718_encoded_length_with_bloom(&self, bloom: &alloy_primitives::Bloom) -> usize {
self.receipt.rlp_encoded_length_with_bloom(bloom) + (!self.ty.is_legacy()) as usize
}
}

impl Typed2718 for TypedReceipt {
fn ty(&self) -> u8 {
self.ty.ty()
}
}

#[test]
fn check_receipt_root_optimism() {
let logs = vec![Log {
address: Address::ZERO,
data: LogData::new_unchecked(vec![], Default::default()),
}];
let logs_bloom = bloom!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
let receipt = ReceiptWithBloom {
receipt: TypedReceipt {
receipt: Receipt {
status: Eip658Value::success(),
cumulative_gas_used: 102068,
logs,
},
ty: TxType::Eip2930,
},
logs_bloom,
};
let receipt = vec![receipt];
let root = calculate_receipt_root(&receipt);
assert_eq!(root, b256!("fe70ae4a136d98944951b2123859698d59ad251a381abc9960fa81cae3d0d4a0"));
}
}
1 change: 1 addition & 0 deletions crates/consensus/src/receipt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ pub trait RlpDecodableReceipt: Sized {
/// Main consumer of this trait is [`ReceiptWithBloom`]. It is expected that [`RlpEncodableReceipt`]
/// implementation for this type produces network encoding whcih is used by [`alloy_rlp::Encodable`]
/// implementation for [`ReceiptWithBloom`].
#[auto_impl::auto_impl(&)]
pub trait Eip2718EncodableReceipt: RlpEncodableReceipt + Typed2718 {
/// EIP-2718 encoded length with the provided bloom filter.
fn eip2718_encoded_length_with_bloom(&self, bloom: &Bloom) -> usize;
Expand Down
5 changes: 5 additions & 0 deletions crates/consensus/src/receipt/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ pub enum Eip658Value {
}

impl Eip658Value {
/// Returns a successful transaction status.
pub const fn success() -> Self {
Self::Eip658(true)
}

/// Returns true if the transaction was successful OR if the transaction
/// is pre-[EIP-658].
///
Expand Down

0 comments on commit 01e0081

Please sign in to comment.