Skip to content

Commit 4dbd1c8

Browse files
committed
Be more verbose about failed proof verifications
+ Dump data in all cases, not only zkapps
1 parent d0c9b78 commit 4dbd1c8

File tree

1 file changed

+111
-55
lines changed

1 file changed

+111
-55
lines changed

ledger/src/proofs/verification.rs

Lines changed: 111 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -741,15 +741,23 @@ pub fn verify_block(
741741
};
742742

743743
let Ok(protocol_state) = ProtocolState::try_from(protocol_state) else {
744+
openmina_core::warn!(openmina_core::log::system_time(); message = format!("verify_block: Protocol state contains invalid field"));
744745
return false; // invalid bigint
745746
};
746747
let protocol_state_hash = MinaHash::hash(&protocol_state);
747748

748749
let accum_check =
749750
accumulator_check::accumulator_check(srs, &[protocol_state_proof]).unwrap_or(false);
750751
let verified = verify_impl(&protocol_state_hash, protocol_state_proof, &vk).unwrap_or(false);
752+
let ok = accum_check && verified;
753+
754+
openmina_core::info!(openmina_core::log::system_time(); message = format!("verify_block OK={ok:?}"));
755+
756+
if !ok {
757+
on_fail::dump_block_verification(header);
758+
}
751759

752-
accum_check && verified
760+
ok
753761
}
754762

755763
pub fn verify_transaction<'a>(
@@ -781,9 +789,16 @@ pub fn verify_transaction<'a>(
781789

782790
let accum_check =
783791
accumulator_check::accumulator_check(srs, &accum_check_proofs).unwrap_or(false);
784-
785792
let verified = batch_verify_impl(inputs.as_slice()).unwrap_or(false);
786-
accum_check && verified
793+
let ok = accum_check && verified;
794+
795+
openmina_core::info!(openmina_core::log::system_time(); message = format!("verify_transactions OK={ok:?}"));
796+
797+
if !ok {
798+
on_fail::dump_tx_verification(&inputs);
799+
}
800+
801+
ok
787802
}
788803

789804
/// https://github.com/MinaProtocol/mina/blob/bfd1009abdbee78979ff0343cc73a3480e862f58/src/lib/crypto/kimchi_bindings/stubs/src/pasta_fq_plonk_proof.rs#L116
@@ -809,16 +824,8 @@ pub fn verify_zkapp(
809824

810825
openmina_core::info!(openmina_core::log::system_time(); message = format!("verify_zkapp OK={ok:?}"));
811826

812-
#[cfg(not(test))]
813827
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-
}
828+
on_fail::dump_zkapp_verification(verification_key, zkapp_statement, sideloaded_proof);
822829
}
823830

824831
ok
@@ -916,59 +923,108 @@ where
916923
}
917924

918925
/// 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,
926+
mod on_fail {
927+
use super::*;
928+
929+
pub(super) fn dump_zkapp_verification(
930+
verification_key: &VerificationKey,
931+
zkapp_statement: &ZkappStatement,
932+
sideloaded_proof: &PicklesProofProofsVerified2ReprStableV2,
933+
) {
934+
use mina_p2p_messages::binprot;
935+
use mina_p2p_messages::binprot::macros::{BinProtRead, BinProtWrite};
936+
937+
#[derive(Clone, Debug, PartialEq, BinProtRead, BinProtWrite)]
938+
struct VerifyZkapp {
939+
vk: v2::MinaBaseVerificationKeyWireStableV1,
940+
zkapp_statement: v2::MinaBaseZkappStatementStableV2,
941+
proof: v2::PicklesProofProofsVerified2ReprStableV2,
942+
}
943+
944+
let data = VerifyZkapp {
945+
vk: verification_key.into(),
946+
zkapp_statement: zkapp_statement.into(),
947+
proof: sideloaded_proof.clone(),
948+
};
949+
950+
dump_to_file(&data, "verify_zkapp")
932951
}
933952

934-
let data = VerifyZkapp {
935-
vk: verification_key.into(),
936-
zkapp_statement: zkapp_statement.into(),
937-
proof: sideloaded_proof.clone(),
938-
};
953+
pub(super) fn dump_block_verification(header: &MinaBlockHeaderStableV2) {
954+
dump_to_file(header, "verify_block")
955+
}
939956

940-
let bin = {
941-
let mut vec = Vec::with_capacity(128 * 1024);
942-
data.binprot_write(&mut vec)?;
943-
vec
944-
};
957+
pub(super) fn dump_tx_verification(
958+
txs: &[(
959+
&Statement<SokDigest>,
960+
&PicklesProofProofsVerified2ReprStableV2,
961+
&VK,
962+
)],
963+
) {
964+
let data = txs
965+
.iter()
966+
.map(|(statement, proof, _vk)| {
967+
let statement: v2::MinaStateSnarkedLedgerStateWithSokStableV2 = (*statement).into();
968+
(statement, (*proof).clone())
969+
})
970+
.collect::<Vec<_>>();
945971

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)?;
972+
dump_to_file(&data, "verify_txs")
973+
}
952974

953-
let mut file = std::fs::File::create(filename)?;
954-
file.write_all(&bin)?;
955-
file.sync_all()?;
975+
#[allow(unreachable_code)]
976+
fn dump_to_file<D: BinProtWrite>(data: &D, filename: &str) {
977+
#[cfg(test)]
978+
{
979+
let (_, _) = (data, filename); // avoid unused vars
980+
return;
981+
}
956982

957-
Ok(())
958-
}
983+
if let Err(e) = dump_to_file_impl(data, filename) {
984+
openmina_core::error!(
985+
openmina_core::log::system_time();
986+
message = "Failed to dump proof verification data",
987+
error = format!("{e:?}")
988+
);
989+
}
990+
}
991+
992+
fn dump_to_file_impl<D: BinProtWrite>(data: &D, filename: &str) -> std::io::Result<()> {
993+
let bin = {
994+
let mut vec = Vec::with_capacity(128 * 1024);
995+
data.binprot_write(&mut vec)?;
996+
vec
997+
};
998+
999+
let debug_dir = openmina_core::get_debug_dir();
1000+
let filename = debug_dir
1001+
.join(generate_new_filename(filename, "binprot", &bin)?)
1002+
.to_string_lossy()
1003+
.to_string();
1004+
std::fs::create_dir_all(&debug_dir)?;
1005+
1006+
let mut file = std::fs::File::create(&filename)?;
1007+
file.write_all(&bin)?;
1008+
file.sync_all()?;
1009+
1010+
openmina_core::error!(openmina_core::log::system_time(); message = format!("proof verication failed, dumped data to {:?}", &filename));
1011+
1012+
Ok(())
1013+
}
9591014

960-
fn generate_new_filename(name: &str, extension: &str, data: &[u8]) -> std::io::Result<String> {
961-
use crate::proofs::util::sha256_sum;
1015+
fn generate_new_filename(name: &str, extension: &str, data: &[u8]) -> std::io::Result<String> {
1016+
use crate::proofs::util::sha256_sum;
9621017

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);
1018+
let sum = sha256_sum(data);
1019+
for index in 0..100_000 {
1020+
let name = format!("{}_{}_{}.{}", name, sum, index, extension);
1021+
let path = std::path::Path::new(&name);
1022+
if !path.try_exists().unwrap_or(true) {
1023+
return Ok(name);
1024+
}
9691025
}
1026+
Err(std::io::Error::other("no filename available"))
9701027
}
971-
Err(std::io::Error::other("no filename available"))
9721028
}
9731029

9741030
#[cfg(test)]

0 commit comments

Comments
 (0)