alloy_evm/eth/
receipt_builder.rs

1//! Abstraction over receipt building logic to allow plugging different primitive types into
2//! [`super::EthBlockExecutor`].
3
4use crate::Evm;
5use alloy_consensus::{Eip658Value, ReceiptEnvelope, TxEnvelope, TxType};
6use revm::{context::result::ExecutionResult, state::EvmState};
7
8/// Context for building a receipt.
9#[derive(Debug)]
10pub struct ReceiptBuilderCtx<'a, T, E: Evm> {
11    /// Transaction
12    pub tx: &'a T,
13    /// Reference to EVM. State changes should not be committed to inner database when building
14    /// receipt so that [`ReceiptBuilder`] can use data from state before transaction execution.
15    pub evm: &'a E,
16    /// Result of transaction execution.
17    pub result: ExecutionResult<E::HaltReason>,
18    /// Reference to EVM state after execution.
19    pub state: &'a EvmState,
20    /// Cumulative gas used.
21    pub cumulative_gas_used: u64,
22}
23
24/// Type that knows how to build a receipt based on execution result.
25#[auto_impl::auto_impl(&, Arc)]
26pub trait ReceiptBuilder {
27    /// Transaction type.
28    type Transaction;
29    /// Receipt type.
30    type Receipt;
31
32    /// Builds a receipt given a transaction and the result of the execution.
33    fn build_receipt<E: Evm>(
34        &self,
35        ctx: ReceiptBuilderCtx<'_, Self::Transaction, E>,
36    ) -> Self::Receipt;
37}
38
39/// Receipt builder operating on Alloy types.
40#[derive(Debug, Default, Clone, Copy)]
41#[non_exhaustive]
42pub struct AlloyReceiptBuilder;
43
44impl ReceiptBuilder for AlloyReceiptBuilder {
45    type Transaction = TxEnvelope;
46    type Receipt = ReceiptEnvelope;
47
48    fn build_receipt<E: Evm>(&self, ctx: ReceiptBuilderCtx<'_, TxEnvelope, E>) -> Self::Receipt {
49        let receipt = alloy_consensus::Receipt {
50            status: Eip658Value::Eip658(ctx.result.is_success()),
51            cumulative_gas_used: ctx.cumulative_gas_used,
52            logs: ctx.result.into_logs(),
53        }
54        .with_bloom();
55
56        match ctx.tx.tx_type() {
57            TxType::Legacy => ReceiptEnvelope::Legacy(receipt),
58            TxType::Eip2930 => ReceiptEnvelope::Eip2930(receipt),
59            TxType::Eip1559 => ReceiptEnvelope::Eip1559(receipt),
60            TxType::Eip4844 => ReceiptEnvelope::Eip4844(receipt),
61            TxType::Eip7702 => ReceiptEnvelope::Eip7702(receipt),
62        }
63    }
64}