From 64561cab163e2070775d7d295344c76dc3f052d3 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 29 Nov 2024 17:00:45 +0100 Subject: [PATCH 1/3] wip: receipt root --- crates/consensus/src/proofs.rs | 39 +++++++++++++++++++++++++- crates/consensus/src/receipt/status.rs | 6 ++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/crates/consensus/src/proofs.rs b/crates/consensus/src/proofs.rs index a4e2ab666c3..24688fff9dd 100644 --- a/crates/consensus/src/proofs.rs +++ b/crates/consensus/src/proofs.rs @@ -1,6 +1,6 @@ //! Helper function for calculating Merkle proofs and hashes. -use crate::{Header, EMPTY_OMMER_ROOT_HASH}; +use crate::{Header, ReceiptWithBloom, RlpReceipt, EMPTY_OMMER_ROOT_HASH}; use alloc::vec::Vec; use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawal}; use alloy_primitives::{keccak256, B256}; @@ -32,3 +32,40 @@ pub fn calculate_ommers_root(ommers: &[Header]) -> B256 { alloy_rlp::encode_list(ommers, &mut ommers_rlp); keccak256(ommers_rlp) } + + +/// Calculates the receipt root for a header. +pub fn calculate_receipt_root(receipts: &[ReceiptWithBloom]) -> B256 +where T: Encodable2718 +{ + // TODO - Implement this function according to https://github.com/paradigmxyz/reth/blob/b09c345257cda4a88e8e347654e946a20f9e5cb7/crates/primitives/src/proofs.rs#L27-L27 + // ordered_trie_root_with_encoder(receipts, |r, buf| r.encode_inner(buf, false)) + todo!() +} + + +#[cfg(test)] +mod tests { + use super::*; + use alloy_primitives::{bloom, Address, Log, LogData}; + use crate::{Eip658Value, Receipt}; + + 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: Receipt { + status: Eip658Value::success(), + cumulative_gas_used: 102068, + logs, + }, + logs_bloom, + }; + let receipt = vec![receipt]; + // let root = calculate_receipt_root(&receipt); + // assert_eq!(root, b256!("fe70ae4a136d98944951b2123859698d59ad251a381abc9960fa81cae3d0d4a0")); + } +} \ No newline at end of file diff --git a/crates/consensus/src/receipt/status.rs b/crates/consensus/src/receipt/status.rs index 9cbddfdb581..2aacf53d225 100644 --- a/crates/consensus/src/receipt/status.rs +++ b/crates/consensus/src/receipt/status.rs @@ -16,6 +16,12 @@ 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]. /// From 9428946a9226be8e382cb7d0b809b902e637202c Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 2 Dec 2024 18:19:46 +0400 Subject: [PATCH 2/3] wip --- crates/consensus/src/proofs.rs | 99 +++++++++++++++++++++----- crates/consensus/src/receipt/status.rs | 1 - 2 files changed, 81 insertions(+), 19 deletions(-) diff --git a/crates/consensus/src/proofs.rs b/crates/consensus/src/proofs.rs index 24688fff9dd..6af378bcb33 100644 --- a/crates/consensus/src/proofs.rs +++ b/crates/consensus/src/proofs.rs @@ -1,6 +1,6 @@ //! Helper function for calculating Merkle proofs and hashes. -use crate::{Header, ReceiptWithBloom, RlpReceipt, EMPTY_OMMER_ROOT_HASH}; +use crate::{Header, EMPTY_OMMER_ROOT_HASH}; use alloc::vec::Vec; use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawal}; use alloy_primitives::{keccak256, B256}; @@ -33,23 +33,83 @@ pub fn calculate_ommers_root(ommers: &[Header]) -> B256 { keccak256(ommers_rlp) } - -/// Calculates the receipt root for a header. -pub fn calculate_receipt_root(receipts: &[ReceiptWithBloom]) -> B256 -where T: Encodable2718 +/// Calculates the receipt root. +pub fn calculate_receipt_root(receipts: &[T]) -> B256 +where + T: Encodable2718, { - // TODO - Implement this function according to https://github.com/paradigmxyz/reth/blob/b09c345257cda4a88e8e347654e946a20f9e5cb7/crates/primitives/src/proofs.rs#L27-L27 - // ordered_trie_root_with_encoder(receipts, |r, buf| r.encode_inner(buf, false)) - todo!() + ordered_trie_root_with_encoder(receipts, |r, buf| r.encode_2718(buf)) } - #[cfg(test)] mod tests { use super::*; - use alloy_primitives::{bloom, Address, Log, LogData}; - use crate::{Eip658Value, Receipt}; + 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, @@ -57,15 +117,18 @@ mod tests { }]; let logs_bloom = bloom!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"); let receipt = ReceiptWithBloom { - receipt: Receipt { - status: Eip658Value::success(), - cumulative_gas_used: 102068, - logs, + 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")); + let root = calculate_receipt_root(&receipt); + assert_eq!(root, b256!("fe70ae4a136d98944951b2123859698d59ad251a381abc9960fa81cae3d0d4a0")); } -} \ No newline at end of file +} diff --git a/crates/consensus/src/receipt/status.rs b/crates/consensus/src/receipt/status.rs index 2aacf53d225..afbe1bd4111 100644 --- a/crates/consensus/src/receipt/status.rs +++ b/crates/consensus/src/receipt/status.rs @@ -16,7 +16,6 @@ pub enum Eip658Value { } impl Eip658Value { - /// Returns a successful transaction status. pub const fn success() -> Self { Self::Eip658(true) From f0ac5c0730c5275b9d5fbb2a9a9115b8028eefed Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 2 Dec 2024 18:23:28 +0400 Subject: [PATCH 3/3] add auto_impl --- crates/consensus/src/receipt/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/consensus/src/receipt/mod.rs b/crates/consensus/src/receipt/mod.rs index 3249a5cd5e1..f45a84c34f1 100644 --- a/crates/consensus/src/receipt/mod.rs +++ b/crates/consensus/src/receipt/mod.rs @@ -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;