Skip to content

Commit 40068bc

Browse files
authored
fix: handle EIP-4844 and EIP-7702 transaction types in compact encoding (#48)
## Summary - Fixes panic `"Unsupported BerachainTxType extended identifier: 3"` during transaction processing - Adds missing support for EIP-4844 (blob) and EIP-7702 (set code) transaction types in compact encoding - Ensures complete backwards compatibility with existing Ethereum transaction data ## Test plan - [x] Added comprehensive backwards compatibility tests - [x] Verified roundtrip encoding/decoding for all transaction types - [x] Tested Ethereum TxType → compact → BerachainTxType conversion - [x] All 55 tests pass including new backwards compatibility coverage
1 parent 3367133 commit 40068bc

File tree

1 file changed

+128
-6
lines changed

1 file changed

+128
-6
lines changed

src/transaction/txtype.rs

Lines changed: 128 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use crate::transaction::{BerachainTxType, POL_TX_TYPE};
44
use alloy_consensus::TxType;
5+
use alloy_eips::eip2718::{EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID};
56
use bytes::{Buf, BufMut};
67
use reth::providers::errors::db::DatabaseError;
78
use reth_codecs::{Compact, txtype::COMPACT_EXTENDED_IDENTIFIER_FLAG};
@@ -22,9 +23,6 @@ impl Compact for BerachainTxType {
2223
}
2324
}
2425

