@@ -13,7 +13,7 @@ use crate::decoding::{
13
13
} ;
14
14
15
15
use alloy_eips:: eip4844:: Blob ;
16
- use alloy_primitives:: Bytes ;
16
+ use alloy_primitives:: { ruint :: UintTryTo , Bytes , U256 } ;
17
17
18
18
/// The Codec.
19
19
#[ derive( Debug ) ]
@@ -43,7 +43,7 @@ impl Codec {
43
43
/// Decodes the input data and returns the decoded [`Batch`].
44
44
pub fn decode < T : CommitDataSource > ( input : & T ) -> Result < Batch , CodecError > {
45
45
let calldata = input. calldata ( ) ;
46
- let version = calldata . first ( ) . ok_or ( DecodingError :: MissingCodecVersion ) ?;
46
+ let version = get_codec_version ( calldata ) ?;
47
47
48
48
let payload = match version {
49
49
0 => decode_v0 ( calldata) ?,
@@ -63,7 +63,7 @@ impl Codec {
63
63
let blob = input. blob ( ) . ok_or ( DecodingError :: MissingBlob ) ?;
64
64
decode_v7 ( blob. as_ref ( ) ) ?
65
65
}
66
- v => return Err ( DecodingError :: UnsupportedCodecVersion ( * v) . into ( ) ) ,
66
+ v => return Err ( DecodingError :: UnsupportedCodecVersion ( v) . into ( ) ) ,
67
67
} ;
68
68
69
69
Ok ( payload)
@@ -77,3 +77,23 @@ pub trait CommitDataSource {
77
77
/// Returns the blob for decoding.
78
78
fn blob ( & self ) -> Option < & Blob > ;
79
79
}
80
+
81
+ /// Returns the codec version from the calldata.
82
+ fn get_codec_version ( calldata : & [ u8 ] ) -> Result < u8 , DecodingError > {
83
+ const CODEC_VERSION_OFFSET_START : usize = 4 ;
84
+ const CODEC_VERSION_LEN : usize = 32 ;
85
+ const CODEC_VERSION_OFFSET_END : usize = CODEC_VERSION_OFFSET_START + CODEC_VERSION_LEN ;
86
+ const HIGH_BYTES_MASK : U256 =
87
+ U256 :: from_limbs ( [ u64:: MAX , u64:: MAX , u64:: MAX , 0xffffffffffffff00 ] ) ;
88
+
89
+ let version = calldata
90
+ . get ( CODEC_VERSION_OFFSET_START ..CODEC_VERSION_OFFSET_END )
91
+ . ok_or ( DecodingError :: Eof ) ?;
92
+ let version = U256 :: from_be_slice ( version) ;
93
+
94
+ if ( version & HIGH_BYTES_MASK ) != U256 :: ZERO {
95
+ return Err ( DecodingError :: MalformedCodecVersion ( version) )
96
+ }
97
+
98
+ Ok ( version. uint_try_to ( ) . expect ( "fits in single byte" ) )
99
+ }
0 commit comments