@@ -2,10 +2,12 @@ use clap::{
22 crate_description, crate_name, value_t, value_t_or_exit, values_t_or_exit, App , Arg ,
33 ArgMatches , SubCommand ,
44} ;
5+ use regex:: Regex ;
56use serde_json:: json;
67use solana_clap_utils:: input_validators:: { is_parsable, is_slot} ;
78use solana_ledger:: entry:: Entry ;
89use solana_ledger:: {
10+ ancestor_iterator:: AncestorIterator ,
911 bank_forks_utils,
1012 blockstore:: Blockstore ,
1113 blockstore_db:: { self , AccessType , Column , Database } ,
@@ -25,11 +27,11 @@ use solana_sdk::{
2527} ;
2628use solana_vote_program:: vote_state:: VoteState ;
2729use std:: {
28- collections:: { BTreeMap , HashMap , HashSet } ,
30+ collections:: { BTreeMap , BTreeSet , HashMap , HashSet } ,
2931 convert:: TryInto ,
3032 ffi:: OsStr ,
3133 fs:: { self , File } ,
32- io:: { self , stdout, Write } ,
34+ io:: { self , stdout, BufRead , BufReader , Write } ,
3335 path:: { Path , PathBuf } ,
3436 process:: { exit, Command , Stdio } ,
3537 str:: FromStr ,
@@ -834,6 +836,25 @@ fn main() {
834836 . about ( "Prints the ledger's genesis config" )
835837 . arg ( & max_genesis_archive_unpacked_size_arg)
836838 )
839+ . subcommand (
840+ SubCommand :: with_name ( "parse_full_frozen" )
841+ . about ( "Parses log for information about critical events about ancestors of the given `ending_slot`" )
842+ . arg ( & starting_slot_arg)
843+ . arg (
844+ Arg :: with_name ( "ending_slot" )
845+ . long ( "ending-slot" )
846+ . value_name ( "SLOT" )
847+ . takes_value ( true )
848+ . help ( "The last slot to iterate to" ) ,
849+ )
850+ . arg (
851+ Arg :: with_name ( "log_path" )
852+ . long ( "log-path" )
853+ . value_name ( "PATH" )
854+ . takes_value ( true )
855+ . help ( "path to log file to parse" ) ,
856+ )
857+ )
837858 . subcommand (
838859 SubCommand :: with_name ( "genesis-hash" )
839860 . about ( "Prints the ledger's genesis hash" )
@@ -1134,6 +1155,70 @@ fn main() {
11341155 }
11351156 }
11361157 }
1158+ ( "parse_full_frozen" , Some ( arg_matches) ) => {
1159+ let starting_slot = value_t_or_exit ! ( arg_matches, "starting_slot" , Slot ) ;
1160+ let ending_slot = value_t_or_exit ! ( arg_matches, "ending_slot" , Slot ) ;
1161+ let blockstore = open_blockstore ( & ledger_path, AccessType :: TryPrimaryThenSecondary ) ;
1162+ let mut ancestors = BTreeSet :: new ( ) ;
1163+ if blockstore. meta ( ending_slot) . unwrap ( ) . is_none ( ) {
1164+ panic ! ( "Ending slot doesn't exist" ) ;
1165+ }
1166+ for a in AncestorIterator :: new ( ending_slot, & blockstore) {
1167+ ancestors. insert ( a) ;
1168+ if a <= starting_slot {
1169+ break ;
1170+ }
1171+ }
1172+ println ! ( "ancestors: {:?}" , ancestors. iter( ) ) ;
1173+
1174+ let mut frozen = BTreeMap :: new ( ) ;
1175+ let mut full = BTreeMap :: new ( ) ;
1176+ let frozen_regex = Regex :: new ( r"bank frozen: (\d*)" ) . unwrap ( ) ;
1177+ let full_regex = Regex :: new ( r"slot (\d*) is full" ) . unwrap ( ) ;
1178+
1179+ let log_file = PathBuf :: from ( value_t_or_exit ! ( arg_matches, "log_path" , String ) ) ;
1180+ let f = BufReader :: new ( File :: open ( log_file) . unwrap ( ) ) ;
1181+ println ! ( "Reading log file" ) ;
1182+ for line in f. lines ( ) {
1183+ if let Ok ( line) = line {
1184+ let parse_results = {
1185+ if let Some ( slot_string) = frozen_regex. captures_iter ( & line) . next ( ) {
1186+ Some ( ( slot_string, & mut frozen) )
1187+ } else if let Some ( slot_string) = full_regex. captures_iter ( & line) . next ( ) {
1188+ Some ( ( slot_string, & mut full) )
1189+ } else {
1190+ None
1191+ }
1192+ } ;
1193+
1194+ if let Some ( ( slot_string, map) ) = parse_results {
1195+ let slot = slot_string
1196+ . get ( 1 )
1197+ . expect ( "Only one match group" )
1198+ . as_str ( )
1199+ . parse :: < u64 > ( )
1200+ . unwrap ( ) ;
1201+ if ancestors. contains ( & slot) && !map. contains_key ( & slot) {
1202+ map. insert ( slot, line) ;
1203+ }
1204+ if slot == starting_slot
1205+ && frozen. contains_key ( & slot)
1206+ && full. contains_key ( & slot)
1207+ {
1208+ break ;
1209+ }
1210+ }
1211+ }
1212+ }
1213+
1214+ for ( ( slot1, frozen_log) , ( slot2, full_log) ) in frozen. iter ( ) . zip ( full. iter ( ) ) {
1215+ assert_eq ! ( slot1, slot2) ;
1216+ println ! (
1217+ "Slot: {}\n , full: {}\n , frozen: {}" ,
1218+ slot1, full_log, frozen_log
1219+ ) ;
1220+ }
1221+ }
11371222 ( "verify" , Some ( arg_matches) ) => {
11381223 let process_options = ProcessOptions {
11391224 dev_halt_at_slot : value_t ! ( arg_matches, "halt_at_slot" , Slot ) . ok ( ) ,
0 commit comments