@@ -16,7 +16,7 @@ use crate::{
1616} ;
1717
1818use alloy_eips:: eip4844:: Blob ;
19- use alloy_primitives:: Bytes ;
19+ use alloy_primitives:: { Bytes , U256 } ;
2020
2121/// The Codec.
2222#[ derive( Debug ) ]
@@ -46,7 +46,7 @@ impl Codec {
4646 /// Decodes the input data and returns the decoded [`Batch`].
4747 pub fn decode < T : CommitDataSource > ( input : & T ) -> Result < Batch , CodecError > {
4848 let calldata = input. calldata ( ) ;
49- let version = calldata . first ( ) . ok_or ( DecodingError :: MissingCodecVersion ) ?;
49+ let version = get_codec_version ( & calldata ) . ok_or ( DecodingError :: MissingCodecVersion ) ?;
5050
5151 let payload = match version {
5252 0 => decode_v0 ( calldata) ?,
@@ -66,7 +66,7 @@ impl Codec {
6666 let blob = input. blob ( ) . ok_or ( DecodingError :: MissingBlob ) ?;
6767 decode_v7 ( blob. as_ref ( ) ) ?
6868 }
69- v => return Err ( DecodingError :: UnsupportedCodecVersion ( * v) . into ( ) ) ,
69+ v => return Err ( DecodingError :: UnsupportedCodecVersion ( v) . into ( ) ) ,
7070 } ;
7171
7272 Ok ( payload)
@@ -80,3 +80,21 @@ pub trait CommitDataSource {
8080 /// Returns the blob for decoding.
8181 fn blob ( & self ) -> Option < & Blob > ;
8282}
83+
84+ /// Returns the codec version from the calldata.
85+ fn get_codec_version ( calldata : & [ u8 ] ) -> Option < u8 > {
86+ const CODEC_VERSION_OFFSET_START : usize = 4 ;
87+ const CODEC_VERSION_OFFSET_END : usize = 4 + 32 ;
88+ const HIGH_BYTES_FLAG : U256 =
89+ U256 :: from_limbs ( [ u64:: MAX , u64:: MAX , u64:: MAX , 0xffffffffffffff00 ] ) ;
90+ const LOW_BYTES_FLAG : U256 = U256 :: from_limbs ( [ 0 , 0 , 0 , 0xff ] ) ;
91+
92+ let version = calldata. get ( CODEC_VERSION_OFFSET_START ..CODEC_VERSION_OFFSET_END ) ?;
93+ let version = U256 :: from_be_slice ( version) ;
94+
95+ if ( version & HIGH_BYTES_FLAG ) != U256 :: ZERO {
96+ return None
97+ }
98+
99+ Some ( ( version & LOW_BYTES_FLAG ) . saturating_to ( ) )
100+ }
0 commit comments