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