mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: unify ReceiptWithBloom from Alloy (#13088)
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
This commit is contained in:
committed by
GitHub
parent
55f931d0b9
commit
cd13bd91cd
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -8351,6 +8351,7 @@ name = "reth-optimism-consensus"
|
||||
version = "1.1.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
"alloy-primitives",
|
||||
"alloy-trie",
|
||||
"reth-chainspec",
|
||||
@ -9455,6 +9456,7 @@ name = "reth-trie"
|
||||
version = "1.1.2"
|
||||
dependencies = [
|
||||
"alloy-consensus",
|
||||
"alloy-eips",
|
||||
"alloy-primitives",
|
||||
"alloy-rlp",
|
||||
"alloy-trie",
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use alloy_consensus::{proofs::calculate_receipt_root, TxReceipt};
|
||||
use alloy_eips::eip7685::Requests;
|
||||
use alloy_primitives::{Bloom, B256};
|
||||
use reth_chainspec::EthereumHardforks;
|
||||
@ -62,10 +63,10 @@ fn verify_receipts(
|
||||
) -> Result<(), ConsensusError> {
|
||||
// Calculate receipts root.
|
||||
let receipts_with_bloom = receipts.iter().map(Receipt::with_bloom_ref).collect::<Vec<_>>();
|
||||
let receipts_root = reth_primitives::proofs::calculate_receipt_root_ref(&receipts_with_bloom);
|
||||
let receipts_root = calculate_receipt_root(&receipts_with_bloom);
|
||||
|
||||
// Calculate header logs bloom.
|
||||
let logs_bloom = receipts_with_bloom.iter().fold(Bloom::ZERO, |bloom, r| bloom | r.bloom);
|
||||
let logs_bloom = receipts_with_bloom.iter().fold(Bloom::ZERO, |bloom, r| bloom | r.bloom());
|
||||
|
||||
compare_receipts_root_and_logs_bloom(
|
||||
receipts_root,
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
use alloy_primitives::B256;
|
||||
use alloy_rlp::{RlpDecodableWrapper, RlpEncodableWrapper};
|
||||
use reth_codecs_derive::add_arbitrary_tests;
|
||||
use reth_primitives::ReceiptWithBloom;
|
||||
use reth_primitives::{Receipt, ReceiptWithBloom};
|
||||
|
||||
/// A request for transaction receipts from the given block hashes.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, RlpEncodableWrapper, RlpDecodableWrapper, Default)]
|
||||
@ -23,7 +23,7 @@ pub struct GetReceipts(
|
||||
#[add_arbitrary_tests(rlp)]
|
||||
pub struct Receipts(
|
||||
/// Each receipt hash should correspond to a block hash in the request.
|
||||
pub Vec<Vec<ReceiptWithBloom>>,
|
||||
pub Vec<Vec<ReceiptWithBloom<Receipt>>>,
|
||||
);
|
||||
|
||||
#[cfg(test)]
|
||||
@ -37,7 +37,7 @@ mod tests {
|
||||
fn roundtrip_eip1559() {
|
||||
let receipts = Receipts(vec![vec![ReceiptWithBloom {
|
||||
receipt: Receipt { tx_type: TxType::Eip1559, ..Default::default() },
|
||||
bloom: Default::default(),
|
||||
logs_bloom: Default::default(),
|
||||
}]]);
|
||||
|
||||
let mut out = vec![];
|
||||
@ -108,7 +108,7 @@ mod tests {
|
||||
success: false,
|
||||
..Default::default()
|
||||
},
|
||||
bloom: hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into(),
|
||||
logs_bloom: hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into(),
|
||||
},
|
||||
]]),
|
||||
};
|
||||
@ -145,7 +145,7 @@ mod tests {
|
||||
success: false,
|
||||
..Default::default()
|
||||
},
|
||||
bloom: hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into(),
|
||||
logs_bloom: hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into(),
|
||||
},
|
||||
],
|
||||
]),
|
||||
|
||||
@ -150,7 +150,7 @@ pub enum PeerResponseResult<N: NetworkPrimitives = EthNetworkPrimitives> {
|
||||
/// Represents a result containing node data or an error.
|
||||
NodeData(RequestResult<Vec<Bytes>>),
|
||||
/// Represents a result containing receipts or an error.
|
||||
Receipts(RequestResult<Vec<Vec<ReceiptWithBloom>>>),
|
||||
Receipts(RequestResult<Vec<Vec<ReceiptWithBloom<reth_primitives::Receipt>>>>),
|
||||
}
|
||||
|
||||
// === impl PeerResponseResult ===
|
||||
|
||||
@ -26,6 +26,7 @@ reth-optimism-chainspec.workspace = true
|
||||
reth-optimism-primitives = { workspace = true, features = ["serde"] }
|
||||
|
||||
# ethereum
|
||||
alloy-eips.workspace = true
|
||||
alloy-primitives.workspace = true
|
||||
alloy-consensus.workspace = true
|
||||
alloy-trie.workspace = true
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
//! Helper function for Receipt root calculation for Optimism hardforks.
|
||||
|
||||
use alloy_eips::eip2718::Encodable2718;
|
||||
use alloy_primitives::B256;
|
||||
use alloy_trie::root::ordered_trie_root_with_encoder;
|
||||
use reth_chainspec::ChainSpec;
|
||||
use reth_optimism_forks::OpHardfork;
|
||||
use reth_primitives::{Receipt, ReceiptWithBloom, ReceiptWithBloomRef};
|
||||
use reth_primitives::{Receipt, ReceiptWithBloom};
|
||||
|
||||
/// Calculates the receipt root for a header.
|
||||
pub(crate) fn calculate_receipt_root_optimism(
|
||||
receipts: &[ReceiptWithBloom],
|
||||
receipts: &[ReceiptWithBloom<Receipt>],
|
||||
chain_spec: &ChainSpec,
|
||||
timestamp: u64,
|
||||
) -> B256 {
|
||||
@ -29,12 +30,10 @@ pub(crate) fn calculate_receipt_root_optimism(
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
return ordered_trie_root_with_encoder(receipts.as_slice(), |r, buf| {
|
||||
r.encode_inner(buf, false)
|
||||
})
|
||||
return ordered_trie_root_with_encoder(receipts.as_slice(), |r, buf| r.encode_2718(buf))
|
||||
}
|
||||
|
||||
ordered_trie_root_with_encoder(receipts, |r, buf| r.encode_inner(buf, false))
|
||||
ordered_trie_root_with_encoder(receipts, |r, buf| r.encode_2718(buf))
|
||||
}
|
||||
|
||||
/// Calculates the receipt root for a header for the reference type of [Receipt].
|
||||
@ -63,12 +62,12 @@ pub fn calculate_receipt_root_no_memo_optimism(
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
return ordered_trie_root_with_encoder(&receipts, |r, buf| {
|
||||
ReceiptWithBloomRef::from(r).encode_inner(buf, false)
|
||||
r.with_bloom_ref().encode_2718(buf);
|
||||
})
|
||||
}
|
||||
|
||||
ordered_trie_root_with_encoder(receipts, |r, buf| {
|
||||
ReceiptWithBloomRef::from(*r).encode_inner(buf, false)
|
||||
r.with_bloom_ref().encode_2718(buf);
|
||||
})
|
||||
}
|
||||
|
||||
@ -123,7 +122,7 @@ mod tests {
|
||||
deposit_nonce: Some(4012991u64),
|
||||
deposit_receipt_version: None,
|
||||
},
|
||||
bloom: Bloom(hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into()),
|
||||
logs_bloom: Bloom(hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into()),
|
||||
},
|
||||
// 0x2f433586bae30573c393adfa02bc81d2a1888a3d6c9869f473fb57245166bd9a
|
||||
ReceiptWithBloom {
|
||||
@ -169,7 +168,7 @@ mod tests {
|
||||
deposit_nonce: None,
|
||||
deposit_receipt_version: None,
|
||||
},
|
||||
bloom: Bloom(hex!("00001000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000040000000000004000000000080000000000000000000000000000000000000000000000000000008000000000000080020000000000000000000000000002000000000000000000000000000080000010000").into()),
|
||||
logs_bloom: Bloom(hex!("00001000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000040000000000004000000000080000000000000000000000000000000000000000000000000000008000000000000080020000000000000000000000000002000000000000000000000000000080000010000").into()),
|
||||
},
|
||||
// 0x6c33676e8f6077f46a62eabab70bc6d1b1b18a624b0739086d77093a1ecf8266
|
||||
ReceiptWithBloom {
|
||||
@ -211,7 +210,7 @@ mod tests {
|
||||
deposit_nonce: None,
|
||||
deposit_receipt_version: None,
|
||||
},
|
||||
bloom: Bloom(hex!("00000000000000000000200000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000002000000000020000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000040000000000004000000000080000000000000000000000000000000000000000000000000000008000000000000080020000000000000000000000000002000000000000000000000000000080000000000").into()),
|
||||
logs_bloom: Bloom(hex!("00000000000000000000200000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000002000000000020000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000040000000000004000000000080000000000000000000000000000000000000000000000000000008000000000000080020000000000000000000000000002000000000000000000000000000080000000000").into()),
|
||||
},
|
||||
// 0x4d3ecbef04ba7ce7f5ab55be0c61978ca97c117d7da448ed9771d4ff0c720a3f
|
||||
ReceiptWithBloom {
|
||||
@ -283,7 +282,7 @@ mod tests {
|
||||
deposit_nonce: None,
|
||||
deposit_receipt_version: None,
|
||||
},
|
||||
bloom: Bloom(hex!("00200000000000000000000080000000000000000000000000040000100004000000000000000000000000100000000000000000000000000000100000000000000000000000000002000008000000200000000200000000020000000000000040000000000000000400000200000000000000000000000000000010000000000400000000010400000000000000000000000000002000c80000004080002000000000000000400200000000800000000000000000000000000000000000000000000002000000000000000000000000000000000100001000000000000000000000002000000000000000000000010000000000000000000000800000800000").into()),
|
||||
logs_bloom: Bloom(hex!("00200000000000000000000080000000000000000000000000040000100004000000000000000000000000100000000000000000000000000000100000000000000000000000000002000008000000200000000200000000020000000000000040000000000000000400000200000000000000000000000000000010000000000400000000010400000000000000000000000000002000c80000004080002000000000000000400200000000800000000000000000000000000000000000000000000002000000000000000000000000000000000100001000000000000000000000002000000000000000000000010000000000000000000000800000800000").into()),
|
||||
},
|
||||
// 0xf738af5eb00ba23dbc1be2dbce41dbc0180f0085b7fb46646e90bf737af90351
|
||||
ReceiptWithBloom {
|
||||
@ -325,7 +324,7 @@ mod tests {
|
||||
deposit_nonce: None,
|
||||
deposit_receipt_version: None,
|
||||
},
|
||||
bloom: Bloom(hex!("00000000000000000000000000000000400000000000000000000000000000000000004000000000000001000000000000000002000000000100000000000000000000000000000000000008000000000000000000000000000000000000000004000000020000000000000000000800000000000000000000000010200100200008000002000000000000000000800000000000000000000002000000000000000000000000000000080000000000000000000000004000000000000000000000000002000000000000000000000000000000000000200000000000000020002000000000000000002000000000000000000000000000000000000000000000").into()),
|
||||
logs_bloom: Bloom(hex!("00000000000000000000000000000000400000000000000000000000000000000000004000000000000001000000000000000002000000000100000000000000000000000000000000000008000000000000000000000000000000000000000004000000020000000000000000000800000000000000000000000010200100200008000002000000000000000000800000000000000000000002000000000000000000000000000000080000000000000000000000004000000000000000000000000002000000000000000000000000000000000000200000000000000020002000000000000000002000000000000000000000000000000000000000000000").into()),
|
||||
},
|
||||
];
|
||||
let root = calculate_receipt_root_optimism(&receipts, BASE_SEPOLIA.as_ref(), case.1);
|
||||
@ -339,7 +338,7 @@ mod tests {
|
||||
address: Address::ZERO,
|
||||
data: LogData::new_unchecked(vec![], Default::default()),
|
||||
}];
|
||||
let bloom = bloom!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
|
||||
let logs_bloom = bloom!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001");
|
||||
let receipt = ReceiptWithBloom {
|
||||
receipt: Receipt {
|
||||
tx_type: TxType::Eip2930,
|
||||
@ -349,7 +348,7 @@ mod tests {
|
||||
deposit_nonce: None,
|
||||
deposit_receipt_version: None,
|
||||
},
|
||||
bloom,
|
||||
logs_bloom,
|
||||
};
|
||||
let receipt = vec![receipt];
|
||||
let root = calculate_receipt_root_optimism(&receipt, BASE_SEPOLIA.as_ref(), 0);
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use crate::proof::calculate_receipt_root_optimism;
|
||||
use alloy_consensus::TxReceipt;
|
||||
use alloy_primitives::{Bloom, B256};
|
||||
use reth_chainspec::{ChainSpec, EthereumHardforks};
|
||||
use reth_consensus::ConsensusError;
|
||||
@ -57,7 +58,7 @@ fn verify_receipts(
|
||||
calculate_receipt_root_optimism(&receipts_with_bloom, chain_spec, timestamp);
|
||||
|
||||
// Calculate header logs bloom.
|
||||
let logs_bloom = receipts_with_bloom.iter().fold(Bloom::ZERO, |bloom, r| bloom | r.bloom);
|
||||
let logs_bloom = receipts_with_bloom.iter().fold(Bloom::ZERO, |bloom, r| bloom | r.bloom());
|
||||
|
||||
compare_receipts_root_and_logs_bloom(
|
||||
receipts_root,
|
||||
|
||||
@ -40,9 +40,7 @@ pub use block::{
|
||||
};
|
||||
#[cfg(feature = "reth-codec")]
|
||||
pub use compression::*;
|
||||
pub use receipt::{
|
||||
gas_spent_by_transactions, Receipt, ReceiptWithBloom, ReceiptWithBloomRef, Receipts,
|
||||
};
|
||||
pub use receipt::{gas_spent_by_transactions, Receipt, Receipts};
|
||||
pub use reth_primitives_traits::{
|
||||
logs_bloom, Account, Bytecode, GotExpected, GotExpectedBoxed, Header, HeaderError, Log,
|
||||
LogData, NodePrimitives, SealedHeader, StorageEntry,
|
||||
@ -56,6 +54,8 @@ pub use transaction::{
|
||||
TransactionSigned, TransactionSignedEcRecovered, TxType,
|
||||
};
|
||||
|
||||
pub use alloy_consensus::ReceiptWithBloom;
|
||||
|
||||
// Re-exports
|
||||
pub use reth_ethereum_forks::*;
|
||||
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
//! Helper function for calculating Merkle proofs and hashes.
|
||||
|
||||
use crate::{Receipt, ReceiptWithBloom, ReceiptWithBloomRef};
|
||||
use crate::Receipt;
|
||||
use alloy_eips::eip2718::Encodable2718;
|
||||
use alloy_primitives::B256;
|
||||
use alloy_trie::root::ordered_trie_root_with_encoder;
|
||||
|
||||
pub use alloy_consensus::proofs::calculate_receipt_root;
|
||||
|
||||
/// Calculate a transaction root.
|
||||
///
|
||||
/// `(rlp(index), encoded(tx))` pairs.
|
||||
@ -18,23 +21,11 @@ pub use alloy_consensus::proofs::calculate_withdrawals_root;
|
||||
#[doc(inline)]
|
||||
pub use alloy_consensus::proofs::calculate_ommers_root;
|
||||
|
||||
/// Calculates the receipt root for a header.
|
||||
pub fn calculate_receipt_root(receipts: &[ReceiptWithBloom]) -> B256 {
|
||||
ordered_trie_root_with_encoder(receipts, |r, buf| r.encode_inner(buf, false))
|
||||
}
|
||||
|
||||
/// Calculates the receipt root for a header.
|
||||
pub fn calculate_receipt_root_ref(receipts: &[ReceiptWithBloomRef<'_>]) -> B256 {
|
||||
ordered_trie_root_with_encoder(receipts, |r, buf| r.encode_inner(buf, false))
|
||||
}
|
||||
|
||||
/// Calculates the receipt root for a header for the reference type of [Receipt].
|
||||
///
|
||||
/// NOTE: Prefer [`calculate_receipt_root`] if you have log blooms memoized.
|
||||
pub fn calculate_receipt_root_no_memo(receipts: &[&Receipt]) -> B256 {
|
||||
ordered_trie_root_with_encoder(receipts, |r, buf| {
|
||||
ReceiptWithBloomRef::from(*r).encode_inner(buf, false)
|
||||
})
|
||||
ordered_trie_root_with_encoder(receipts, |r, buf| r.with_bloom_ref().encode_2718(buf))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -67,6 +58,8 @@ mod tests {
|
||||
#[cfg(not(feature = "optimism"))]
|
||||
#[test]
|
||||
fn check_receipt_root_optimism() {
|
||||
use alloy_consensus::ReceiptWithBloom;
|
||||
|
||||
let logs = vec![Log {
|
||||
address: Address::ZERO,
|
||||
data: LogData::new_unchecked(vec![], Default::default()),
|
||||
@ -79,7 +72,7 @@ mod tests {
|
||||
cumulative_gas_used: 102068,
|
||||
logs,
|
||||
},
|
||||
bloom,
|
||||
logs_bloom: bloom,
|
||||
};
|
||||
let receipt = vec![receipt];
|
||||
let root = calculate_receipt_root(&receipt);
|
||||
|
||||
@ -1,15 +1,13 @@
|
||||
use alloc::{vec, vec::Vec};
|
||||
use core::cmp::Ordering;
|
||||
use reth_primitives_traits::InMemorySize;
|
||||
|
||||
use alloy_consensus::{
|
||||
constants::{EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID, EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID},
|
||||
Eip658Value, TxReceipt, Typed2718,
|
||||
Eip2718EncodableReceipt, Eip658Value, ReceiptWithBloom, RlpDecodableReceipt,
|
||||
RlpEncodableReceipt, TxReceipt, Typed2718,
|
||||
};
|
||||
use alloy_eips::eip2718::Encodable2718;
|
||||
use alloy_primitives::{Bloom, Log, B256};
|
||||
use alloy_rlp::{length_of_length, Decodable, Encodable, RlpDecodable, RlpEncodable};
|
||||
use bytes::{Buf, BufMut};
|
||||
use alloy_rlp::{Decodable, Encodable, Header, RlpDecodable, RlpEncodable};
|
||||
use bytes::BufMut;
|
||||
use derive_more::{DerefMut, From, IntoIterator};
|
||||
use reth_primitives_traits::receipt::ReceiptExt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -61,15 +59,180 @@ impl Receipt {
|
||||
|
||||
/// 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<Self> {
|
||||
self.into()
|
||||
}
|
||||
|
||||
/// Calculates the bloom filter for the receipt and returns the [`ReceiptWithBloomRef`]
|
||||
/// Calculates the bloom filter for the receipt and returns the [`ReceiptWithBloom`]
|
||||
/// container type.
|
||||
pub fn with_bloom_ref(&self) -> ReceiptWithBloomRef<'_> {
|
||||
pub fn with_bloom_ref(&self) -> ReceiptWithBloom<&Self> {
|
||||
self.into()
|
||||
}
|
||||
|
||||
/// Returns length of RLP-encoded receipt fields with the given [`Bloom`] without an RLP header.
|
||||
pub fn rlp_encoded_fields_length(&self, bloom: &Bloom) -> usize {
|
||||
let len = self.success.length() +
|
||||
self.cumulative_gas_used.length() +
|
||||
bloom.length() +
|
||||
self.logs.length();
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
if self.tx_type == TxType::Deposit {
|
||||
let mut len = len;
|
||||
|
||||
if let Some(deposit_nonce) = self.deposit_nonce {
|
||||
len += deposit_nonce.length();
|
||||
}
|
||||
if let Some(deposit_receipt_version) = self.deposit_receipt_version {
|
||||
len += deposit_receipt_version.length();
|
||||
}
|
||||
|
||||
return len
|
||||
}
|
||||
|
||||
len
|
||||
}
|
||||
|
||||
/// RLP-encodes receipt fields with the given [`Bloom`] without an RLP header.
|
||||
pub fn rlp_encode_fields(&self, bloom: &Bloom, out: &mut dyn BufMut) {
|
||||
self.success.encode(out);
|
||||
self.cumulative_gas_used.encode(out);
|
||||
bloom.encode(out);
|
||||
self.logs.encode(out);
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
if self.tx_type == TxType::Deposit {
|
||||
if let Some(nonce) = self.deposit_nonce {
|
||||
nonce.encode(out);
|
||||
}
|
||||
if let Some(version) = self.deposit_receipt_version {
|
||||
version.encode(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns RLP header for inner encoding.
|
||||
pub fn rlp_header_inner(&self, bloom: &Bloom) -> Header {
|
||||
Header { list: true, payload_length: self.rlp_encoded_fields_length(bloom) }
|
||||
}
|
||||
|
||||
fn decode_receipt_with_bloom(
|
||||
buf: &mut &[u8],
|
||||
tx_type: TxType,
|
||||
) -> alloy_rlp::Result<ReceiptWithBloom<Self>> {
|
||||
let b = &mut &**buf;
|
||||
let rlp_head = alloy_rlp::Header::decode(b)?;
|
||||
if !rlp_head.list {
|
||||
return Err(alloy_rlp::Error::UnexpectedString)
|
||||
}
|
||||
let started_len = b.len();
|
||||
|
||||
let success = Decodable::decode(b)?;
|
||||
let cumulative_gas_used = Decodable::decode(b)?;
|
||||
let bloom = Decodable::decode(b)?;
|
||||
let logs = Decodable::decode(b)?;
|
||||
|
||||
let receipt = match tx_type {
|
||||
#[cfg(feature = "optimism")]
|
||||
TxType::Deposit => {
|
||||
let remaining = |b: &[u8]| rlp_head.payload_length - (started_len - b.len()) > 0;
|
||||
let deposit_nonce = remaining(b).then(|| Decodable::decode(b)).transpose()?;
|
||||
let deposit_receipt_version =
|
||||
remaining(b).then(|| Decodable::decode(b)).transpose()?;
|
||||
|
||||
Self {
|
||||
tx_type,
|
||||
success,
|
||||
cumulative_gas_used,
|
||||
logs,
|
||||
deposit_nonce,
|
||||
deposit_receipt_version,
|
||||
}
|
||||
}
|
||||
_ => Self {
|
||||
tx_type,
|
||||
success,
|
||||
cumulative_gas_used,
|
||||
logs,
|
||||
#[cfg(feature = "optimism")]
|
||||
deposit_nonce: None,
|
||||
#[cfg(feature = "optimism")]
|
||||
deposit_receipt_version: None,
|
||||
},
|
||||
};
|
||||
|
||||
let this = ReceiptWithBloom { receipt, logs_bloom: bloom };
|
||||
let consumed = started_len - b.len();
|
||||
if consumed != rlp_head.payload_length {
|
||||
return Err(alloy_rlp::Error::ListLengthMismatch {
|
||||
expected: rlp_head.payload_length,
|
||||
got: consumed,
|
||||
})
|
||||
}
|
||||
*buf = *b;
|
||||
Ok(this)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eip2718EncodableReceipt for Receipt {
|
||||
fn eip2718_encoded_length_with_bloom(&self, bloom: &Bloom) -> usize {
|
||||
self.rlp_header_inner(bloom).length_with_payload() +
|
||||
!matches!(self.tx_type, TxType::Legacy) as usize // account for type prefix
|
||||
}
|
||||
|
||||
fn eip2718_encode_with_bloom(&self, bloom: &Bloom, out: &mut dyn BufMut) {
|
||||
if !matches!(self.tx_type, TxType::Legacy) {
|
||||
out.put_u8(self.tx_type as u8);
|
||||
}
|
||||
self.rlp_header_inner(bloom).encode(out);
|
||||
self.rlp_encode_fields(bloom, out);
|
||||
}
|
||||
}
|
||||
|
||||
impl RlpEncodableReceipt for Receipt {
|
||||
fn rlp_encoded_length_with_bloom(&self, bloom: &Bloom) -> usize {
|
||||
let mut len = self.eip2718_encoded_length_with_bloom(bloom);
|
||||
if !matches!(self.tx_type, TxType::Legacy) {
|
||||
len += Header {
|
||||
list: false,
|
||||
payload_length: self.eip2718_encoded_length_with_bloom(bloom),
|
||||
}
|
||||
.length();
|
||||
}
|
||||
|
||||
len
|
||||
}
|
||||
|
||||
fn rlp_encode_with_bloom(&self, bloom: &Bloom, out: &mut dyn BufMut) {
|
||||
if !matches!(self.tx_type, TxType::Legacy) {
|
||||
Header { list: false, payload_length: self.eip2718_encoded_length_with_bloom(bloom) }
|
||||
.encode(out);
|
||||
}
|
||||
self.eip2718_encode_with_bloom(bloom, out);
|
||||
}
|
||||
}
|
||||
|
||||
impl RlpDecodableReceipt for Receipt {
|
||||
fn rlp_decode_with_bloom(buf: &mut &[u8]) -> alloy_rlp::Result<ReceiptWithBloom<Self>> {
|
||||
let header_buf = &mut &**buf;
|
||||
let header = Header::decode(header_buf)?;
|
||||
|
||||
if header.list {
|
||||
return Self::decode_receipt_with_bloom(buf, TxType::Legacy);
|
||||
}
|
||||
|
||||
*buf = *header_buf;
|
||||
|
||||
let remaining = buf.len();
|
||||
let tx_type = TxType::decode(buf)?;
|
||||
let this = Self::decode_receipt_with_bloom(buf, tx_type)?;
|
||||
|
||||
if buf.len() + header.payload_length != remaining {
|
||||
return Err(alloy_rlp::Error::UnexpectedLength);
|
||||
}
|
||||
|
||||
Ok(this)
|
||||
}
|
||||
}
|
||||
|
||||
impl TxReceipt for Receipt {
|
||||
@ -183,51 +346,12 @@ impl<T> FromIterator<Vec<Option<T>>> for Receipts<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Receipt> for ReceiptWithBloom {
|
||||
fn from(receipt: Receipt) -> Self {
|
||||
let bloom = receipt.bloom_slow();
|
||||
Self { receipt, bloom }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Default for Receipts<T> {
|
||||
fn default() -> Self {
|
||||
Self { receipt_vec: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
/// [`Receipt`] with calculated bloom filter.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize)]
|
||||
#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
|
||||
pub struct ReceiptWithBloom {
|
||||
/// Bloom filter build from logs.
|
||||
pub bloom: Bloom,
|
||||
/// Main receipt body
|
||||
pub receipt: Receipt,
|
||||
}
|
||||
|
||||
impl ReceiptWithBloom {
|
||||
/// Create new [`ReceiptWithBloom`]
|
||||
pub const fn new(receipt: Receipt, bloom: Bloom) -> Self {
|
||||
Self { receipt, bloom }
|
||||
}
|
||||
|
||||
/// Consume the structure, returning only the receipt
|
||||
pub fn into_receipt(self) -> Receipt {
|
||||
self.receipt
|
||||
}
|
||||
|
||||
/// Consume the structure, returning the receipt and the bloom filter
|
||||
pub fn into_components(self) -> (Receipt, Bloom) {
|
||||
(self.receipt, self.bloom)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
const fn as_encoder(&self) -> ReceiptWithBloomEncoder<'_> {
|
||||
ReceiptWithBloomEncoder { receipt: &self.receipt, bloom: &self.bloom }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
impl<'a> arbitrary::Arbitrary<'a> for Receipt {
|
||||
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
@ -260,317 +384,10 @@ impl<'a> arbitrary::Arbitrary<'a> for Receipt {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable2718 for ReceiptWithBloom {
|
||||
fn type_flag(&self) -> Option<u8> {
|
||||
match self.receipt.tx_type {
|
||||
TxType::Legacy => None,
|
||||
tx_type => Some(tx_type as u8),
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_2718_len(&self) -> usize {
|
||||
let encoder = self.as_encoder();
|
||||
match self.receipt.tx_type {
|
||||
TxType::Legacy => encoder.receipt_length(),
|
||||
_ => 1 + encoder.receipt_length(), // 1 byte for the type prefix
|
||||
}
|
||||
}
|
||||
|
||||
/// Encodes the receipt into its "raw" format.
|
||||
/// This format is also referred to as "binary" encoding.
|
||||
///
|
||||
/// For legacy receipts, it encodes the RLP of the receipt into the buffer:
|
||||
/// `rlp([status, cumulativeGasUsed, logsBloom, logs])` as per EIP-2718.
|
||||
/// For EIP-2718 typed transactions, it encodes the type of the transaction followed by the rlp
|
||||
/// of the receipt:
|
||||
/// - EIP-1559, 2930 and 4844 transactions: `tx-type || rlp([status, cumulativeGasUsed,
|
||||
/// logsBloom, logs])`
|
||||
fn encode_2718(&self, out: &mut dyn BufMut) {
|
||||
self.encode_inner(out, false)
|
||||
}
|
||||
|
||||
fn encoded_2718(&self) -> Vec<u8> {
|
||||
let mut out = vec![];
|
||||
self.encode_2718(&mut out);
|
||||
out
|
||||
}
|
||||
}
|
||||
|
||||
impl ReceiptWithBloom {
|
||||
/// Encode receipt with or without the header data.
|
||||
pub fn encode_inner(&self, out: &mut dyn BufMut, with_header: bool) {
|
||||
self.as_encoder().encode_inner(out, with_header)
|
||||
}
|
||||
|
||||
/// Decodes the receipt payload
|
||||
fn decode_receipt(buf: &mut &[u8], tx_type: TxType) -> alloy_rlp::Result<Self> {
|
||||
let b = &mut &**buf;
|
||||
let rlp_head = alloy_rlp::Header::decode(b)?;
|
||||
if !rlp_head.list {
|
||||
return Err(alloy_rlp::Error::UnexpectedString)
|
||||
}
|
||||
let started_len = b.len();
|
||||
|
||||
let success = alloy_rlp::Decodable::decode(b)?;
|
||||
let cumulative_gas_used = alloy_rlp::Decodable::decode(b)?;
|
||||
let bloom = Decodable::decode(b)?;
|
||||
let logs = alloy_rlp::Decodable::decode(b)?;
|
||||
|
||||
let receipt = match tx_type {
|
||||
#[cfg(feature = "optimism")]
|
||||
TxType::Deposit => {
|
||||
let remaining = |b: &[u8]| rlp_head.payload_length - (started_len - b.len()) > 0;
|
||||
let deposit_nonce =
|
||||
remaining(b).then(|| alloy_rlp::Decodable::decode(b)).transpose()?;
|
||||
let deposit_receipt_version =
|
||||
remaining(b).then(|| alloy_rlp::Decodable::decode(b)).transpose()?;
|
||||
|
||||
Receipt {
|
||||
tx_type,
|
||||
success,
|
||||
cumulative_gas_used,
|
||||
logs,
|
||||
deposit_nonce,
|
||||
deposit_receipt_version,
|
||||
}
|
||||
}
|
||||
_ => Receipt {
|
||||
tx_type,
|
||||
success,
|
||||
cumulative_gas_used,
|
||||
logs,
|
||||
#[cfg(feature = "optimism")]
|
||||
deposit_nonce: None,
|
||||
#[cfg(feature = "optimism")]
|
||||
deposit_receipt_version: None,
|
||||
},
|
||||
};
|
||||
|
||||
let this = Self { receipt, bloom };
|
||||
let consumed = started_len - b.len();
|
||||
if consumed != rlp_head.payload_length {
|
||||
return Err(alloy_rlp::Error::ListLengthMismatch {
|
||||
expected: rlp_head.payload_length,
|
||||
got: consumed,
|
||||
})
|
||||
}
|
||||
*buf = *b;
|
||||
Ok(this)
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for ReceiptWithBloom {
|
||||
fn encode(&self, out: &mut dyn BufMut) {
|
||||
self.encode_inner(out, true)
|
||||
}
|
||||
fn length(&self) -> usize {
|
||||
self.as_encoder().length()
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for ReceiptWithBloom {
|
||||
fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
|
||||
// a receipt is either encoded as a string (non legacy) or a list (legacy).
|
||||
// We should not consume the buffer if we are decoding a legacy receipt, so let's
|
||||
// check if the first byte is between 0x80 and 0xbf.
|
||||
let rlp_type = *buf
|
||||
.first()
|
||||
.ok_or(alloy_rlp::Error::Custom("cannot decode a receipt from empty bytes"))?;
|
||||
|
||||
match rlp_type.cmp(&alloy_rlp::EMPTY_LIST_CODE) {
|
||||
Ordering::Less => {
|
||||
// strip out the string header
|
||||
let _header = alloy_rlp::Header::decode(buf)?;
|
||||
let receipt_type = *buf.first().ok_or(alloy_rlp::Error::Custom(
|
||||
"typed receipt cannot be decoded from an empty slice",
|
||||
))?;
|
||||
match receipt_type {
|
||||
EIP2930_TX_TYPE_ID => {
|
||||
buf.advance(1);
|
||||
Self::decode_receipt(buf, TxType::Eip2930)
|
||||
}
|
||||
EIP1559_TX_TYPE_ID => {
|
||||
buf.advance(1);
|
||||
Self::decode_receipt(buf, TxType::Eip1559)
|
||||
}
|
||||
EIP4844_TX_TYPE_ID => {
|
||||
buf.advance(1);
|
||||
Self::decode_receipt(buf, TxType::Eip4844)
|
||||
}
|
||||
EIP7702_TX_TYPE_ID => {
|
||||
buf.advance(1);
|
||||
Self::decode_receipt(buf, TxType::Eip7702)
|
||||
}
|
||||
#[cfg(feature = "optimism")]
|
||||
op_alloy_consensus::DEPOSIT_TX_TYPE_ID => {
|
||||
buf.advance(1);
|
||||
Self::decode_receipt(buf, TxType::Deposit)
|
||||
}
|
||||
_ => Err(alloy_rlp::Error::Custom("invalid receipt type")),
|
||||
}
|
||||
}
|
||||
Ordering::Equal => {
|
||||
Err(alloy_rlp::Error::Custom("an empty list is not a valid receipt encoding"))
|
||||
}
|
||||
Ordering::Greater => Self::decode_receipt(buf, TxType::Legacy),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// [`Receipt`] reference type with calculated bloom filter.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct ReceiptWithBloomRef<'a> {
|
||||
/// Bloom filter build from logs.
|
||||
pub bloom: Bloom,
|
||||
/// Main receipt body
|
||||
pub receipt: &'a Receipt,
|
||||
}
|
||||
|
||||
impl<'a> ReceiptWithBloomRef<'a> {
|
||||
/// Create new [`ReceiptWithBloomRef`]
|
||||
pub const fn new(receipt: &'a Receipt, bloom: Bloom) -> Self {
|
||||
Self { receipt, bloom }
|
||||
}
|
||||
|
||||
/// Encode receipt with or without the header data.
|
||||
pub fn encode_inner(&self, out: &mut dyn BufMut, with_header: bool) {
|
||||
self.as_encoder().encode_inner(out, with_header)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
const fn as_encoder(&self) -> ReceiptWithBloomEncoder<'_> {
|
||||
ReceiptWithBloomEncoder { receipt: self.receipt, bloom: &self.bloom }
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for ReceiptWithBloomRef<'_> {
|
||||
fn encode(&self, out: &mut dyn BufMut) {
|
||||
self.as_encoder().encode_inner(out, true)
|
||||
}
|
||||
fn length(&self) -> usize {
|
||||
self.as_encoder().length()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Receipt> for ReceiptWithBloomRef<'a> {
|
||||
fn from(receipt: &'a Receipt) -> Self {
|
||||
let bloom = receipt.bloom_slow();
|
||||
ReceiptWithBloomRef { receipt, bloom }
|
||||
}
|
||||
}
|
||||
|
||||
struct ReceiptWithBloomEncoder<'a> {
|
||||
bloom: &'a Bloom,
|
||||
receipt: &'a Receipt,
|
||||
}
|
||||
|
||||
impl ReceiptWithBloomEncoder<'_> {
|
||||
/// Returns the rlp header for the receipt payload.
|
||||
fn receipt_rlp_header(&self) -> alloy_rlp::Header {
|
||||
let mut rlp_head = alloy_rlp::Header { list: true, payload_length: 0 };
|
||||
|
||||
rlp_head.payload_length += self.receipt.success.length();
|
||||
rlp_head.payload_length += self.receipt.cumulative_gas_used.length();
|
||||
rlp_head.payload_length += self.bloom.length();
|
||||
rlp_head.payload_length += self.receipt.logs.length();
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
if self.receipt.tx_type == TxType::Deposit {
|
||||
if let Some(deposit_nonce) = self.receipt.deposit_nonce {
|
||||
rlp_head.payload_length += deposit_nonce.length();
|
||||
}
|
||||
if let Some(deposit_receipt_version) = self.receipt.deposit_receipt_version {
|
||||
rlp_head.payload_length += deposit_receipt_version.length();
|
||||
}
|
||||
}
|
||||
|
||||
rlp_head
|
||||
}
|
||||
|
||||
/// Encodes the receipt data.
|
||||
fn encode_fields(&self, out: &mut dyn BufMut) {
|
||||
self.receipt_rlp_header().encode(out);
|
||||
self.receipt.success.encode(out);
|
||||
self.receipt.cumulative_gas_used.encode(out);
|
||||
self.bloom.encode(out);
|
||||
self.receipt.logs.encode(out);
|
||||
#[cfg(feature = "optimism")]
|
||||
if self.receipt.tx_type == TxType::Deposit {
|
||||
if let Some(deposit_nonce) = self.receipt.deposit_nonce {
|
||||
deposit_nonce.encode(out)
|
||||
}
|
||||
if let Some(deposit_receipt_version) = self.receipt.deposit_receipt_version {
|
||||
deposit_receipt_version.encode(out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Encode receipt with or without the header data.
|
||||
fn encode_inner(&self, out: &mut dyn BufMut, with_header: bool) {
|
||||
if matches!(self.receipt.tx_type, TxType::Legacy) {
|
||||
self.encode_fields(out);
|
||||
return
|
||||
}
|
||||
|
||||
let mut payload = Vec::new();
|
||||
self.encode_fields(&mut payload);
|
||||
|
||||
if with_header {
|
||||
let payload_length = payload.len() + 1;
|
||||
let header = alloy_rlp::Header { list: false, payload_length };
|
||||
header.encode(out);
|
||||
}
|
||||
|
||||
match self.receipt.tx_type {
|
||||
TxType::Legacy => unreachable!("legacy already handled"),
|
||||
|
||||
TxType::Eip2930 => {
|
||||
out.put_u8(EIP2930_TX_TYPE_ID);
|
||||
}
|
||||
TxType::Eip1559 => {
|
||||
out.put_u8(EIP1559_TX_TYPE_ID);
|
||||
}
|
||||
TxType::Eip4844 => {
|
||||
out.put_u8(EIP4844_TX_TYPE_ID);
|
||||
}
|
||||
TxType::Eip7702 => {
|
||||
out.put_u8(EIP7702_TX_TYPE_ID);
|
||||
}
|
||||
#[cfg(feature = "optimism")]
|
||||
TxType::Deposit => {
|
||||
out.put_u8(op_alloy_consensus::DEPOSIT_TX_TYPE_ID);
|
||||
}
|
||||
}
|
||||
out.put_slice(payload.as_ref());
|
||||
}
|
||||
|
||||
/// Returns the length of the receipt data.
|
||||
fn receipt_length(&self) -> usize {
|
||||
let rlp_head = self.receipt_rlp_header();
|
||||
length_of_length(rlp_head.payload_length) + rlp_head.payload_length
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for ReceiptWithBloomEncoder<'_> {
|
||||
fn encode(&self, out: &mut dyn BufMut) {
|
||||
self.encode_inner(out, true)
|
||||
}
|
||||
fn length(&self) -> usize {
|
||||
let mut payload_len = self.receipt_length();
|
||||
// account for eip-2718 type prefix and set the list
|
||||
if !matches!(self.receipt.tx_type, TxType::Legacy) {
|
||||
payload_len += 1;
|
||||
// we include a string header for typed receipts, so include the length here
|
||||
payload_len += length_of_length(payload_len);
|
||||
}
|
||||
|
||||
payload_len
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use alloy_eips::eip2718::Encodable2718;
|
||||
use alloy_primitives::{address, b256, bytes, hex_literal::hex, Bytes};
|
||||
use reth_codecs::Compact;
|
||||
|
||||
@ -610,7 +427,7 @@ mod tests {
|
||||
#[cfg(feature = "optimism")]
|
||||
deposit_receipt_version: None,
|
||||
},
|
||||
bloom: [0; 256].into(),
|
||||
logs_bloom: [0; 256].into(),
|
||||
};
|
||||
|
||||
receipt.encode(&mut data);
|
||||
@ -644,7 +461,7 @@ mod tests {
|
||||
#[cfg(feature = "optimism")]
|
||||
deposit_receipt_version: None,
|
||||
},
|
||||
bloom: [0; 256].into(),
|
||||
logs_bloom: [0; 256].into(),
|
||||
};
|
||||
|
||||
let receipt = ReceiptWithBloom::decode(&mut &data[..]).unwrap();
|
||||
@ -654,7 +471,7 @@ mod tests {
|
||||
#[cfg(feature = "optimism")]
|
||||
#[test]
|
||||
fn decode_deposit_receipt_regolith_roundtrip() {
|
||||
let data = hex!("7ef9010c0182b741b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0833d3bbf");
|
||||
let data = hex!("b901107ef9010c0182b741b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0833d3bbf");
|
||||
|
||||
// Deposit Receipt (post-regolith)
|
||||
let expected = ReceiptWithBloom {
|
||||
@ -666,21 +483,21 @@ mod tests {
|
||||
deposit_nonce: Some(4012991),
|
||||
deposit_receipt_version: None,
|
||||
},
|
||||
bloom: [0; 256].into(),
|
||||
logs_bloom: [0; 256].into(),
|
||||
};
|
||||
|
||||
let receipt = ReceiptWithBloom::decode(&mut &data[..]).unwrap();
|
||||
assert_eq!(receipt, expected);
|
||||
|
||||
let mut buf = Vec::with_capacity(data.len());
|
||||
receipt.encode_inner(&mut buf, false);
|
||||
receipt.encode(&mut buf);
|
||||
assert_eq!(buf, &data[..]);
|
||||
}
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
#[test]
|
||||
fn decode_deposit_receipt_canyon_roundtrip() {
|
||||
let data = hex!("7ef9010d0182b741b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0833d3bbf01");
|
||||
let data = hex!("b901117ef9010d0182b741b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0833d3bbf01");
|
||||
|
||||
// Deposit Receipt (post-regolith)
|
||||
let expected = ReceiptWithBloom {
|
||||
@ -692,14 +509,14 @@ mod tests {
|
||||
deposit_nonce: Some(4012991),
|
||||
deposit_receipt_version: Some(1),
|
||||
},
|
||||
bloom: [0; 256].into(),
|
||||
logs_bloom: [0; 256].into(),
|
||||
};
|
||||
|
||||
let receipt = ReceiptWithBloom::decode(&mut &data[..]).unwrap();
|
||||
assert_eq!(receipt, expected);
|
||||
|
||||
let mut buf = Vec::with_capacity(data.len());
|
||||
expected.encode_inner(&mut buf, false);
|
||||
expected.encode(&mut buf);
|
||||
assert_eq!(buf, &data[..]);
|
||||
}
|
||||
|
||||
@ -746,7 +563,7 @@ mod tests {
|
||||
#[cfg(feature = "optimism")]
|
||||
deposit_receipt_version: None,
|
||||
},
|
||||
bloom: Bloom::default(),
|
||||
logs_bloom: Bloom::default(),
|
||||
};
|
||||
|
||||
let encoded = receipt.encoded_2718();
|
||||
@ -768,7 +585,7 @@ mod tests {
|
||||
#[cfg(feature = "optimism")]
|
||||
deposit_receipt_version: None,
|
||||
},
|
||||
bloom: Bloom::default(),
|
||||
logs_bloom: Bloom::default(),
|
||||
};
|
||||
|
||||
let legacy_encoded = legacy_receipt.encoded_2718();
|
||||
|
||||
@ -217,7 +217,7 @@ pub fn build_block<T: TransactionCompat<Error: FromEthApiError>>(
|
||||
logs: call.logs.iter().map(|log| &log.inner).cloned().collect(),
|
||||
..Default::default()
|
||||
}
|
||||
.into(),
|
||||
.with_bloom(),
|
||||
);
|
||||
|
||||
calls.push(call);
|
||||
|
||||
@ -348,7 +348,6 @@ impl<F: BlindedProviderFactory> SparseStateTrie<F> {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<F> SparseStateTrie<F>
|
||||
where
|
||||
F: BlindedProviderFactory,
|
||||
|
||||
@ -23,6 +23,7 @@ reth-trie-common.workspace = true
|
||||
revm.workspace = true
|
||||
|
||||
# alloy
|
||||
alloy-eips.workspace = true
|
||||
alloy-rlp.workspace = true
|
||||
alloy-primitives.workspace = true
|
||||
alloy-consensus.workspace = true
|
||||
@ -63,6 +64,7 @@ serde = [
|
||||
"alloy-primitives/serde",
|
||||
"alloy-consensus/serde",
|
||||
"alloy-trie/serde",
|
||||
"alloy-eips/serde",
|
||||
"revm/serde",
|
||||
"reth-trie-common/serde"
|
||||
]
|
||||
|
||||
@ -3,7 +3,7 @@ use alloy_primitives::B256;
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
use proptest::{prelude::*, strategy::ValueTree, test_runner::TestRunner};
|
||||
use proptest_arbitrary_interop::arb;
|
||||
use reth_primitives::ReceiptWithBloom;
|
||||
use reth_primitives::{Receipt, ReceiptWithBloom};
|
||||
use reth_trie::triehash::KeccakHasher;
|
||||
|
||||
/// Benchmarks different implementations of the root calculation.
|
||||
@ -27,8 +27,8 @@ pub fn trie_root_benchmark(c: &mut Criterion) {
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_test_data(size: usize) -> Vec<ReceiptWithBloom> {
|
||||
prop::collection::vec(arb::<ReceiptWithBloom>(), size)
|
||||
fn generate_test_data(size: usize) -> Vec<ReceiptWithBloom<Receipt>> {
|
||||
prop::collection::vec(arb::<ReceiptWithBloom<Receipt>>(), size)
|
||||
.new_tree(&mut TestRunner::new(ProptestConfig::default()))
|
||||
.unwrap()
|
||||
.current()
|
||||
@ -43,19 +43,19 @@ criterion_main!(benches);
|
||||
|
||||
mod implementations {
|
||||
use super::*;
|
||||
use alloy_eips::eip2718::Encodable2718;
|
||||
use alloy_rlp::Encodable;
|
||||
use alloy_trie::root::adjust_index_for_rlp;
|
||||
use reth_primitives::Receipt;
|
||||
use reth_trie_common::{HashBuilder, Nibbles};
|
||||
|
||||
pub fn trie_hash_ordered_trie_root(receipts: &[ReceiptWithBloom]) -> B256 {
|
||||
triehash::ordered_trie_root::<KeccakHasher, _>(receipts.iter().map(|receipt| {
|
||||
let mut receipt_rlp = Vec::new();
|
||||
receipt.encode_inner(&mut receipt_rlp, false);
|
||||
receipt_rlp
|
||||
}))
|
||||
pub fn trie_hash_ordered_trie_root(receipts: &[ReceiptWithBloom<Receipt>]) -> B256 {
|
||||
triehash::ordered_trie_root::<KeccakHasher, _>(
|
||||
receipts.iter().map(|receipt_with_bloom| receipt_with_bloom.encoded_2718()),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn hash_builder_root(receipts: &[ReceiptWithBloom]) -> B256 {
|
||||
pub fn hash_builder_root(receipts: &[ReceiptWithBloom<Receipt>]) -> B256 {
|
||||
let mut index_buffer = Vec::new();
|
||||
let mut value_buffer = Vec::new();
|
||||
|
||||
@ -68,7 +68,7 @@ mod implementations {
|
||||
index.encode(&mut index_buffer);
|
||||
|
||||
value_buffer.clear();
|
||||
receipts[index].encode_inner(&mut value_buffer, false);
|
||||
receipts[index].encode_2718(&mut value_buffer);
|
||||
|
||||
hb.add_leaf(Nibbles::unpack(&index_buffer), &value_buffer);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user