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_successful(&receipt)?;
24        Ok(receipt)
25    }
26}
27
28/// Returns an error naming the transaction and its gas usage if the receipt reports a revert.
29pub(crate) fn ensure_successful(receipt: &impl ReceiptResponse) -> eyre::Result<()> {
30    ensure!(
31        receipt.status(),
32        "transaction {} reverted after using {} gas",
33        receipt.transaction_hash(),
34        receipt.gas_used()
35    );
36    Ok(())
37}
38
39/// Waits for the receipts of all transactions in order, failing if any of them reverted.
40///
41/// See [`PendingTransactionExt::successful_receipt`].
42pub async fn await_successful_receipts<N: Network>(
43    txs: impl IntoIterator<Item = PendingTransactionBuilder<N>>,
44) -> eyre::Result<Vec<N::ReceiptResponse>> {
45    let mut receipts = Vec::new();
46    for tx in txs {
47        receipts.push(tx.successful_receipt().await?);
48    }
49    Ok(receipts)
50}