reth_codecs/alloy/transaction/
optimism.rs1use crate::{
4 alloy::transaction::ethereum::{CompactEnvelope, Envelope, FromTxCompact, ToTxCompact},
5 generate_tests,
6 txtype::{
7 COMPACT_EXTENDED_IDENTIFIER_FLAG, COMPACT_IDENTIFIER_EIP1559, COMPACT_IDENTIFIER_EIP2930,
8 COMPACT_IDENTIFIER_LEGACY,
9 },
10 Compact,
11};
12use alloy_consensus::{
13 constants::EIP7702_TX_TYPE_ID, Signed, TxEip1559, TxEip2930, TxEip7702, TxLegacy,
14};
15use alloy_primitives::{Address, Bytes, Sealed, Signature, TxKind, B256, U256};
16use bytes::BufMut;
17use op_alloy_consensus::{OpTxEnvelope, OpTxType, OpTypedTransaction, TxDeposit as AlloyTxDeposit};
18use reth_codecs_derive::add_arbitrary_tests;
19
20#[derive(Debug, Clone, PartialEq, Eq, Hash, Default, Compact)]
29#[cfg_attr(
30 any(test, feature = "test-utils"),
31 derive(arbitrary::Arbitrary, serde::Serialize, serde::Deserialize)
32)]
33#[cfg_attr(feature = "test-utils", allow(unreachable_pub), visibility::make(pub))]
34#[reth_codecs(crate = "crate")]
35#[add_arbitrary_tests(crate, compact)]
36pub(crate) struct TxDeposit {
37 source_hash: B256,
38 from: Address,
39 to: TxKind,
40 mint: Option<u128>,
41 value: U256,
42 gas_limit: u64,
43 is_system_transaction: bool,
44 input: Bytes,
45}
46
47impl Compact for AlloyTxDeposit {
48 fn to_compact<B>(&self, buf: &mut B) -> usize
49 where
50 B: bytes::BufMut + AsMut<[u8]>,
51 {
52 let tx = TxDeposit {
53 source_hash: self.source_hash,
54 from: self.from,
55 to: self.to,
56 mint: match self.mint {
57 0 => None,
58 v => Some(v),
59 },
60 value: self.value,
61 gas_limit: self.gas_limit,
62 is_system_transaction: self.is_system_transaction,
63 input: self.input.clone(),
64 };
65 tx.to_compact(buf)
66 }
67
68 fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) {
69 let (tx, _) = TxDeposit::from_compact(buf, len);
70 let alloy_tx = Self {
71 source_hash: tx.source_hash,
72 from: tx.from,
73 to: tx.to,
74 mint: tx.mint.unwrap_or_default(),
75 value: tx.value,
76 gas_limit: tx.gas_limit,
77 is_system_transaction: tx.is_system_transaction,
78 input: tx.input,
79 };
80 (alloy_tx, buf)
81 }
82}
83
84impl crate::Compact for OpTxType {
85 fn to_compact<B>(&self, buf: &mut B) -> usize
86 where
87 B: bytes::BufMut + AsMut<[u8]>,
88 {
89 use crate::txtype::*;
90
91 match self {
92 Self::Legacy => COMPACT_IDENTIFIER_LEGACY,
93 Self::Eip2930 => COMPACT_IDENTIFIER_EIP2930,
94 Self::Eip1559 => COMPACT_IDENTIFIER_EIP1559,
95 Self::Eip7702 => {
96 buf.put_u8(EIP7702_TX_TYPE_ID);
97 COMPACT_EXTENDED_IDENTIFIER_FLAG
98 }
99 Self::Deposit => {
100 buf.put_u8(op_alloy_consensus::DEPOSIT_TX_TYPE_ID);
101 COMPACT_EXTENDED_IDENTIFIER_FLAG
102 }
103 }
104 }
105
106 fn from_compact(mut buf: &[u8], identifier: usize) -> (Self, &[u8]) {
110 use bytes::Buf;
111 (
112 match identifier {
113 COMPACT_IDENTIFIER_LEGACY => Self::Legacy,
114 COMPACT_IDENTIFIER_EIP2930 => Self::Eip2930,
115 COMPACT_IDENTIFIER_EIP1559 => Self::Eip1559,
116 COMPACT_EXTENDED_IDENTIFIER_FLAG => {
117 let extended_identifier = buf.get_u8();
118 match extended_identifier {
119 EIP7702_TX_TYPE_ID => Self::Eip7702,
120 op_alloy_consensus::DEPOSIT_TX_TYPE_ID => Self::Deposit,
121 _ => panic!("Unsupported OpTxType identifier: {extended_identifier}"),
122 }
123 }
124 _ => panic!("Unknown identifier for TxType: {identifier}"),
125 },
126 buf,
127 )
128 }
129}
130
131impl Compact for OpTypedTransaction {
132 fn to_compact<B>(&self, out: &mut B) -> usize
133 where
134 B: bytes::BufMut + AsMut<[u8]>,
135 {
136 let identifier = self.tx_type().to_compact(out);
137 match self {
138 Self::Legacy(tx) => tx.to_compact(out),
139 Self::Eip2930(tx) => tx.to_compact(out),
140 Self::Eip1559(tx) => tx.to_compact(out),
141 Self::Eip7702(tx) => tx.to_compact(out),
142 Self::Deposit(tx) => tx.to_compact(out),
143 };
144 identifier
145 }
146
147 fn from_compact(buf: &[u8], identifier: usize) -> (Self, &[u8]) {
148 let (tx_type, buf) = OpTxType::from_compact(buf, identifier);
149 match tx_type {
150 OpTxType::Legacy => {
151 let (tx, buf) = Compact::from_compact(buf, buf.len());
152 (Self::Legacy(tx), buf)
153 }
154 OpTxType::Eip2930 => {
155 let (tx, buf) = Compact::from_compact(buf, buf.len());
156 (Self::Eip2930(tx), buf)
157 }
158 OpTxType::Eip1559 => {
159 let (tx, buf) = Compact::from_compact(buf, buf.len());
160 (Self::Eip1559(tx), buf)
161 }
162 OpTxType::Eip7702 => {
163 let (tx, buf) = Compact::from_compact(buf, buf.len());
164 (Self::Eip7702(tx), buf)
165 }
166 OpTxType::Deposit => {
167 let (tx, buf) = Compact::from_compact(buf, buf.len());
168 (Self::Deposit(tx), buf)
169 }
170 }
171 }
172}
173
174impl ToTxCompact for OpTxEnvelope {
175 fn to_tx_compact(&self, buf: &mut (impl BufMut + AsMut<[u8]>)) {
176 match self {
177 Self::Legacy(tx) => tx.tx().to_compact(buf),
178 Self::Eip2930(tx) => tx.tx().to_compact(buf),
179 Self::Eip1559(tx) => tx.tx().to_compact(buf),
180 Self::Eip7702(tx) => tx.tx().to_compact(buf),
181 Self::Deposit(tx) => tx.to_compact(buf),
182 };
183 }
184}
185
186impl FromTxCompact for OpTxEnvelope {
187 type TxType = OpTxType;
188
189 fn from_tx_compact(buf: &[u8], tx_type: OpTxType, signature: Signature) -> (Self, &[u8]) {
190 match tx_type {
191 OpTxType::Legacy => {
192 let (tx, buf) = TxLegacy::from_compact(buf, buf.len());
193 let tx = Signed::new_unhashed(tx, signature);
194 (Self::Legacy(tx), buf)
195 }
196 OpTxType::Eip2930 => {
197 let (tx, buf) = TxEip2930::from_compact(buf, buf.len());
198 let tx = Signed::new_unhashed(tx, signature);
199 (Self::Eip2930(tx), buf)
200 }
201 OpTxType::Eip1559 => {
202 let (tx, buf) = TxEip1559::from_compact(buf, buf.len());
203 let tx = Signed::new_unhashed(tx, signature);
204 (Self::Eip1559(tx), buf)
205 }
206 OpTxType::Eip7702 => {
207 let (tx, buf) = TxEip7702::from_compact(buf, buf.len());
208 let tx = Signed::new_unhashed(tx, signature);
209 (Self::Eip7702(tx), buf)
210 }
211 OpTxType::Deposit => {
212 let (tx, buf) = op_alloy_consensus::TxDeposit::from_compact(buf, buf.len());
213 let tx = Sealed::new(tx);
214 (Self::Deposit(tx), buf)
215 }
216 }
217 }
218}
219
220const DEPOSIT_SIGNATURE: Signature = Signature::new(U256::ZERO, U256::ZERO, false);
221
222impl Envelope for OpTxEnvelope {
223 fn signature(&self) -> &Signature {
224 match self {
225 Self::Legacy(tx) => tx.signature(),
226 Self::Eip2930(tx) => tx.signature(),
227 Self::Eip1559(tx) => tx.signature(),
228 Self::Eip7702(tx) => tx.signature(),
229 Self::Deposit(_) => &DEPOSIT_SIGNATURE,
230 }
231 }
232
233 fn tx_type(&self) -> Self::TxType {
234 Self::tx_type(self)
235 }
236}
237
238impl Compact for OpTxEnvelope {
239 fn to_compact<B>(&self, buf: &mut B) -> usize
240 where
241 B: BufMut + AsMut<[u8]>,
242 {
243 CompactEnvelope::to_compact(self, buf)
244 }
245
246 fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) {
247 CompactEnvelope::from_compact(buf, len)
248 }
249}
250
251generate_tests!(#[crate, compact] OpTypedTransaction, OpTypedTransactionTests);