@@ -28,6 +28,7 @@ use ledger::{
2828use mina_hasher:: Fp ;
2929use mina_p2p_messages:: {
3030 binprot:: BinProtRead ,
31+ list:: List ,
3132 v2:: {
3233 self , DataHashLibStateHashStableV1 , LedgerHash , MinaBaseLedgerHash0StableV1 ,
3334 MinaBasePendingCoinbaseStableV2 , MinaBasePendingCoinbaseWitnessStableV2 ,
@@ -1109,7 +1110,9 @@ fn staged_ledger_reconstruct(
11091110 . map ( |p| p. staged_ledger_hash . clone ( ) )
11101111 . unwrap_or_else ( || snarked_ledger_hash. clone ( ) ) ;
11111112
1112- let result = if let Some ( parts) = parts {
1113+ let ledger = snarked_ledger. make_child ( ) ;
1114+
1115+ let mut result = if let Some ( parts) = & parts {
11131116 let states = parts
11141117 . needed_blocks
11151118 . iter ( )
@@ -1121,16 +1124,31 @@ fn staged_ledger_reconstruct(
11211124 constraint_constants ( ) ,
11221125 Verifier ,
11231126 ( & parts. scan_state ) . into ( ) ,
1124- snarked_ledger ,
1127+ ledger ,
11251128 LocalState :: empty ( ) ,
11261129 parts. staged_ledger_hash . 0 . to_field ( ) ,
11271130 ( & parts. pending_coinbase ) . into ( ) ,
11281131 |key| states. get ( & key) . cloned ( ) . unwrap ( ) ,
11291132 )
11301133 } else {
1131- StagedLedger :: create_exn ( constraint_constants ( ) . clone ( ) , snarked_ledger )
1134+ StagedLedger :: create_exn ( constraint_constants ( ) . clone ( ) , ledger )
11321135 } ;
11331136
1137+ match result. as_mut ( ) {
1138+ Ok ( staged_ledger) => {
1139+ staged_ledger. commit_and_reparent_to_root ( ) ;
1140+ }
1141+ Err ( _) => {
1142+ if let Err ( e) = dump_reconstruct_to_file ( & snarked_ledger, & parts) {
1143+ openmina_core:: error!(
1144+ openmina_core:: log:: system_time( ) ;
1145+ kind = "LedgerService::dump - Failed reconstruct" ,
1146+ summary = format!( "Failed to save reconstruction to file: {e:?}" )
1147+ ) ;
1148+ }
1149+ }
1150+ }
1151+
11341152 ( staged_ledger_hash, result)
11351153}
11361154
@@ -1159,6 +1177,65 @@ pub trait LedgerService: redux::Service {
11591177 }
11601178}
11611179
1180+ /// Save reconstruction to file, when it fails.
1181+ /// So we can easily reproduce the application both in Rust and OCaml, to compare them.
1182+ fn dump_reconstruct_to_file (
1183+ snarked_ledger : & Mask ,
1184+ parts : & Option < Arc < StagedLedgerAuxAndPendingCoinbasesValid > > ,
1185+ ) -> std:: io:: Result < ( ) > {
1186+ use mina_p2p_messages:: binprot:: {
1187+ self ,
1188+ macros:: { BinProtRead , BinProtWrite } ,
1189+ } ;
1190+
1191+ #[ derive( BinProtRead , BinProtWrite ) ]
1192+ struct ReconstructContext {
1193+ accounts : Vec < v2:: MinaBaseAccountBinableArgStableV2 > ,
1194+ scan_state : v2:: TransactionSnarkScanStateStableV2 ,
1195+ pending_coinbase : v2:: MinaBasePendingCoinbaseStableV2 ,
1196+ staged_ledger_hash : LedgerHash ,
1197+ states : List < v2:: MinaStateProtocolStateValueStableV2 > ,
1198+ }
1199+
1200+ let Some ( parts) = parts else {
1201+ return Err ( std:: io:: ErrorKind :: Other . into ( ) ) ;
1202+ } ;
1203+
1204+ let StagedLedgerAuxAndPendingCoinbasesValid {
1205+ scan_state,
1206+ staged_ledger_hash,
1207+ pending_coinbase,
1208+ needed_blocks,
1209+ } = & * * parts;
1210+
1211+ let reconstruct_context = ReconstructContext {
1212+ accounts : snarked_ledger
1213+ . to_list ( )
1214+ . iter ( )
1215+ . map ( v2:: MinaBaseAccountBinableArgStableV2 :: from)
1216+ . collect ( ) ,
1217+ scan_state : scan_state. clone ( ) ,
1218+ pending_coinbase : pending_coinbase. clone ( ) ,
1219+ staged_ledger_hash : staged_ledger_hash. clone ( ) ,
1220+ states : needed_blocks. clone ( ) ,
1221+ } ;
1222+
1223+ const FILENAME : & str = "/tmp/failed_reconstruct_ctx.binprot" ;
1224+
1225+ use mina_p2p_messages:: binprot:: BinProtWrite ;
1226+ let mut file = std:: fs:: File :: create ( FILENAME ) ?;
1227+ reconstruct_context. binprot_write ( & mut file) ?;
1228+ file. sync_all ( ) ?;
1229+
1230+ openmina_core:: info!(
1231+ openmina_core:: log:: system_time( ) ;
1232+ kind = "LedgerService::dump - Failed reconstruct" ,
1233+ summary = format!( "Reconstruction saved to: {FILENAME:?}" )
1234+ ) ;
1235+
1236+ Ok ( ( ) )
1237+ }
1238+
11621239/// Save staged ledger and block to file, when the application fail.
11631240/// So we can easily reproduce the application both in Rust and OCaml, to compare them.
11641241/// - https://github.com/openmina/openmina/blob/8e68037aafddd43842a54c8439baeafee4c6e1eb/ledger/src/staged_ledger/staged_ledger.rs#L5959
0 commit comments