reth_codecs/alloy/
optimism.rs1use crate::Compact;
4use alloc::{borrow::Cow, vec::Vec};
5use alloy_consensus::{Receipt, TxReceipt};
6use alloy_primitives::Log;
7use op_alloy_consensus::{OpDepositReceipt, OpReceipt, OpTxType};
8use reth_codecs_derive::CompactZstd;
9
10#[derive(CompactZstd)]
11#[reth_codecs(crate = "crate")]
12#[reth_zstd(
13 compressor = reth_zstd_compressors::RECEIPT_COMPRESSOR,
14 decompressor = reth_zstd_compressors::RECEIPT_DECOMPRESSOR
15)]
16struct CompactOpReceipt<'a> {
17 tx_type: OpTxType,
18 success: bool,
19 cumulative_gas_used: u64,
20 #[expect(clippy::owned_cow)]
21 logs: Cow<'a, Vec<Log>>,
22 deposit_nonce: Option<u64>,
23 deposit_receipt_version: Option<u64>,
24}
25
26impl<'a> From<&'a OpReceipt> for CompactOpReceipt<'a> {
27 fn from(receipt: &'a OpReceipt) -> Self {
28 Self {
29 tx_type: receipt.tx_type(),
30 success: receipt.status(),
31 cumulative_gas_used: receipt.cumulative_gas_used(),
32 logs: Cow::Borrowed(&receipt.as_receipt().logs),
33 deposit_nonce: if let OpReceipt::Deposit(receipt) = receipt {
34 receipt.deposit_nonce
35 } else {
36 None
37 },
38 deposit_receipt_version: if let OpReceipt::Deposit(receipt) = receipt {
39 receipt.deposit_receipt_version
40 } else {
41 None
42 },
43 }
44 }
45}
46
47impl From<CompactOpReceipt<'_>> for OpReceipt {
48 fn from(receipt: CompactOpReceipt<'_>) -> Self {
49 let CompactOpReceipt {
50 tx_type,
51 success,
52 cumulative_gas_used,
53 logs,
54 deposit_nonce,
55 deposit_receipt_version,
56 } = receipt;
57
58 let inner =
59 Receipt { status: success.into(), cumulative_gas_used, logs: logs.into_owned() };
60
61 match tx_type {
62 OpTxType::Legacy => Self::Legacy(inner),
63 OpTxType::Eip2930 => Self::Eip2930(inner),
64 OpTxType::Eip1559 => Self::Eip1559(inner),
65 OpTxType::Eip7702 => Self::Eip7702(inner),
66 OpTxType::Deposit => {
67 Self::Deposit(OpDepositReceipt { inner, deposit_nonce, deposit_receipt_version })
68 }
69 }
70 }
71}
72
73impl Compact for OpReceipt {
74 fn to_compact<B>(&self, buf: &mut B) -> usize
75 where
76 B: bytes::BufMut + AsMut<[u8]>,
77 {
78 CompactOpReceipt::from(self).to_compact(buf)
79 }
80
81 fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) {
82 let (receipt, buf) = CompactOpReceipt::from_compact(buf, len);
83 (receipt.into(), buf)
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90 use crate::{test_utils::UnusedBits, validate_bitflag_backwards_compat};
91
92 #[test]
93 fn test_ensure_backwards_compatibility() {
94 assert_eq!(CompactOpReceipt::bitflag_encoded_bytes(), 2);
95 validate_bitflag_backwards_compat!(CompactOpReceipt<'_>, UnusedBits::NotZero);
96 }
97}