22
33use crate :: transaction:: { BerachainTxType , POL_TX_TYPE } ;
44use alloy_consensus:: TxType ;
5+ use alloy_eips:: eip2718:: { EIP4844_TX_TYPE_ID , EIP7702_TX_TYPE_ID } ;
56use bytes:: { Buf , BufMut } ;
67use reth:: providers:: errors:: db:: DatabaseError ;
78use 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