99use std:: { collections:: HashMap , convert:: TryFrom } ;
1010
1111use serde:: { Deserialize , Serialize } ;
12+ use thiserror:: Error ;
1213pub use zksync_basic_types:: commitment:: { L1BatchCommitmentMode , PubdataParams , PubdataType } ;
1314use zksync_contracts:: BaseSystemContractsHashes ;
1415use zksync_crypto_primitives:: hasher:: { keccak:: KeccakHasher , Hasher } ;
@@ -38,6 +39,21 @@ use crate::{
3839#[ cfg( test) ]
3940mod tests;
4041
42+ #[ derive( Debug , Error ) ]
43+ pub enum CommitmentValidationError {
44+ #[ error( "State diff hash mismatch: expected {expected}, got {actual}" ) ]
45+ StateDiffHashMismatch { expected : H256 , actual : H256 } ,
46+ #[ error( "Blob linear hashes mismatch: expected {expected:?}, got {actual:?}" ) ]
47+ BlobLinearHashesMismatch {
48+ expected : Vec < H256 > ,
49+ actual : Vec < H256 > ,
50+ } ,
51+ #[ error( "L2 L1 logs tree root mismatch: expected {expected}, got {actual}" ) ]
52+ L2L1LogsTreeRootMismatch { expected : H256 , actual : H256 } ,
53+ #[ error( "Serialized size for BlockPassThroughData is bigger than expected: expected {expected}, got {actual}" ) ]
54+ SerializedSizeMismatch { expected : usize , actual : usize } ,
55+ }
56+
4157/// Type that can be serialized for commitment.
4258pub trait SerializeCommitment {
4359 /// Size of the structure in bytes.
@@ -335,7 +351,7 @@ pub enum L1BatchAuxiliaryOutput {
335351}
336352
337353impl L1BatchAuxiliaryOutput {
338- fn new ( input : CommitmentInput ) -> Self {
354+ fn new ( input : CommitmentInput ) -> Result < Self , CommitmentValidationError > {
339355 match input {
340356 CommitmentInput :: PreBoojum {
341357 common : common_input,
@@ -365,14 +381,14 @@ impl L1BatchAuxiliaryOutput {
365381 let repeated_writes_compressed = pre_boojum_serialize_commitments ( & repeated_writes) ;
366382 let repeated_writes_hash = H256 :: from ( keccak256 ( & repeated_writes_compressed) ) ;
367383
368- Self :: PreBoojum {
384+ Ok ( Self :: PreBoojum {
369385 common : common_output,
370386 l2_l1_logs_linear_hash,
371387 initial_writes_compressed,
372388 initial_writes_hash,
373389 repeated_writes_compressed,
374390 repeated_writes_hash,
375- }
391+ } )
376392 }
377393 CommitmentInput :: PostBoojum {
378394 common : common_input,
@@ -419,10 +435,12 @@ impl L1BatchAuxiliaryOutput {
419435 . then_some ( log. 0 . value )
420436 } )
421437 . expect ( "Failed to find state diff hash in system logs" ) ;
422- assert_eq ! (
423- state_diffs_hash, state_diff_hash_from_logs,
424- "State diff hash mismatch"
425- ) ;
438+ if state_diffs_hash != state_diff_hash_from_logs {
439+ return Err ( CommitmentValidationError :: StateDiffHashMismatch {
440+ expected : state_diff_hash_from_logs,
441+ actual : state_diffs_hash,
442+ } ) ;
443+ }
426444
427445 let blob_linear_hashes_from_logs =
428446 parse_system_logs_for_blob_hashes_pre_gateway (
@@ -431,10 +449,12 @@ impl L1BatchAuxiliaryOutput {
431449 ) ;
432450 let blob_linear_hashes: Vec < _ > =
433451 blob_hashes. iter ( ) . map ( |b| b. linear_hash ) . collect ( ) ;
434- assert_eq ! (
435- blob_linear_hashes, blob_linear_hashes_from_logs,
436- "Blob linear hashes mismatch"
437- ) ;
452+ if blob_linear_hashes != blob_linear_hashes_from_logs {
453+ return Err ( CommitmentValidationError :: BlobLinearHashesMismatch {
454+ expected : blob_linear_hashes_from_logs,
455+ actual : blob_linear_hashes,
456+ } ) ;
457+ }
438458 }
439459
440460 let l2_to_l1_logs_tree_root_from_logs = system_logs
@@ -444,13 +464,15 @@ impl L1BatchAuxiliaryOutput {
444464 . then_some ( log. 0 . value )
445465 } )
446466 . expect ( "Failed to find L2 to L1 logs tree root in system logs" ) ;
447- assert_eq ! (
448- l2_l1_logs_merkle_root, l2_to_l1_logs_tree_root_from_logs,
449- "L2 L1 logs tree root mismatch"
450- ) ;
467+ if l2_l1_logs_merkle_root != l2_to_l1_logs_tree_root_from_logs {
468+ return Err ( CommitmentValidationError :: L2L1LogsTreeRootMismatch {
469+ expected : l2_to_l1_logs_tree_root_from_logs,
470+ actual : l2_l1_logs_merkle_root,
471+ } ) ;
472+ }
451473 }
452474
453- Self :: PostBoojum {
475+ Ok ( Self :: PostBoojum {
454476 common : common_output,
455477 system_logs_linear_hash,
456478 state_diffs_compressed,
@@ -459,7 +481,7 @@ impl L1BatchAuxiliaryOutput {
459481 blob_hashes,
460482 local_root,
461483 aggregation_root,
462- }
484+ } )
463485 }
464486 }
465487 }
@@ -589,24 +611,25 @@ struct L1BatchPassThroughData {
589611}
590612
591613impl L1BatchPassThroughData {
592- pub fn to_bytes ( & self ) -> Vec < u8 > {
614+ pub fn to_bytes ( & self ) -> Result < Vec < u8 > , CommitmentValidationError > {
593615 // We assume that currently we have only two shared state: Rollup and ZkPorter where porter is always zero
594616 const SERIALIZED_SIZE : usize = 8 + 32 + 8 + 32 ;
595617 let mut result = Vec :: with_capacity ( SERIALIZED_SIZE ) ;
596618 for state in self . shared_states . iter ( ) {
597619 result. extend_from_slice ( & state. last_leaf_index . to_be_bytes ( ) ) ;
598620 result. extend_from_slice ( state. root_hash . as_bytes ( ) ) ;
599621 }
600- assert_eq ! (
601- result. len( ) ,
602- SERIALIZED_SIZE ,
603- "Serialized size for BlockPassThroughData is bigger than expected"
604- ) ;
605- result
622+ if result. len ( ) != SERIALIZED_SIZE {
623+ return Err ( CommitmentValidationError :: SerializedSizeMismatch {
624+ expected : SERIALIZED_SIZE ,
625+ actual : result. len ( ) ,
626+ } ) ;
627+ }
628+ Ok ( result)
606629 }
607630
608- pub fn hash ( & self ) -> H256 {
609- H256 :: from_slice ( & keccak256 ( & self . to_bytes ( ) ) )
631+ pub fn hash ( & self ) -> Result < H256 , CommitmentValidationError > {
632+ Ok ( H256 :: from_slice ( & keccak256 ( & self . to_bytes ( ) ? ) ) )
610633 }
611634}
612635
@@ -627,7 +650,7 @@ pub struct L1BatchCommitmentHash {
627650}
628651
629652impl L1BatchCommitment {
630- pub fn new ( input : CommitmentInput ) -> Self {
653+ pub fn new ( input : CommitmentInput ) -> Result < Self , CommitmentValidationError > {
631654 let meta_parameters = L1BatchMetaParameters {
632655 zkporter_is_available : ZKPORTER_IS_AVAILABLE ,
633656 bootloader_code_hash : input. common ( ) . bootloader_code_hash ,
@@ -636,7 +659,7 @@ impl L1BatchCommitment {
636659 protocol_version : Some ( input. common ( ) . protocol_version ) ,
637660 } ;
638661
639- Self {
662+ Ok ( Self {
640663 pass_through_data : L1BatchPassThroughData {
641664 shared_states : vec ! [
642665 RootState {
@@ -650,9 +673,9 @@ impl L1BatchCommitment {
650673 } ,
651674 ] ,
652675 } ,
653- auxiliary_output : L1BatchAuxiliaryOutput :: new ( input) ,
676+ auxiliary_output : L1BatchAuxiliaryOutput :: new ( input) ? ,
654677 meta_parameters,
655- }
678+ } )
656679 }
657680
658681 pub fn meta_parameters ( & self ) -> L1BatchMetaParameters {
@@ -672,25 +695,25 @@ impl L1BatchCommitment {
672695 }
673696 }
674697
675- pub fn hash ( & self ) -> L1BatchCommitmentHash {
698+ pub fn hash ( & self ) -> Result < L1BatchCommitmentHash , CommitmentValidationError > {
676699 let mut result = vec ! [ ] ;
677- let pass_through_data_hash = self . pass_through_data . hash ( ) ;
700+ let pass_through_data_hash = self . pass_through_data . hash ( ) ? ;
678701 result. extend_from_slice ( pass_through_data_hash. as_bytes ( ) ) ;
679702 let metadata_hash = self . meta_parameters . hash ( ) ;
680703 result. extend_from_slice ( metadata_hash. as_bytes ( ) ) ;
681704 let auxiliary_output_hash = self . auxiliary_output . hash ( ) ;
682705 result. extend_from_slice ( auxiliary_output_hash. as_bytes ( ) ) ;
683706 let hash = keccak256 ( & result) ;
684707 let commitment = H256 :: from_slice ( & hash) ;
685- L1BatchCommitmentHash {
708+ Ok ( L1BatchCommitmentHash {
686709 pass_through_data : pass_through_data_hash,
687710 aux_output : auxiliary_output_hash,
688711 meta_parameters : metadata_hash,
689712 commitment,
690- }
713+ } )
691714 }
692715
693- pub fn artifacts ( & self ) -> L1BatchCommitmentArtifacts {
716+ pub fn artifacts ( & self ) -> Result < L1BatchCommitmentArtifacts , CommitmentValidationError > {
694717 let ( compressed_initial_writes, compressed_repeated_writes, compressed_state_diffs) =
695718 match & self . auxiliary_output {
696719 L1BatchAuxiliaryOutput :: PostBoojum {
@@ -708,8 +731,8 @@ impl L1BatchCommitment {
708731 ) ,
709732 } ;
710733
711- L1BatchCommitmentArtifacts {
712- commitment_hash : self . hash ( ) ,
734+ Ok ( L1BatchCommitmentArtifacts {
735+ commitment_hash : self . hash ( ) ? ,
713736 l2_l1_merkle_root : self . l2_l1_logs_merkle_root ( ) ,
714737 compressed_state_diffs,
715738 zkporter_is_available : self . meta_parameters . zkporter_is_available ,
@@ -719,7 +742,7 @@ impl L1BatchCommitment {
719742 local_root : self . auxiliary_output . local_root ( ) ,
720743 aggregation_root : self . auxiliary_output . aggregation_root ( ) ,
721744 state_diff_hash : self . auxiliary_output . state_diff_hash ( ) ,
722- }
745+ } )
723746 }
724747}
725748
0 commit comments