25-
// For backwards compatibility purposes only 2 bits of the type are encoded in the identifier
26-
// parameter. In the case of a [`COMPACT_EXTENDED_IDENTIFIER_FLAG`], the full transaction type
27-
// is read from the buffer as a single byte.
2826
fn from_compact(mut buf: &[u8], identifier: usize) -> (Self, &[u8]) {
2927
use reth_codecs::txtype::*;
3028

@@ -33,10 +31,14 @@ impl Compact for BerachainTxType {
3331
COMPACT_IDENTIFIER_EIP2930 => Self::Ethereum(TxType::Eip2930),
3432
COMPACT_IDENTIFIER_EIP1559 => Self::Ethereum(TxType::Eip1559),
3533
COMPACT_EXTENDED_IDENTIFIER_FLAG => {
36-
let tx_type_byte = buf.get_u8();
37-
match tx_type_byte {
34+
let extended_identifier = buf.get_u8();
35+
match extended_identifier {
3836
POL_TX_TYPE => Self::Berachain,
39-
_ => panic!("Unsupported BerachainTxType extended identifier: {tx_type_byte}"),
37+
EIP4844_TX_TYPE_ID => Self::Ethereum(TxType::Eip4844),
38+
EIP7702_TX_TYPE_ID => Self::Ethereum(TxType::Eip7702),
39+
_ => panic!(
40+
"Unsupported BerachainTxType extended identifier: {extended_identifier}"
41+
),
4042
}
4143
}
4244
_ => panic!("Unknown identifier for BerachainTxType: {identifier}"),
@@ -65,3 +67,123 @@ impl Decompress for BerachainTxType {
6567
Ok(tx)
6668
}
6769
}
70+
71+
#[cfg(test)]
72+
mod tests {
73+
use super::*;
74+
use alloy_consensus::TxType;
75+
76+
#[test]
77+
fn test_eip4844_compact_roundtrip() {
78+
let tx_type = BerachainTxType::Ethereum(TxType::Eip4844);
79+
80+
let mut buf = Vec::new();
81+
let identifier = tx_type.to_compact(&mut buf);
82+
83+
let (decoded, _) = BerachainTxType::from_compact(&buf, identifier);
84+
assert_eq!(tx_type, decoded);
85+
}
86+
87+
#[test]
88+
fn test_eip7702_compact_roundtrip() {
89+
let tx_type = BerachainTxType::Ethereum(TxType::Eip7702);
90+
91+
let mut buf = Vec::new();
92+
let identifier = tx_type.to_compact(&mut buf);
93+
94+
let (decoded, _) = BerachainTxType::from_compact(&buf, identifier);
95+
assert_eq!(tx_type, decoded);
96+
}
97+
98+
#[test]
99+
fn test_berachain_pol_compact_roundtrip() {
100+
let tx_type = BerachainTxType::Berachain;
101+
102+
let mut buf = Vec::new();
103+
let identifier = tx_type.to_compact(&mut buf);
104+
105+
let (decoded, _) = BerachainTxType::from_compact(&buf, identifier);
106+
assert_eq!(tx_type, decoded);
107+
}
108+
109+
/// Test backwards compatibility: Ethereum TxType -> compact -> BerachainTxType
110+
/// This ensures existing Ethereum transaction data can be read by Berachain
111+
#[test]
112+
fn test_backwards_compatibility_ethereum_to_berachain() {
113+
let ethereum_types = vec![
114+
TxType::Legacy,
115+
TxType::Eip2930,
116+
TxType::Eip1559,
117+
TxType::Eip4844,
118+
TxType::Eip7702,
119+
];
120+
121+
for eth_type in ethereum_types {
122+
// Compact using standard Ethereum TxType
123+
let mut buf = Vec::new();
124+
let identifier = eth_type.to_compact(&mut buf);
125+
126+
// Decompress using BerachainTxType
127+
let (berachain_type, _) = BerachainTxType::from_compact(&buf, identifier);
128+
129+
// Should convert to BerachainTxType::Ethereum variant
130+
match berachain_type {
131+
BerachainTxType::Ethereum(decoded_eth_type) => {
132+
assert_eq!(
133+
decoded_eth_type, eth_type,
134+
"Ethereum type {eth_type:?} should round-trip correctly"
135+
);
136+
}
137+
BerachainTxType::Berachain => {
138+
panic!(
139+
"Ethereum type {eth_type:?} should not decode as Berachain POL transaction"
140+
);
141+
}
142+
}
143+
}
144+
}
145+
146+
/// Test that BerachainTxType can decompress data originally compressed by Ethereum TxType
147+
/// for specific transaction types that use extended identifiers
148+
#[test]
149+
fn test_backwards_compatibility_extended_identifiers() {
150+
// Test EIP-4844 (blob transactions)
151+
let eip4844_type = TxType::Eip4844;
152+
let mut buf = Vec::new();
153+
let identifier = eip4844_type.to_compact(&mut buf);
154+
155+
let (decoded, _) = BerachainTxType::from_compact(&buf, identifier);
156+
assert_eq!(decoded, BerachainTxType::Ethereum(TxType::Eip4844));
157+
158+
// Test EIP-7702 (set code transactions)
159+
let eip7702_type = TxType::Eip7702;
160+
let mut buf = Vec::new();
161+
let identifier = eip7702_type.to_compact(&mut buf);
162+
163+
let (decoded, _) = BerachainTxType::from_compact(&buf, identifier);
164+
assert_eq!(decoded, BerachainTxType::Ethereum(TxType::Eip7702));
165+
}
166+
167+
/// Test that standard Ethereum types (0-2) use direct identifiers
168+
/// and don't interfere with Berachain's extended identifier usage
169+
#[test]
170+
fn test_backwards_compatibility_direct_identifiers() {
171+
// These should use direct identifiers, not extended
172+
let direct_types = vec![
173+
(TxType::Legacy, BerachainTxType::Ethereum(TxType::Legacy)),
174+
(TxType::Eip2930, BerachainTxType::Ethereum(TxType::Eip2930)),
175+
(TxType::Eip1559, BerachainTxType::Ethereum(TxType::Eip1559)),
176+
];
177+
178+
for (eth_type, expected_berachain_type) in direct_types {
179+
let mut buf = Vec::new();
180+
let identifier = eth_type.to_compact(&mut buf);
181+
182+
// Direct identifiers should not write to buffer
183+
assert!(buf.is_empty(), "Direct identifier types should not write to buffer");
184+
185+
let (decoded, _) = BerachainTxType::from_compact(&buf, identifier);
186+
assert_eq!(decoded, expected_berachain_type);
187+
}
188+
}
189+
}

0 commit comments

Comments
 (0)