Skip to content

Commit 804dc99

Browse files
authored
feat: impl compact for alloy txtype (paradigmxyz#13152)
1 parent 6594482 commit 804dc99

File tree

4 files changed

+101
-1
lines changed

4 files changed

+101
-1
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/storage/codecs/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ serde_json.workspace = true
4848
arbitrary = { workspace = true, features = ["derive"] }
4949
proptest.workspace = true
5050
proptest-arbitrary-interop.workspace = true
51+
rstest.workspace = true
5152

5253
[features]
5354
default = ["std", "alloy"]

crates/storage/codecs/src/alloy/transaction/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ cond_mod!(
55
eip2930,
66
eip4844,
77
eip7702,
8-
legacy
8+
legacy,
9+
txtype
910
);
1011

1112

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//! Compact implementation for [`TxType`]
2+
3+
use crate::txtype::{COMPACT_EXTENDED_IDENTIFIER_FLAG, COMPACT_IDENTIFIER_EIP1559, COMPACT_IDENTIFIER_EIP2930, COMPACT_IDENTIFIER_LEGACY};
4+
use alloy_consensus::constants::{EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID};
5+
use alloy_consensus::TxType;
6+
7+
impl crate::Compact for TxType {
8+
fn to_compact<B>(&self, buf: &mut B) -> usize
9+
where
10+
B: bytes::BufMut + AsMut<[u8]>,
11+
{
12+
use crate::txtype::*;
13+
14+
match self {
15+
Self::Legacy => COMPACT_IDENTIFIER_LEGACY,
16+
Self::Eip2930 => COMPACT_IDENTIFIER_EIP2930,
17+
Self::Eip1559 => COMPACT_IDENTIFIER_EIP1559,
18+
Self::Eip4844 => {
19+
buf.put_u8(EIP4844_TX_TYPE_ID);
20+
COMPACT_EXTENDED_IDENTIFIER_FLAG
21+
}
22+
Self::Eip7702 => {
23+
buf.put_u8(EIP7702_TX_TYPE_ID);
24+
COMPACT_EXTENDED_IDENTIFIER_FLAG
25+
}
26+
}
27+
}
28+
29+
// For backwards compatibility purposes only 2 bits of the type are encoded in the identifier
30+
// parameter. In the case of a [`COMPACT_EXTENDED_IDENTIFIER_FLAG`], the full transaction type
31+
// is read from the buffer as a single byte.
32+
fn from_compact(mut buf: &[u8], identifier: usize) -> (Self, &[u8]) {
33+
use bytes::Buf;
34+
(
35+
match identifier {
36+
COMPACT_IDENTIFIER_LEGACY => Self::Legacy,
37+
COMPACT_IDENTIFIER_EIP2930 => Self::Eip2930,
38+
COMPACT_IDENTIFIER_EIP1559 => Self::Eip1559,
39+
COMPACT_EXTENDED_IDENTIFIER_FLAG => {
40+
let extended_identifier = buf.get_u8();
41+
match extended_identifier {
42+
EIP4844_TX_TYPE_ID => Self::Eip4844,
43+
EIP7702_TX_TYPE_ID => Self::Eip7702,
44+
_ => panic!("Unsupported TxType identifier: {extended_identifier}"),
45+
}
46+
}
47+
_ => panic!("Unknown identifier for TxType: {identifier}"),
48+
},
49+
buf,
50+
)
51+
}
52+
}
53+
54+
#[cfg(test)]
55+
mod tests {
56+
use super::*;
57+
use rstest::rstest;
58+
59+
use alloy_consensus::constants::{EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID};
60+
use crate::Compact;
61+
62+
63+
#[rstest]
64+
#[case(TxType::Legacy, COMPACT_IDENTIFIER_LEGACY, vec![])]
65+
#[case(TxType::Eip2930, COMPACT_IDENTIFIER_EIP2930, vec![])]
66+
#[case(TxType::Eip1559, COMPACT_IDENTIFIER_EIP1559, vec![])]
67+
#[case(TxType::Eip4844, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP4844_TX_TYPE_ID])]
68+
#[case(TxType::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])]
69+
fn test_txtype_to_compact(
70+
#[case] tx_type: TxType,
71+
#[case] expected_identifier: usize,
72+
#[case] expected_buf: Vec<u8>,
73+
) {
74+
let mut buf = vec![];
75+
let identifier = tx_type.to_compact(&mut buf);
76+
77+
assert_eq!(identifier, expected_identifier, "Unexpected identifier for TxType {tx_type:?}",);
78+
assert_eq!(buf, expected_buf, "Unexpected buffer for TxType {tx_type:?}",);
79+
}
80+
81+
#[rstest]
82+
#[case(TxType::Legacy, COMPACT_IDENTIFIER_LEGACY, vec![])]
83+
#[case(TxType::Eip2930, COMPACT_IDENTIFIER_EIP2930, vec![])]
84+
#[case(TxType::Eip1559, COMPACT_IDENTIFIER_EIP1559, vec![])]
85+
#[case(TxType::Eip4844, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP4844_TX_TYPE_ID])]
86+
#[case(TxType::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])]
87+
fn test_txtype_from_compact(
88+
#[case] expected_type: TxType,
89+
#[case] identifier: usize,
90+
#[case] buf: Vec<u8>,
91+
) {
92+
let (actual_type, remaining_buf) = TxType::from_compact(&buf, identifier);
93+
94+
assert_eq!(actual_type, expected_type, "Unexpected TxType for identifier {identifier}");
95+
assert!(remaining_buf.is_empty(), "Buffer not fully consumed for identifier {identifier}");
96+
}
97+
}

0 commit comments

Comments
 (0)