reth_seismic_rpc/eth/
receipt.rs

1//! Loads and formats Seismic receipt RPC response.
2
3use alloy_consensus::transaction::TransactionMeta;
4use alloy_eips::eip7840::BlobParams;
5use reth_chainspec::{ChainSpec, ChainSpecProvider, EthChainSpec};
6use reth_node_api::{FullNodeComponents, NodeTypes};
7use reth_rpc_eth_api::{helpers::LoadReceipt, FromEthApiError, RpcNodeCore, RpcReceipt};
8use reth_rpc_eth_types::{receipt::build_receipt, EthApiError};
9use reth_seismic_primitives::{SeismicReceipt, SeismicTransactionSigned};
10use reth_storage_api::{ReceiptProvider, TransactionsProvider};
11use seismic_alloy_consensus::{SeismicReceiptEnvelope, SeismicTxType};
12use seismic_alloy_rpc_types::SeismicTransactionReceipt;
13
14use crate::SeismicEthApi;
15
16impl<N> LoadReceipt for SeismicEthApi<N>
17where
18    Self: Send + Sync,
19    N: FullNodeComponents<Types: NodeTypes<ChainSpec = ChainSpec>>,
20    Self::Provider: TransactionsProvider<Transaction = SeismicTransactionSigned>
21        + ReceiptProvider<Receipt = SeismicReceipt>
22        + ChainSpecProvider<ChainSpec = ChainSpec>,
23{
24    async fn build_transaction_receipt(
25        &self,
26        tx: SeismicTransactionSigned,
27        meta: TransactionMeta,
28        receipt: SeismicReceipt,
29    ) -> Result<RpcReceipt<Self::NetworkTypes>, Self::Error> {
30        let hash = meta.block_hash;
31        // get all receipts for the block
32        let all_receipts = self
33            .inner
34            .cache()
35            .get_receipts(hash)
36            .await
37            .map_err(Self::Error::from_eth_err)?
38            .ok_or(EthApiError::HeaderNotFound(hash.into()))?;
39        let blob_params = self.provider().chain_spec().blob_params_at_timestamp(meta.timestamp);
40
41        Ok(SeismicReceiptBuilder::new(&tx, meta, &receipt, &all_receipts, blob_params)?.build())
42    }
43}
44
45/// Builds an [`SeismicTransactionReceipt`].
46///
47/// Like [`EthReceiptBuilder`], but with Seismic types
48#[derive(Debug)]
49pub struct SeismicReceiptBuilder {
50    /// The base response body, contains L1 fields.
51    pub base: SeismicTransactionReceipt,
52}
53
54impl SeismicReceiptBuilder {
55    /// Returns a new builder.
56    pub fn new(
57        transaction: &SeismicTransactionSigned,
58        meta: TransactionMeta,
59        receipt: &SeismicReceipt,
60        all_receipts: &[SeismicReceipt],
61        blob_params: Option<BlobParams>,
62    ) -> Result<Self, EthApiError> {
63        let base = build_receipt(
64            transaction,
65            meta,
66            receipt,
67            all_receipts,
68            blob_params,
69            |receipt_with_bloom| match receipt.tx_type() {
70                SeismicTxType::Legacy => SeismicReceiptEnvelope::Legacy(receipt_with_bloom),
71                SeismicTxType::Eip2930 => SeismicReceiptEnvelope::Eip2930(receipt_with_bloom),
72                SeismicTxType::Eip1559 => SeismicReceiptEnvelope::Eip1559(receipt_with_bloom),
73                SeismicTxType::Eip7702 => SeismicReceiptEnvelope::Eip7702(receipt_with_bloom),
74                SeismicTxType::Seismic => SeismicReceiptEnvelope::Seismic(receipt_with_bloom),
75                #[allow(unreachable_patterns)]
76                _ => unreachable!(),
77            },
78        )?;
79
80        Ok(Self { base })
81    }
82
83    /// Builds [`SeismicTransactionReceipt`] by combing core (l1) receipt fields and additional
84    /// Seismic receipt fields.
85    pub fn build(self) -> SeismicTransactionReceipt {
86        self.base
87    }
88}