@@ -29,7 +29,7 @@ use ledger::{
29
29
} ;
30
30
use mina_hasher:: Fp ;
31
31
use mina_p2p_messages:: v2:: {
32
- DataHashLibStateHashStableV1 , LedgerHash , MinaBaseAccountBinableArgStableV2 ,
32
+ self , DataHashLibStateHashStableV1 , LedgerHash , MinaBaseAccountBinableArgStableV2 ,
33
33
MinaBaseLedgerHash0StableV1 , MinaBaseSokMessageStableV1 , MinaBaseStagedLedgerHashStableV1 ,
34
34
MinaLedgerSyncLedgerAnswerStableV2 , MinaLedgerSyncLedgerQueryStableV1 ,
35
35
MinaStateBlockchainStateValueStableV2LedgerProofStatement , MinaStateProtocolStateValueStableV2 ,
@@ -530,7 +530,25 @@ impl<T: LedgerService> TransitionFrontierService for T {
530
530
// TODO(binier): return error if not matching.
531
531
let expected_ledger_hashes = block. staged_ledger_hashes ( ) ;
532
532
if & ledger_hashes != expected_ledger_hashes {
533
- panic ! ( "staged ledger hash mismatch. found: {ledger_hashes:?}, expected: {expected_ledger_hashes:?}" ) ;
533
+ let staged_ledger = self
534
+ . ctx_mut ( )
535
+ . staged_ledger_mut ( & pred_block. staged_ledger_hash ( ) )
536
+ . unwrap ( ) ; // We already know the ledger exists, see the same call a few lines above
537
+
538
+ match dump_application_to_file ( staged_ledger, block. clone ( ) , pred_block) {
539
+ Ok ( filename) => openmina_core:: info!(
540
+ openmina_core:: log:: system_time( ) ;
541
+ kind = "LedgerService::dump - Failed application" ,
542
+ summary = format!( "StagedLedger and block saved to: {filename:?}" )
543
+ ) ,
544
+ Err ( e) => openmina_core:: error!(
545
+ openmina_core:: log:: system_time( ) ;
546
+ kind = "LedgerService::dump - Failed application" ,
547
+ summary = format!( "Failed to save block application to file: {e:?}" )
548
+ ) ,
549
+ }
550
+
551
+ panic ! ( "staged ledger hash mismatch. found: {ledger_hashes:#?}, expected: {expected_ledger_hashes:#?}" ) ;
534
552
}
535
553
536
554
let ledger_hash = block. staged_ledger_hash ( ) ;
@@ -975,6 +993,54 @@ impl<T: LedgerService> BlockProducerVrfEvaluatorLedgerService for T {
975
993
}
976
994
}
977
995
996
+ /// Save staged ledger and block to file, when the application fail.
997
+ /// So we can easily reproduce the application both in Rust and OCaml, to compare them.
998
+ /// - https://github.com/openmina/openmina/blob/8e68037aafddd43842a54c8439baeafee4c6e1eb/ledger/src/staged_ledger/staged_ledger.rs#L5959
999
+ /// - TODO: Find OCaml link, I remember having the same test in OCaml but I can't find where
1000
+ fn dump_application_to_file (
1001
+ staged_ledger : & StagedLedger ,
1002
+ block : ArcBlockWithHash ,
1003
+ pred_block : ArcBlockWithHash ,
1004
+ ) -> std:: io:: Result < String > {
1005
+ use mina_p2p_messages:: {
1006
+ binprot,
1007
+ binprot:: macros:: { BinProtRead , BinProtWrite } ,
1008
+ } ;
1009
+
1010
+ #[ derive( BinProtRead , BinProtWrite ) ]
1011
+ struct ApplyContext {
1012
+ accounts : Vec < v2:: MinaBaseAccountBinableArgStableV2 > ,
1013
+ scan_state : v2:: TransactionSnarkScanStateStableV2 ,
1014
+ pending_coinbase : v2:: MinaBasePendingCoinbaseStableV2 ,
1015
+ pred_block : v2:: MinaBlockBlockStableV2 ,
1016
+ blocks : Vec < v2:: MinaBlockBlockStableV2 > ,
1017
+ }
1018
+
1019
+ let cs = & block. block . header . protocol_state . body . consensus_state ;
1020
+ let block_height = cs. blockchain_length . as_u32 ( ) ;
1021
+
1022
+ let apply_context = ApplyContext {
1023
+ accounts : staged_ledger
1024
+ . ledger ( )
1025
+ . to_list ( )
1026
+ . iter ( )
1027
+ . map ( v2:: MinaBaseAccountBinableArgStableV2 :: from)
1028
+ . collect :: < Vec < _ > > ( ) ,
1029
+ scan_state : staged_ledger. scan_state ( ) . into ( ) ,
1030
+ pending_coinbase : staged_ledger. pending_coinbase_collection ( ) . into ( ) ,
1031
+ pred_block : ( * pred_block. block ) . clone ( ) ,
1032
+ blocks : vec ! [ ( * block. block) . clone( ) ] ,
1033
+ } ;
1034
+
1035
+ use mina_p2p_messages:: binprot:: BinProtWrite ;
1036
+ let filename = format ! ( "/tmp/failed_application_ctx_{}.binprot" , block_height) ;
1037
+ let mut file = std:: fs:: File :: create ( & filename) ?;
1038
+ apply_context. binprot_write ( & mut file) ?;
1039
+ file. sync_all ( ) ?;
1040
+
1041
+ Ok ( filename)
1042
+ }
1043
+
978
1044
#[ cfg( test) ]
979
1045
mod tests {
980
1046
use mina_p2p_messages:: v2:: MinaBaseLedgerHash0StableV1 ;
0 commit comments