reth_codecs/alloy/transaction/
optimism.rs
1use 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, Signature, Sealed, 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: self.mint,
57 value: self.value,
58 gas_limit: self.gas_limit,
59 is_system_transaction: self.is_system_transaction,
60 input: self.input.clone(),
61 };
62 tx.to_compact(buf)
63 }
64
65 fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) {
66 let (tx, _) = TxDeposit::from_compact(buf, len);
67 let alloy_tx = Self {
68 source_hash: tx.source_hash,
69 from: tx.from,
70 to: tx.to,
71 mint: tx.mint,
72 value: tx.value,
73 gas_limit: tx.gas_limit,
74 is_system_transaction: tx.is_system_transaction,
75 input: tx.input,
76 };
77 (alloy_tx, buf)
78 }
79}
80
81impl crate::Compact for OpTxType {
82 fn to_compact<B>(&self, buf: &mut B) -> usize
83 where
84 B: bytes::BufMut + AsMut<[u8]>,
85 {
86 use crate::txtype::*;
87
88 match self {
89 Self::Legacy => COMPACT_IDENTIFIER_LEGACY,
90 Self::Eip2930 => COMPACT_IDENTIFIER_EIP2930,
91 Self::Eip1559 => COMPACT_IDENTIFIER_EIP1559,
92 Self::Eip7702 => {
93 buf.put_u8(EIP7702_TX_TYPE_ID);
94 COMPACT_EXTENDED_IDENTIFIER_FLAG
95 }
96 Self::Deposit => {
97 buf.put_u8(op_alloy_consensus::DEPOSIT_TX_TYPE_ID);
98 COMPACT_EXTENDED_IDENTIFIER_FLAG
99 }
100 }
101 }
102
103 fn from_compact(mut buf: &[u8], identifier: usize) -> (Self, &[u8]) {
107 use bytes::Buf;
108 (
109 match identifier {
110 COMPACT_IDENTIFIER_LEGACY => Self::Legacy,
111 COMPACT_IDENTIFIER_EIP2930 => Self::Eip2930,
112 COMPACT_IDENTIFIER_EIP1559 => Self::Eip1559,
113 COMPACT_EXTENDED_IDENTIFIER_FLAG => {
114 let extended_identifier = buf.get_u8();
115 match extended_identifier {
116 EIP7702_TX_TYPE_ID => Self::Eip7702,
117 op_alloy_consensus::DEPOSIT_TX_TYPE_ID => Self::Deposit,
118 _ => panic!("Unsupported OpTxType identifier: {extended_identifier}"),
119 }
120 }
121 _ => panic!("Unknown identifier for TxType: {identifier}"),
122 },
123 buf,
124 )
125 }
126}
127
128impl Compact for OpTypedTransaction {
129 fn to_compact<B>(&self, out: &mut B) -> usize
130 where
131 B: bytes::BufMut + AsMut<[u8]>,
132 {
133 let identifier = self.tx_type().to_compact(out);
134 match self {
135 Self::Legacy(tx) => tx.to_compact(out),
136 Self::Eip2930(tx) => tx.to_compact(out),
137 Self::Eip1559(tx) => tx.to_compact(out),
138 Self::Eip7702(tx) => tx.to_compact(out),
139 Self::Deposit(tx) => tx.to_compact(out),
140 };
141 identifier
142 }
143
144 fn from_compact(buf: &[u8], identifier: usize) -> (Self, &[u8]) {
145 let (tx_type, buf) = OpTxType::from_compact(buf, identifier);
146 match tx_type {
147 OpTxType::Legacy => {
148 let (tx, buf) = Compact::from_compact(buf, buf.len());
149 (Self::Legacy(tx), buf)
150 }
151 OpTxType::Eip2930 => {
152 let (tx, buf) = Compact::from_compact(buf, buf.len());
153 (Self::Eip2930(tx), buf)
154 }
155 OpTxType::Eip1559 => {
156 let (tx, buf) = Compact::from_compact(buf, buf.len());
157 (Self::Eip1559(tx), buf)
158 }
159 OpTxType::Eip7702 => {
160 let (tx, buf) = Compact::from_compact(buf, buf.len());
161 (Self::Eip7702(tx), buf)
162 }
163 OpTxType::Deposit => {
164 let (tx, buf) = Compact::from_compact(buf, buf.len());
165 (Self::Deposit(tx), buf)
166 }
167 }
168 }
169}
170
171impl ToTxCompact for OpTxEnvelope {
172 fn to_tx_compact(&self, buf: &mut (impl BufMut + AsMut<[u8]>)) {
173 match self {
174 Self::Legacy(tx) => tx.tx().to_compact(buf),
175 Self::Eip2930(tx) => tx.tx().to_compact(buf),
176 Self::Eip1559(tx) => tx.tx().to_compact(buf),
177 Self::Eip7702(tx) => tx.tx().to_compact(buf),
178 Self::Deposit(tx) => tx.to_compact(buf),
179 };
180 }
181}
182
183impl FromTxCompact for OpTxEnvelope {
184 type TxType = OpTxType;
185
186 fn from_tx_compact(
187 buf: &[u8],
188 tx_type: OpTxType,
189 signature: Signature,
190 ) -> (Self, &[u8]) {
191 match tx_type {
192 OpTxType::Legacy => {
193 let (tx, buf) = TxLegacy::from_compact(buf, buf.len());
194 let tx = Signed::new_unhashed(tx, signature);
195 (Self::Legacy(tx), buf)
196 }
197 OpTxType::Eip2930 => {
198 let (tx, buf) = TxEip2930::from_compact(buf, buf.len());
199 let tx = Signed::new_unhashed(tx, signature);
200 (Self::Eip2930(tx), buf)
201 }
202 OpTxType::Eip1559 => {
203 let (tx, buf) = TxEip1559::from_compact(buf, buf.len());
204 let tx = Signed::new_unhashed(tx, signature);
205 (Self::Eip1559(tx), buf)
206 }
207 OpTxType::Eip7702 => {
208 let (tx, buf) = TxEip7702::from_compact(buf, buf.len());
209 let tx = Signed::new_unhashed(tx, signature);
210 (Self::Eip7702(tx), buf)
211 }
212 OpTxType::Deposit => {
213 let (tx, buf) = op_alloy_consensus::TxDeposit::from_compact(buf, buf.len());
214 let tx = Sealed::new(tx);
215 (Self::Deposit(tx), buf)
216 }
217 }
218 }
219}
220
221const DEPOSIT_SIGNATURE: Signature =
222 Signature::new(U256::ZERO, U256::ZERO, false);
223
224impl Envelope for OpTxEnvelope {
225 fn signature(&self) -> &Signature {
226 match self {
227 Self::Legacy(tx) => tx.signature(),
228 Self::Eip2930(tx) => tx.signature(),
229 Self::Eip1559(tx) => tx.signature(),
230 Self::Eip7702(tx) => tx.signature(),
231 Self::Deposit(_) => &DEPOSIT_SIGNATURE,
232 }
233 }
234
235 fn tx_type(&self) -> Self::TxType {
236 Self::tx_type(self)
237 }
238}
239
240impl Compact for OpTxEnvelope {
241 fn to_compact<B>(&self, buf: &mut B) -> usize
242 where
243 B: BufMut + AsMut<[u8]>,
244 {
245 CompactEnvelope::to_compact(self, buf)
246 }
247
248 fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) {
249 CompactEnvelope::from_compact(buf, len)
250 }
251}
252
253generate_tests!(#[crate, compact] OpTypedTransaction, OpTypedTransactionTests);