@@ -3,7 +3,9 @@ package relayer
33import (
44 "fmt"
55
6+ "github.com/scroll-tech/da-codec/encoding"
67 "github.com/scroll-tech/go-ethereum/common"
8+ "github.com/scroll-tech/go-ethereum/crypto/kzg4844"
79 "github.com/scroll-tech/go-ethereum/log"
810
911 "scroll-tech/rollup/internal/orm"
@@ -245,3 +247,93 @@ func (r *Layer2Relayer) validateSingleChunk(chunk *orm.Chunk, prevChunk *orm.Chu
245247
246248 return nil
247249}
250+
251+ func (r * Layer2Relayer ) sanityChecksCommitBatchCodecV7CalldataAndBlobs (calldata []byte , blobs []* kzg4844.Blob , batchesToSubmit []* dbBatchWithChunks , firstBatch , lastBatch * orm.Batch ,
252+ ) error {
253+ // Check blob count matches batch count
254+ if len (blobs ) != len (batchesToSubmit ) {
255+ return fmt .Errorf ("blob count mismatch: got %d, want %d" , len (blobs ), len (batchesToSubmit ))
256+ }
257+
258+ // Parse calldata (after first 4 bytes: method selector)
259+ method := r .l1RollupABI .Methods ["commitBatches" ]
260+ if len (calldata ) < 4 {
261+ return fmt .Errorf ("calldata too short to contain method selector" )
262+ }
263+ decoded , err := method .Inputs .Unpack (calldata [4 :])
264+ if err != nil {
265+ return fmt .Errorf ("failed to unpack commitBatches calldata: %w" , err )
266+ }
267+
268+ if len (decoded ) != 3 {
269+ return fmt .Errorf ("unexpected number of decoded parameters: got %d, want 3" , len (decoded ))
270+ }
271+
272+ version := decoded [0 ].(uint8 )
273+ parentBatchHash := decoded [1 ].(common.Hash )
274+ lastBatchHash := decoded [2 ].(common.Hash )
275+
276+ // Check version and batch hashes
277+ if version != uint8 (firstBatch .CodecVersion ) {
278+ return fmt .Errorf ("sanity check failed: version mismatch: calldata=%d, db=%d" , version , firstBatch .CodecVersion )
279+ }
280+ if parentBatchHash != common .HexToHash (firstBatch .ParentBatchHash ) {
281+ return fmt .Errorf ("sanity check failed: parentBatchHash mismatch: calldata=%s, db=%s" , parentBatchHash .Hex (), firstBatch .ParentBatchHash )
282+ }
283+ if lastBatchHash != common .HexToHash (lastBatch .Hash ) {
284+ return fmt .Errorf ("sanity check failed: lastBatchHash mismatch: calldata=%s, db=%s" , lastBatchHash .Hex (), lastBatch .Hash )
285+ }
286+
287+ // Get codec for blob decoding
288+ codec , err := encoding .CodecFromVersion (encoding .CodecVersion (firstBatch .CodecVersion ))
289+ if err != nil {
290+ return fmt .Errorf ("failed to get codec: %w" , err )
291+ }
292+
293+ // Loop through each batch and blob, decode and compare
294+ for i , blob := range blobs {
295+ dbBatch := batchesToSubmit [i ].Batch
296+ dbChunks := batchesToSubmit [i ].Chunks
297+
298+ // Collect all blocks for the batch
299+ var batchBlocks []* encoding.Block
300+ for _ , c := range dbChunks {
301+ blocks , err := r .l2BlockOrm .GetL2BlocksInRange (r .ctx , c .StartBlockNumber , c .EndBlockNumber )
302+ if err != nil {
303+ return fmt .Errorf ("failed to get blocks for batch %d chunk %d: %w" , dbBatch .Index , c .Index , err )
304+ }
305+ batchBlocks = append (batchBlocks , blocks ... )
306+ }
307+
308+ // Decode blob payload
309+ payload , err := codec .DecodeBlob (blob )
310+ if err != nil {
311+ return fmt .Errorf ("failed to decode blob for batch %d: %w" , dbBatch .Index , err )
312+ }
313+
314+ // Check L1 message queue hashes
315+ if payload .PrevL1MessageQueueHash () != common .HexToHash (dbBatch .PrevL1MessageQueueHash ) {
316+ return fmt .Errorf ("sanity check failed: prevL1MessageQueueHash mismatch for batch %d: decoded=%s, db=%s" ,
317+ dbBatch .Index , payload .PrevL1MessageQueueHash ().Hex (), dbBatch .PrevL1MessageQueueHash )
318+ }
319+ if payload .PostL1MessageQueueHash () != common .HexToHash (dbBatch .PostL1MessageQueueHash ) {
320+ return fmt .Errorf ("sanity check failed: postL1MessageQueueHash mismatch for batch %d: decoded=%s, db=%s" ,
321+ dbBatch .Index , payload .PostL1MessageQueueHash ().Hex (), dbBatch .PostL1MessageQueueHash )
322+ }
323+
324+ // Compare block count and block numbers
325+ decodedBlocks := payload .Blocks ()
326+ if len (decodedBlocks ) != len (batchBlocks ) {
327+ return fmt .Errorf ("sanity check failed: block count mismatch in batch %d: decoded=%d, db=%d" , dbBatch .Index , len (decodedBlocks ), len (batchBlocks ))
328+ }
329+ for j , b := range batchBlocks {
330+ if decodedBlocks [j ].Number () != b .Header .Number .Uint64 () {
331+ return fmt .Errorf ("sanity check failed: block number mismatch in batch %d block %d: decoded=%d, db=%d" ,
332+ dbBatch .Index , j , decodedBlocks [j ].Number (), b .Header .Number .Uint64 ())
333+ }
334+ }
335+ }
336+
337+ // All checks passed
338+ return nil
339+ }
0 commit comments