op_revm/transaction/
abstraction.rs1use super::deposit::{DepositTransactionParts, DEPOSIT_TRANSACTION_TYPE};
2use auto_impl::auto_impl;
3use revm::{
4 context::TxEnv,
5 context_interface::transaction::Transaction,
6 handler::SystemCallTx,
7 primitives::{Address, Bytes, TxKind, B256, U256},
8};
9use std::vec;
10
11#[auto_impl(&, &mut, Box, Arc)]
12pub trait OpTxTr: Transaction {
13 fn enveloped_tx(&self) -> Option<&Bytes>;
14
15 fn source_hash(&self) -> Option<B256>;
17
18 fn mint(&self) -> Option<u128>;
20
21 fn is_system_transaction(&self) -> bool;
23
24 fn is_deposit(&self) -> bool {
26 self.tx_type() == DEPOSIT_TRANSACTION_TYPE
27 }
28}
29
30#[derive(Clone, Debug, PartialEq, Eq)]
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
32pub struct OpTransaction<T: Transaction> {
33 pub base: T,
34 pub enveloped_tx: Option<Bytes>,
40 pub deposit: DepositTransactionParts,
41}
42
43impl<T: Transaction> OpTransaction<T> {
44 pub fn new(base: T) -> Self {
45 Self {
46 base,
47 enveloped_tx: None,
48 deposit: DepositTransactionParts::default(),
49 }
50 }
51}
52
53impl Default for OpTransaction<TxEnv> {
54 fn default() -> Self {
55 Self {
56 base: TxEnv::default(),
57 enveloped_tx: Some(vec![0x00].into()),
58 deposit: DepositTransactionParts::default(),
59 }
60 }
61}
62
63impl<TX: Transaction + SystemCallTx> SystemCallTx for OpTransaction<TX> {
64 fn new_system_tx(data: Bytes, system_contract_address: Address) -> Self {
65 OpTransaction::new(TX::new_system_tx(data, system_contract_address))
66 }
67}
68
69impl<T: Transaction> Transaction for OpTransaction<T> {
70 type AccessListItem<'a>
71 = T::AccessListItem<'a>
72 where
73 T: 'a;
74 type Authorization<'a>
75 = T::Authorization<'a>
76 where
77 T: 'a;
78
79 fn tx_type(&self) -> u8 {
80 self.base.tx_type()
81 }
82
83 fn caller(&self) -> Address {
84 self.base.caller()
85 }
86
87 fn gas_limit(&self) -> u64 {
88 self.base.gas_limit()
89 }
90
91 fn value(&self) -> U256 {
92 self.base.value()
93 }
94
95 fn input(&self) -> &Bytes {
96 self.base.input()
97 }
98
99 fn nonce(&self) -> u64 {
100 self.base.nonce()
101 }
102
103 fn kind(&self) -> TxKind {
104 self.base.kind()
105 }
106
107 fn chain_id(&self) -> Option<u64> {
108 self.base.chain_id()
109 }
110
111 fn access_list(&self) -> Option<impl Iterator<Item = Self::AccessListItem<'_>>> {
112 self.base.access_list()
113 }
114
115 fn max_priority_fee_per_gas(&self) -> Option<u128> {
116 self.base.max_priority_fee_per_gas()
117 }
118
119 fn max_fee_per_gas(&self) -> u128 {
120 self.base.max_fee_per_gas()
121 }
122
123 fn gas_price(&self) -> u128 {
124 self.base.gas_price()
125 }
126
127 fn blob_versioned_hashes(&self) -> &[B256] {
128 self.base.blob_versioned_hashes()
129 }
130
131 fn max_fee_per_blob_gas(&self) -> u128 {
132 self.base.max_fee_per_blob_gas()
133 }
134
135 fn effective_gas_price(&self, base_fee: u128) -> u128 {
136 self.base.effective_gas_price(base_fee)
137 }
138
139 fn authorization_list_len(&self) -> usize {
140 self.base.authorization_list_len()
141 }
142
143 fn authorization_list(&self) -> impl Iterator<Item = Self::Authorization<'_>> {
144 self.base.authorization_list()
145 }
146
147 fn initcodes(&self) -> &[Bytes] {
148 self.base.initcodes()
149 }
150}
151
152impl<T: Transaction> OpTxTr for OpTransaction<T> {
153 fn enveloped_tx(&self) -> Option<&Bytes> {
154 self.enveloped_tx.as_ref()
155 }
156
157 fn source_hash(&self) -> Option<B256> {
158 if self.tx_type() != DEPOSIT_TRANSACTION_TYPE {
159 return None;
160 }
161 Some(self.deposit.source_hash)
162 }
163
164 fn mint(&self) -> Option<u128> {
165 self.deposit.mint
166 }
167
168 fn is_system_transaction(&self) -> bool {
169 self.deposit.is_system_transaction
170 }
171}
172
173#[cfg(test)]
174mod tests {
175 use crate::transaction::deposit::DEPOSIT_TRANSACTION_TYPE;
176
177 use super::*;
178 use revm::primitives::{Address, B256};
179
180 #[test]
181 fn test_deposit_transaction_fields() {
182 let op_tx = OpTransaction {
183 base: TxEnv {
184 tx_type: DEPOSIT_TRANSACTION_TYPE,
185 gas_limit: 10,
186 gas_price: 100,
187 gas_priority_fee: Some(5),
188 ..Default::default()
189 },
190 enveloped_tx: None,
191 deposit: DepositTransactionParts {
192 is_system_transaction: false,
193 mint: Some(0u128),
194 source_hash: B256::default(),
195 },
196 };
197 assert_eq!(op_tx.tx_type(), DEPOSIT_TRANSACTION_TYPE);
199 assert_eq!(op_tx.gas_limit(), 10);
201 assert_eq!(op_tx.kind(), revm::primitives::TxKind::Call(Address::ZERO));
202 assert_eq!(op_tx.effective_gas_price(90), 95);
204 assert_eq!(op_tx.max_fee_per_gas(), 100);
205 }
206}