Skip to main content

reth_e2e_test_utils/
receipt.rs

1//! Helpers for awaiting the receipts of transactions sent through alloy providers.
2
3use alloy_network::{Network, ReceiptResponse};
4use alloy_provider::PendingTransactionBuilder;
5use eyre::ensure;
6use std::future::Future;
7
8/// Extension trait for transactions sent through an alloy provider.
9pub trait PendingTransactionExt<N: Network> {
10    /// Waits for the receipt of the transaction and returns it, failing if the transaction
11    /// reverted.
12    ///
13    /// Like [`PendingTransactionBuilder::get_receipt`], this waits until the transaction is
14    /// included, so the block containing it must be produced, e.g. by
15    /// [`NodeTestContext::advance_block`](crate::node::NodeTestContext::advance_block) or
16    /// [dev mining](crate::E2ETestSetupBuilder::with_dev_mining).
17    fn successful_receipt(self) -> impl Future<Output = eyre::Result<N::ReceiptResponse>> + Send;
18}
19
20impl<N: Network> PendingTransactionExt<N> for PendingTransactionBuilder<N> {
21    async fn successful_receipt(self) -> eyre::Result<N::ReceiptResponse> {
22        let receipt = self.get_receipt().await?;
23        ensure!(
24            receipt.status(),
25            "transaction {} reverted after using {} gas",
26            receipt.transaction_hash(),
27            receipt.gas_used()
28        );
29        Ok(receipt)
30    }
31}
32
33/// Waits for the receipts of all transactions in order, failing if any of them reverted.
34///
35/// See [`PendingTransactionExt::successful_receipt`].
36pub async fn await_successful_receipts<N: Network>(
37    txs: impl IntoIterator<Item = PendingTransactionBuilder<N>>,
38) -> eyre::Result<Vec<N::ReceiptResponse>> {
39    let mut receipts = Vec::new();
40    for tx in txs {
41        receipts.push(tx.successful_receipt().await?);
42    }
43    Ok(receipts)
44}