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