alloy_consensus/transaction/
tx_type.rs1use alloy_eips::{
4 eip2718::{Eip2718Error, IsTyped2718},
5 Typed2718,
6};
7use alloy_primitives::{U64, U8};
8use alloy_rlp::{Decodable, Encodable};
9use core::fmt;
10
11#[repr(u8)]
35#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
36#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
37#[cfg_attr(feature = "serde", serde(into = "U8", try_from = "U64"))]
38#[doc(alias = "TransactionType")]
39pub enum TxType {
40 #[default]
42 Legacy = 0,
43 Eip2930 = 1,
45 Eip1559 = 2,
47 Eip4844 = 3,
49 Eip7702 = 4,
51}
52
53impl From<TxType> for u8 {
54 fn from(value: TxType) -> Self {
55 value as Self
56 }
57}
58
59impl From<TxType> for U8 {
60 fn from(tx_type: TxType) -> Self {
61 Self::from(u8::from(tx_type))
62 }
63}
64
65impl TxType {
66 #[inline]
68 pub const fn is_legacy(&self) -> bool {
69 matches!(self, Self::Legacy)
70 }
71
72 #[inline]
74 pub const fn is_eip2930(&self) -> bool {
75 matches!(self, Self::Eip2930)
76 }
77
78 #[inline]
80 pub const fn is_eip1559(&self) -> bool {
81 matches!(self, Self::Eip1559)
82 }
83
84 #[inline]
86 pub const fn is_eip4844(&self) -> bool {
87 matches!(self, Self::Eip4844)
88 }
89
90 #[inline]
92 pub const fn is_eip7702(&self) -> bool {
93 matches!(self, Self::Eip7702)
94 }
95
96 #[inline]
98 pub const fn is_dynamic_fee(&self) -> bool {
99 matches!(self, Self::Eip1559 | Self::Eip4844 | Self::Eip7702)
100 }
101}
102
103impl IsTyped2718 for TxType {
104 fn is_type(type_id: u8) -> bool {
105 matches!(type_id, 0x0..=0x04)
106 }
107}
108
109impl fmt::Display for TxType {
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 match self {
112 Self::Legacy => write!(f, "Legacy"),
113 Self::Eip2930 => write!(f, "EIP-2930"),
114 Self::Eip1559 => write!(f, "EIP-1559"),
115 Self::Eip4844 => write!(f, "EIP-4844"),
116 Self::Eip7702 => write!(f, "EIP-7702"),
117 }
118 }
119}
120
121impl PartialEq<u8> for TxType {
122 fn eq(&self, other: &u8) -> bool {
123 (*self as u8) == *other
124 }
125}
126
127impl PartialEq<TxType> for u8 {
128 fn eq(&self, other: &TxType) -> bool {
129 *self == *other as Self
130 }
131}
132
133#[cfg(any(test, feature = "arbitrary"))]
134impl arbitrary::Arbitrary<'_> for TxType {
135 fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
136 Ok(u.int_in_range(0u8..=4)?.try_into().unwrap())
137 }
138}
139
140impl TryFrom<u8> for TxType {
141 type Error = Eip2718Error;
142
143 fn try_from(value: u8) -> Result<Self, Self::Error> {
144 Ok(match value {
145 0 => Self::Legacy,
146 1 => Self::Eip2930,
147 2 => Self::Eip1559,
148 3 => Self::Eip4844,
149 4 => Self::Eip7702,
150 _ => return Err(Eip2718Error::UnexpectedType(value)),
151 })
152 }
153}
154
155impl TryFrom<u64> for TxType {
156 type Error = &'static str;
157
158 fn try_from(value: u64) -> Result<Self, Self::Error> {
159 let err = || "invalid tx type";
160 let value: u8 = value.try_into().map_err(|_| err())?;
161 Self::try_from(value).map_err(|_| err())
162 }
163}
164
165impl TryFrom<U8> for TxType {
166 type Error = Eip2718Error;
167
168 fn try_from(value: U8) -> Result<Self, Self::Error> {
169 value.to::<u8>().try_into()
170 }
171}
172
173impl TryFrom<U64> for TxType {
174 type Error = &'static str;
175
176 fn try_from(value: U64) -> Result<Self, Self::Error> {
177 value.to::<u64>().try_into()
178 }
179}
180
181impl Encodable for TxType {
182 fn encode(&self, out: &mut dyn alloy_rlp::BufMut) {
183 (*self as u8).encode(out);
184 }
185
186 fn length(&self) -> usize {
187 1
188 }
189}
190
191impl Decodable for TxType {
192 fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
193 let ty = u8::decode(buf)?;
194 Self::try_from(ty).map_err(|_| alloy_rlp::Error::Custom("invalid transaction type"))
195 }
196}
197
198impl Typed2718 for TxType {
199 fn ty(&self) -> u8 {
200 (*self).into()
201 }
202}
203
204#[cfg(test)]
205mod tests {
206 use super::*;
207
208 #[test]
209 fn check_u8_id() {
210 assert_eq!(TxType::Legacy, TxType::Legacy as u8);
211 assert_eq!(TxType::Eip2930, TxType::Eip2930 as u8);
212 assert_eq!(TxType::Eip1559, TxType::Eip1559 as u8);
213 assert_eq!(TxType::Eip7702, TxType::Eip7702 as u8);
214 assert_eq!(TxType::Eip4844, TxType::Eip4844 as u8);
215 }
216}