reth_primitives/transaction/
compat.rs

1use crate::{Transaction, TransactionSigned};
2use alloy_consensus::Typed2718;
3use alloy_primitives::{Address, TxKind, U256};
4#[cfg(feature = "optimism")]
5use op_alloy_consensus::DepositTransaction;
6use reth_tracing::tracing::*;
7use revm_primitives::{AuthorizationList, TxEnv};
8
9/// Implements behaviour to fill a [`TxEnv`] from another transaction.
10pub trait FillTxEnv {
11    /// Fills [`TxEnv`] with an [`Address`] and transaction.
12    fn fill_tx_env(&self, tx_env: &mut TxEnv, sender: Address);
13}
14
15impl FillTxEnv for TransactionSigned {
16    fn fill_tx_env(&self, tx_env: &mut TxEnv, sender: Address) {
17        #[cfg(feature = "optimism")]
18        let envelope = alloy_eips::eip2718::Encodable2718::encoded_2718(self);
19
20        tx_env.caller = sender;
21        match self.as_ref() {
22            Transaction::Legacy(tx) => {
23                tx_env.gas_limit = tx.gas_limit;
24                tx_env.gas_price = U256::from(tx.gas_price);
25                tx_env.gas_priority_fee = None;
26                tx_env.transact_to = tx.to;
27                tx_env.value = tx.value;
28                tx_env.data = tx.input.clone();
29                tx_env.chain_id = tx.chain_id;
30                tx_env.nonce = Some(tx.nonce);
31                tx_env.access_list.clear();
32                tx_env.blob_hashes.clear();
33                tx_env.max_fee_per_blob_gas.take();
34                tx_env.authorization_list = None;
35                tx_env.tx_hash = self.hash();
36                tx_env.tx_type = Some(tx.ty() as isize);
37            }
38            Transaction::Eip2930(tx) => {
39                tx_env.gas_limit = tx.gas_limit;
40                tx_env.gas_price = U256::from(tx.gas_price);
41                tx_env.gas_priority_fee = None;
42                tx_env.transact_to = tx.to;
43                tx_env.value = tx.value;
44                tx_env.data = tx.input.clone();
45                tx_env.chain_id = Some(tx.chain_id);
46                tx_env.nonce = Some(tx.nonce);
47                tx_env.access_list.clone_from(&tx.access_list.0);
48                tx_env.blob_hashes.clear();
49                tx_env.max_fee_per_blob_gas.take();
50                tx_env.authorization_list = None;
51                tx_env.tx_hash = self.hash();
52                tx_env.tx_type = Some(tx.ty() as isize);
53            }
54            Transaction::Eip1559(tx) => {
55                tx_env.gas_limit = tx.gas_limit;
56                tx_env.gas_price = U256::from(tx.max_fee_per_gas);
57                tx_env.gas_priority_fee = Some(U256::from(tx.max_priority_fee_per_gas));
58                tx_env.transact_to = tx.to;
59                tx_env.value = tx.value;
60                tx_env.data = tx.input.clone();
61                tx_env.chain_id = Some(tx.chain_id);
62                tx_env.nonce = Some(tx.nonce);
63                tx_env.access_list.clone_from(&tx.access_list.0);
64                tx_env.blob_hashes.clear();
65                tx_env.max_fee_per_blob_gas.take();
66                tx_env.authorization_list = None;
67                tx_env.tx_hash = self.hash();
68                tx_env.tx_type = Some(tx.ty() as isize);
69            }
70            Transaction::Eip4844(tx) => {
71                tx_env.gas_limit = tx.gas_limit;
72                tx_env.gas_price = U256::from(tx.max_fee_per_gas);
73                tx_env.gas_priority_fee = Some(U256::from(tx.max_priority_fee_per_gas));
74                tx_env.transact_to = TxKind::Call(tx.to);
75                tx_env.value = tx.value;
76                tx_env.data = tx.input.clone();
77                tx_env.chain_id = Some(tx.chain_id);
78                tx_env.nonce = Some(tx.nonce);
79                tx_env.access_list.clone_from(&tx.access_list.0);
80                tx_env.blob_hashes.clone_from(&tx.blob_versioned_hashes);
81                tx_env.max_fee_per_blob_gas = Some(U256::from(tx.max_fee_per_blob_gas));
82                tx_env.authorization_list = None;
83                tx_env.tx_hash = self.hash();
84                tx_env.tx_type = Some(tx.ty() as isize);
85            }
86            Transaction::Eip7702(tx) => {
87                tx_env.gas_limit = tx.gas_limit;
88                tx_env.gas_price = U256::from(tx.max_fee_per_gas);
89                tx_env.gas_priority_fee = Some(U256::from(tx.max_priority_fee_per_gas));
90                tx_env.transact_to = tx.to.into();
91                tx_env.value = tx.value;
92                tx_env.data = tx.input.clone();
93                tx_env.chain_id = Some(tx.chain_id);
94                tx_env.nonce = Some(tx.nonce);
95                tx_env.access_list.clone_from(&tx.access_list.0);
96                tx_env.blob_hashes.clear();
97                tx_env.max_fee_per_blob_gas.take();
98                tx_env.authorization_list =
99                    Some(AuthorizationList::Signed(tx.authorization_list.clone()));
100                tx_env.tx_hash = self.hash();
101                tx_env.tx_type = Some(tx.ty() as isize);
102            }
103            #[cfg(feature = "optimism")]
104            Transaction::Deposit(tx) => {
105                tx_env.access_list.clear();
106                tx_env.gas_limit = tx.gas_limit;
107                tx_env.gas_price = U256::ZERO;
108                tx_env.gas_priority_fee = None;
109                tx_env.transact_to = tx.to;
110                tx_env.value = tx.value;
111                tx_env.data = tx.input.clone();
112                tx_env.chain_id = None;
113                tx_env.nonce = None;
114                tx_env.authorization_list = None;
115
116                tx_env.optimism = revm_primitives::OptimismFields {
117                    source_hash: Some(tx.source_hash),
118                    mint: tx.mint,
119                    is_system_transaction: Some(tx.is_system_transaction),
120                    enveloped_tx: Some(envelope.into()),
121                };
122                tx_env.tx_type = Some(tx.ty() as isize);
123                return;
124            }
125            Transaction::Seismic(_tx) => {
126                // implementation is in EthEvmConfig to avoid changing FillTxEnv trait
127                error!(target: "reth::fill_tx_env", "Seismic transaction not filled");
128                return
129            }
130        }
131
132        #[cfg(feature = "optimism")]
133        if !self.is_deposit() {
134            tx_env.optimism = revm_primitives::OptimismFields {
135                source_hash: None,
136                mint: None,
137                is_system_transaction: Some(false),
138                enveloped_tx: Some(envelope.into()),
139            }
140        }
141    }
142}