@@ -741,15 +741,25 @@ pub fn verify_block(
741741 } ;
742742
743743 let Ok ( protocol_state) = ProtocolState :: try_from ( protocol_state) else {
744+ openmina_core:: warn!(
745+ message = format!( "verify_block: Protocol state contains invalid field" )
746+ ) ;
744747 return false ; // invalid bigint
745748 } ;
746749 let protocol_state_hash = MinaHash :: hash ( & protocol_state) ;
747750
748751 let accum_check =
749752 accumulator_check:: accumulator_check ( srs, & [ protocol_state_proof] ) . unwrap_or ( false ) ;
750753 let verified = verify_impl ( & protocol_state_hash, protocol_state_proof, & vk) . unwrap_or ( false ) ;
754+ let ok = accum_check && verified;
755+
756+ openmina_core:: info!( message = format!( "verify_block OK={ok:?}" ) ) ;
757+
758+ if !ok {
759+ on_fail:: dump_block_verification ( header) ;
760+ }
751761
752- accum_check && verified
762+ ok
753763}
754764
755765pub fn verify_transaction < ' a > (
@@ -781,9 +791,16 @@ pub fn verify_transaction<'a>(
781791
782792 let accum_check =
783793 accumulator_check:: accumulator_check ( srs, & accum_check_proofs) . unwrap_or ( false ) ;
784-
785794 let verified = batch_verify_impl ( inputs. as_slice ( ) ) . unwrap_or ( false ) ;
786- accum_check && verified
795+ let ok = accum_check && verified;
796+
797+ openmina_core:: info!( message = format!( "verify_transactions OK={ok:?}" ) ) ;
798+
799+ if !ok {
800+ on_fail:: dump_tx_verification ( & inputs) ;
801+ }
802+
803+ ok
787804}
788805
789806/// https://github.com/MinaProtocol/mina/blob/bfd1009abdbee78979ff0343cc73a3480e862f58/src/lib/crypto/kimchi_bindings/stubs/src/pasta_fq_plonk_proof.rs#L116
@@ -807,18 +824,10 @@ pub fn verify_zkapp(
807824
808825 let ok = accum_check && verified;
809826
810- openmina_core:: info!( openmina_core :: log :: system_time ( ) ; message = format!( "verify_zkapp OK={ok:?}" ) ) ;
827+ openmina_core:: info!( message = format!( "verify_zkapp OK={ok:?}" ) ) ;
811828
812- #[ cfg( not( test) ) ]
813829 if !ok {
814- if let Err ( e) = dump_zkapp_verification ( verification_key, zkapp_statement, sideloaded_proof)
815- {
816- openmina_core:: error!(
817- openmina_core:: log:: system_time( ) ;
818- message = "Failed to dump zkapp verification" ,
819- error = format!( "{e:?}" )
820- ) ;
821- }
830+ on_fail:: dump_zkapp_verification ( verification_key, zkapp_statement, sideloaded_proof) ;
822831 }
823832
824833 ok
@@ -916,59 +925,109 @@ where
916925}
917926
918927/// Dump data when it fails, to reproduce and compare in OCaml
919- fn dump_zkapp_verification (
920- verification_key : & VerificationKey ,
921- zkapp_statement : & ZkappStatement ,
922- sideloaded_proof : & PicklesProofProofsVerified2ReprStableV2 ,
923- ) -> std:: io:: Result < ( ) > {
924- use mina_p2p_messages:: binprot;
925- use mina_p2p_messages:: binprot:: macros:: { BinProtRead , BinProtWrite } ;
926-
927- #[ derive( Clone , Debug , PartialEq , BinProtRead , BinProtWrite ) ]
928- struct VerifyZkapp {
929- vk : v2:: MinaBaseVerificationKeyWireStableV1 ,
930- zkapp_statement : v2:: MinaBaseZkappStatementStableV2 ,
931- proof : v2:: PicklesProofProofsVerified2ReprStableV2 ,
928+ mod on_fail {
929+ use super :: * ;
930+
931+ pub ( super ) fn dump_zkapp_verification (
932+ verification_key : & VerificationKey ,
933+ zkapp_statement : & ZkappStatement ,
934+ sideloaded_proof : & PicklesProofProofsVerified2ReprStableV2 ,
935+ ) {
936+ use mina_p2p_messages:: binprot;
937+ use mina_p2p_messages:: binprot:: macros:: { BinProtRead , BinProtWrite } ;
938+
939+ #[ derive( Clone , Debug , PartialEq , BinProtRead , BinProtWrite ) ]
940+ struct VerifyZkapp {
941+ vk : v2:: MinaBaseVerificationKeyWireStableV1 ,
942+ zkapp_statement : v2:: MinaBaseZkappStatementStableV2 ,
943+ proof : v2:: PicklesProofProofsVerified2ReprStableV2 ,
944+ }
945+
946+ let data = VerifyZkapp {
947+ vk : verification_key. into ( ) ,
948+ zkapp_statement : zkapp_statement. into ( ) ,
949+ proof : sideloaded_proof. clone ( ) ,
950+ } ;
951+
952+ dump_to_file ( & data, "verify_zkapp" )
932953 }
933954
934- let data = VerifyZkapp {
935- vk : verification_key. into ( ) ,
936- zkapp_statement : zkapp_statement. into ( ) ,
937- proof : sideloaded_proof. clone ( ) ,
938- } ;
955+ pub ( super ) fn dump_block_verification ( header : & MinaBlockHeaderStableV2 ) {
956+ dump_to_file ( header, "verify_block" )
957+ }
939958
940- let bin = {
941- let mut vec = Vec :: with_capacity ( 128 * 1024 ) ;
942- data. binprot_write ( & mut vec) ?;
943- vec
944- } ;
959+ pub ( super ) fn dump_tx_verification (
960+ txs : & [ (
961+ & Statement < SokDigest > ,
962+ & PicklesProofProofsVerified2ReprStableV2 ,
963+ & VK ,
964+ ) ] ,
965+ ) {
966+ let data = txs
967+ . iter ( )
968+ . map ( |( statement, proof, _vk) | {
969+ let statement: v2:: MinaStateSnarkedLedgerStateWithSokStableV2 = ( * statement) . into ( ) ;
970+ ( statement, ( * proof) . clone ( ) )
971+ } )
972+ . collect :: < Vec < _ > > ( ) ;
945973
946- let debug_dir = openmina_core:: get_debug_dir ( ) ;
947- let filename = debug_dir
948- . join ( generate_new_filename ( "verify_zapp" , "binprot" , & bin) ?)
949- . to_string_lossy ( )
950- . to_string ( ) ;
951- std:: fs:: create_dir_all ( & debug_dir) ?;
974+ dump_to_file ( & data, "verify_txs" )
975+ }
952976
953- let mut file = std:: fs:: File :: create ( filename) ?;
954- file. write_all ( & bin) ?;
955- file. sync_all ( ) ?;
977+ #[ allow( unreachable_code) ]
978+ fn dump_to_file < D : BinProtWrite > ( data : & D , filename : & str ) {
979+ #[ cfg( test) ]
980+ {
981+ let ( _, _) = ( data, filename) ; // avoid unused vars
982+ return ;
983+ }
956984
957- Ok ( ( ) )
958- }
985+ if let Err ( e) = dump_to_file_impl ( data, filename) {
986+ openmina_core:: error!(
987+ message = "Failed to dump proof verification data" ,
988+ error = format!( "{e:?}" )
989+ ) ;
990+ }
991+ }
992+
993+ fn dump_to_file_impl < D : BinProtWrite > ( data : & D , filename : & str ) -> std:: io:: Result < ( ) > {
994+ let bin = {
995+ let mut vec = Vec :: with_capacity ( 128 * 1024 ) ;
996+ data. binprot_write ( & mut vec) ?;
997+ vec
998+ } ;
999+
1000+ let debug_dir = openmina_core:: get_debug_dir ( ) ;
1001+ let filename = debug_dir
1002+ . join ( generate_new_filename ( filename, "binprot" , & bin) ?)
1003+ . to_string_lossy ( )
1004+ . to_string ( ) ;
1005+ std:: fs:: create_dir_all ( & debug_dir) ?;
1006+
1007+ let mut file = std:: fs:: File :: create ( & filename) ?;
1008+ file. write_all ( & bin) ?;
1009+ file. sync_all ( ) ?;
1010+
1011+ openmina_core:: error!(
1012+ message = format!( "proof verication failed, dumped data to {:?}" , & filename)
1013+ ) ;
1014+
1015+ Ok ( ( ) )
1016+ }
9591017
960- fn generate_new_filename ( name : & str , extension : & str , data : & [ u8 ] ) -> std:: io:: Result < String > {
961- use crate :: proofs:: util:: sha256_sum;
1018+ fn generate_new_filename ( name : & str , extension : & str , data : & [ u8 ] ) -> std:: io:: Result < String > {
1019+ use crate :: proofs:: util:: sha256_sum;
9621020
963- let sum = sha256_sum ( data) ;
964- for index in 0 ..100_000 {
965- let name = format ! ( "{}_{}_{}.{}" , name, sum, index, extension) ;
966- let path = std:: path:: Path :: new ( & name) ;
967- if !path. try_exists ( ) . unwrap_or ( true ) {
968- return Ok ( name) ;
1021+ let sum = sha256_sum ( data) ;
1022+ for index in 0 ..100_000 {
1023+ let name = format ! ( "{}_{}_{}.{}" , name, sum, index, extension) ;
1024+ let path = std:: path:: Path :: new ( & name) ;
1025+ if !path. try_exists ( ) . unwrap_or ( true ) {
1026+ return Ok ( name) ;
1027+ }
9691028 }
1029+ Err ( std:: io:: Error :: other ( "no filename available" ) )
9701030 }
971- Err ( std:: io:: Error :: other ( "no filename available" ) )
9721031}
9731032
9741033#[ cfg( test) ]
0 commit comments