1use crate::{
2 bytes::Bytes, transaction::AccessListItem, Action, SignedTransaction,
3 Transaction, TransactionWithSignature,
4 TransactionWithSignatureSerializePart,
5};
6use cfx_types::{AddressWithSpace, H256, U256};
7use cfxkey::Address;
8use rlp_derive::{RlpDecodable, RlpEncodable};
9use serde_derive::{Deserialize, Serialize};
10
11use super::{AccessList, AuthorizationListItem};
12
13#[derive(
14 Default,
15 Debug,
16 Clone,
17 Eq,
18 PartialEq,
19 RlpEncodable,
20 RlpDecodable,
21 Serialize,
22 Deserialize,
23)]
24pub struct NativeTransaction {
25 pub nonce: U256,
27 pub gas_price: U256,
29 pub gas: U256,
31 pub action: Action,
33 pub value: U256,
35 pub storage_limit: u64,
37 pub epoch_height: u64,
41 pub chain_id: u32,
43 pub data: Bytes,
45}
46
47impl NativeTransaction {
48 pub fn fake_sign(self, from: AddressWithSpace) -> SignedTransaction {
51 SignedTransaction {
52 transaction: TransactionWithSignature {
53 transaction: TransactionWithSignatureSerializePart {
54 unsigned: Transaction::Native(
55 TypedNativeTransaction::Cip155(self),
56 ),
57 r: U256::one(),
58 s: U256::one(),
59 v: 0,
60 },
61 hash: H256::zero(),
62 rlp_size: None,
63 }
64 .compute_hash(),
65 sender: from.address,
66 public: None,
67 }
68 }
69}
70
71#[derive(
72 Default,
73 Debug,
74 Clone,
75 Eq,
76 PartialEq,
77 RlpEncodable,
78 RlpDecodable,
79 Serialize,
80 Deserialize,
81)]
82pub struct Cip2930Transaction {
83 pub nonce: U256,
84 pub gas_price: U256,
85 pub gas: U256,
86 pub action: Action,
87 pub value: U256,
88 pub storage_limit: u64,
89 pub epoch_height: u64,
90 pub chain_id: u32,
91 pub data: Bytes,
92 pub access_list: Vec<AccessListItem>,
93}
94
95#[derive(
96 Default,
97 Debug,
98 Clone,
99 Eq,
100 PartialEq,
101 RlpEncodable,
102 RlpDecodable,
103 Serialize,
104 Deserialize,
105)]
106pub struct Cip1559Transaction {
107 pub nonce: U256,
108 pub max_priority_fee_per_gas: U256,
109 pub max_fee_per_gas: U256,
110 pub gas: U256,
111 pub action: Action,
112 pub value: U256,
113 pub storage_limit: u64,
114 pub epoch_height: u64,
115 pub chain_id: u32,
116 pub data: Bytes,
117 pub access_list: Vec<AccessListItem>,
118}
119
120#[derive(
121 Default,
122 Debug,
123 Clone,
124 Eq,
125 PartialEq,
126 RlpEncodable,
127 RlpDecodable,
128 Serialize,
129 Deserialize,
130)]
131pub struct Cip7702Transaction {
132 pub nonce: U256,
133 pub max_priority_fee_per_gas: U256,
134 pub max_fee_per_gas: U256,
135 pub gas: U256,
136 pub destination: Address,
137 pub value: U256,
138 pub storage_limit: u64,
139 pub epoch_height: u64,
140 pub chain_id: u32,
141 pub data: Bytes,
142 pub access_list: Vec<AccessListItem>,
143 pub authorization_list: Vec<AuthorizationListItem>,
144}
145
146macro_rules! access_common_ref {
147 ($field:ident, $ty:ty) => {
148 pub fn $field(&self) -> &$ty {
149 match self {
150 TypedNativeTransaction::Cip155(tx) => &tx.$field,
151 TypedNativeTransaction::Cip2930(tx) => &tx.$field,
152 TypedNativeTransaction::Cip1559(tx) => &tx.$field,
153 }
154 }
155 };
156}
157
158impl TypedNativeTransaction {
159 access_common_ref!(gas, U256);
160
161 access_common_ref!(data, Bytes);
162
163 access_common_ref!(nonce, U256);
164
165 access_common_ref!(value, U256);
166
167 access_common_ref!(chain_id, u32);
168
169 access_common_ref!(epoch_height, u64);
170
171 access_common_ref!(storage_limit, u64);
172
173 pub fn action(&self) -> Action {
174 match self {
175 TypedNativeTransaction::Cip155(tx) => tx.action,
176 TypedNativeTransaction::Cip2930(tx) => tx.action,
177 TypedNativeTransaction::Cip1559(tx) => tx.action,
178 }
179 }
180
181 pub fn gas_price(&self) -> &U256 {
182 match self {
183 Cip155(tx) => &tx.gas_price,
184 Cip2930(tx) => &tx.gas_price,
185 Cip1559(tx) => &tx.max_fee_per_gas,
186 }
187 }
188
189 pub fn max_priority_gas_price(&self) -> &U256 {
190 match self {
191 Cip155(tx) => &tx.gas_price,
192 Cip2930(tx) => &tx.gas_price,
193 Cip1559(tx) => &tx.max_priority_fee_per_gas,
194 }
195 }
196
197 pub fn nonce_mut(&mut self) -> &mut U256 {
198 match self {
199 Cip155(tx) => &mut tx.nonce,
200 Cip2930(tx) => &mut tx.nonce,
201 Cip1559(tx) => &mut tx.nonce,
202 }
203 }
204
205 pub fn data_mut(&mut self) -> &mut Vec<u8> {
206 match self {
207 Cip155(tx) => &mut tx.data,
208 Cip2930(tx) => &mut tx.data,
209 Cip1559(tx) => &mut tx.data,
210 }
211 }
212
213 pub fn access_list(&self) -> Option<&AccessList> {
214 match self {
215 Cip155(_tx) => None,
216 Cip2930(tx) => Some(&tx.access_list),
217 Cip1559(tx) => Some(&tx.access_list),
218 }
219 }
220}
221
222#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
223pub enum TypedNativeTransaction {
224 Cip155(NativeTransaction),
225 Cip2930(Cip2930Transaction),
226 Cip1559(Cip1559Transaction),
227}
228
229impl TypedNativeTransaction {
230 pub fn fake_sign_rpc(self, from: AddressWithSpace) -> SignedTransaction {
231 SignedTransaction {
232 transaction: TransactionWithSignature {
233 transaction: TransactionWithSignatureSerializePart {
234 unsigned: Transaction::Native(self),
235 r: U256::one(),
236 s: U256::one(),
237 v: 0,
238 },
239 hash: H256::zero(),
240 rlp_size: None,
241 }
242 .compute_hash(),
243 sender: from.address,
244 public: None,
245 }
246 }
247}
248
249use TypedNativeTransaction::*;