feat: unify ReceiptWithBloom from Alloy (#13088)

Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
This commit is contained in:
Harsh Vardhan Roy
2024-12-07 00:42:44 +05:30
committed by GitHub
parent 55f931d0b9
commit cd13bd91cd
14 changed files with 236 additions and 421 deletions

View File

@ -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::*;

View File

@ -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);

View File

@ -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();