Skip to content

Commit a6fd22b

Browse files
committed
chore: Move replay-block back to stacks-inspect
1 parent d4a9215 commit a6fd22b

File tree

3 files changed

+91
-90
lines changed

3 files changed

+91
-90
lines changed

stackslib/src/main.rs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use std::collections::{BTreeMap, HashMap, HashSet};
3939
use std::fs::{File, OpenOptions};
4040
use std::io::prelude::*;
4141
use std::io::BufReader;
42+
use std::path::PathBuf;
4243
use std::time::Instant;
4344
use std::{env, fs, io, process, thread};
4445

@@ -1341,6 +1342,11 @@ simulating a miner.
13411342
return;
13421343
}
13431344

1345+
if argv[1] == "replay-mock-mining" {
1346+
replay_mock_mining(argv);
1347+
process::exit(0);
1348+
}
1349+
13441350
if argv.len() < 4 {
13451351
eprintln!("Usage: {} blockchain network working_dir", argv[0]);
13461352
process::exit(1);
@@ -1977,3 +1983,87 @@ fn analyze_sortition_mev(argv: Vec<String>) {
19771983

19781984
process::exit(0);
19791985
}
1986+
1987+
fn replay_mock_mining(argv: Vec<String>) {
1988+
let print_help_and_exit = || -> ! {
1989+
let n = &argv[0];
1990+
eprintln!("Usage:");
1991+
eprintln!(" {n} <mock-miner-output-dir>");
1992+
process::exit(1);
1993+
};
1994+
1995+
// Process CLI args
1996+
let chainstate_path = argv
1997+
.get(2)
1998+
.unwrap_or_else(|| print_help_and_exit());
1999+
2000+
let blocks_path = argv
2001+
.get(3)
2002+
.map(PathBuf::from)
2003+
.map(fs::canonicalize)
2004+
.transpose()
2005+
.unwrap_or_else(|e| panic!("Not a valid path: {e}"))
2006+
.unwrap_or_else(|| print_help_and_exit());
2007+
2008+
// Validate directory path
2009+
if !blocks_path.is_dir() {
2010+
panic!("{blocks_path:?} is not a valid directory");
2011+
}
2012+
2013+
// Read entries in directory
2014+
let dir_entries = blocks_path
2015+
.read_dir()
2016+
.unwrap_or_else(|e| panic!("Failed to read {blocks_path:?}: {e}"))
2017+
.filter_map(|e| e.ok());
2018+
2019+
// Get filenames, filtering out anything that isn't a regular file
2020+
let filenames = dir_entries.filter_map(|e| match e.file_type() {
2021+
Ok(t) if t.is_file() => e.file_name().into_string().ok(),
2022+
_ => None,
2023+
});
2024+
2025+
// Get vec of (block_height, filename), to prepare for sorting
2026+
//
2027+
// NOTE: Trusting the filename is not ideal. We could sort on data read from the file,
2028+
// but that requires reading all files
2029+
let re = Regex::new(r"^([0-9]+\.json)$").unwrap();
2030+
let mut indexed_files = filenames
2031+
.filter_map(|filename| {
2032+
// Use regex to extract block number from filename
2033+
let Some(cap) = re.captures(&filename) else {
2034+
return None;
2035+
};
2036+
let Some(m) = cap.get(0) else {
2037+
return None;
2038+
};
2039+
let Ok(bh) = m.as_str().parse::<u64>() else {
2040+
return None;
2041+
};
2042+
Some((bh, filename))
2043+
})
2044+
.collect::<Vec<_>>();
2045+
2046+
// Sort by block height
2047+
indexed_files.sort_by_key(|(bh, _)| *bh);
2048+
2049+
if indexed_files.is_empty() {
2050+
panic!("No block files found");
2051+
}
2052+
2053+
info!(
2054+
"Replaying {} blocks starting at {}",
2055+
indexed_files.len(),
2056+
indexed_files[0].0
2057+
);
2058+
2059+
for (bh, filename) in indexed_files {
2060+
let filepath = blocks_path.join(filename);
2061+
// let block = AssembledAnchorBlock::deserialize_from_file(&filepath)
2062+
// .unwrap_or_else(|e| panic!("Error reading block {bh} from file: {e}"));
2063+
debug!("Replaying block from {filepath:?}";
2064+
"block_height" => bh,
2065+
"block" => ?block
2066+
);
2067+
// TODO: Actually replay block
2068+
}
2069+
}

testnet/stacks-node/src/main.rs

Lines changed: 1 addition & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,9 @@ extern crate stacks;
1010
#[macro_use(o, slog_log, slog_trace, slog_debug, slog_info, slog_warn, slog_error)]
1111
extern crate slog;
1212

13-
use regex::Regex;
1413
pub use stacks_common::util;
1514
use stacks_common::util::hash::hex_bytes;
1615

17-
use crate::neon_node::AssembledAnchorBlock;
18-
1916
pub mod monitoring;
2017

2118
pub mod burnchains;
@@ -34,8 +31,7 @@ pub mod syncctl;
3431
pub mod tenure;
3532

3633
use std::collections::HashMap;
37-
use std::path::PathBuf;
38-
use std::{env, fs, panic, process};
34+
use std::{env, panic, process};
3935

4036
use backtrace::Backtrace;
4137
use pico_args::Arguments;
@@ -261,82 +257,6 @@ fn cli_get_miner_spend(
261257
spend_amount
262258
}
263259

264-
fn cli_replay_mock_mining(config_path: &str, path: &str) {
265-
info!("Loading config at path {config_path}");
266-
let config = match ConfigFile::from_path(&config_path) {
267-
Ok(config_file) => Config::from_config_file(config_file, true).unwrap(),
268-
Err(e) => {
269-
warn!("Invalid config file: {e}");
270-
process::exit(1);
271-
}
272-
};
273-
274-
// Validate directory path
275-
let dir = PathBuf::from(path);
276-
let dir = fs::canonicalize(dir).unwrap_or_else(|e| panic!("{path} is not a valid path: {e}"));
277-
278-
if !dir.is_dir() {
279-
panic!("{path} is not a valid directory");
280-
}
281-
282-
// Read entries in directory
283-
let dir_entries = dir
284-
.read_dir()
285-
.unwrap_or_else(|e| panic!("Failed to read {path}: {e}"))
286-
.filter_map(|e| e.ok());
287-
288-
// Get filenames, filtering out anything that isn't a regular file
289-
let filenames = dir_entries.filter_map(|e| match e.file_type() {
290-
Ok(t) if t.is_file() => e.file_name().into_string().ok(),
291-
_ => None,
292-
});
293-
294-
// Get vec of (block_height, filename), to prepare for sorting
295-
//
296-
// NOTE: Trusting the filename is not ideal. We could sort on data read from the file,
297-
// but that requires reading all files
298-
let re = Regex::new(r"^([0-9]+\.json)$").unwrap();
299-
let mut indexed_files = filenames
300-
.filter_map(|filename| {
301-
// Use regex to extract block number from filename
302-
let Some(cap) = re.captures(&filename) else {
303-
return None;
304-
};
305-
let Some(m) = cap.get(0) else {
306-
return None;
307-
};
308-
let Ok(bh) = m.as_str().parse::<u64>() else {
309-
return None;
310-
};
311-
Some((bh, filename))
312-
})
313-
.collect::<Vec<_>>();
314-
315-
// Sort by block height
316-
indexed_files.sort_by_key(|(bh, _)| *bh);
317-
318-
if indexed_files.is_empty() {
319-
panic!("No block files found");
320-
}
321-
322-
info!(
323-
"Replaying {} blocks starting at {}",
324-
indexed_files.len(),
325-
indexed_files[0].0
326-
);
327-
328-
for (bh, filename) in indexed_files {
329-
let filepath = dir.join(filename);
330-
let block = AssembledAnchorBlock::deserialize_from_file(&filepath)
331-
.unwrap_or_else(|e| panic!("Error reading block {bh} from file: {e}"));
332-
debug!("Replaying block from {filepath:?}";
333-
"block_height" => bh,
334-
"block" => ?block
335-
);
336-
// TODO: Actually replay block
337-
}
338-
}
339-
340260
fn main() {
341261
panic::set_hook(Box::new(|panic_info| {
342262
error!("Process abort due to thread panic: {}", panic_info);
@@ -484,13 +404,6 @@ fn main() {
484404
println!("Will spend {}", spend_amount);
485405
process::exit(0);
486406
}
487-
"replay-mock-mining" => {
488-
let path: String = args.value_from_str("--path").unwrap();
489-
let config_path: String = args.value_from_str("--config").unwrap();
490-
args.finish();
491-
cli_replay_mock_mining(&config_path, &path);
492-
process::exit(0);
493-
}
494407
_ => {
495408
print_help();
496409
return;

testnet/stacks-node/src/neon_node.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ use std::cmp::Ordering as CmpOrdering;
142142
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
143143
use std::io::{Read, Write};
144144
use std::net::SocketAddr;
145-
use std::path::Path;
146145
use std::sync::mpsc::{Receiver, TrySendError};
147146
use std::thread::JoinHandle;
148147
use std::time::Duration;
@@ -190,7 +189,6 @@ use stacks::net::stackerdb::{StackerDBConfig, StackerDBSync, StackerDBs};
190189
use stacks::net::{
191190
Error as NetError, NetworkResult, PeerNetworkComms, RPCHandlerArgs, ServiceFlags,
192191
};
193-
use stacks::util::{deserialize_json_from_file, serialize_json_to_file};
194192
use stacks::util_lib::strings::{UrlString, VecDisplay};
195193
use stacks_common::codec::StacksMessageCodec;
196194
use stacks_common::types::chainstate::{

0 commit comments

Comments
 (0)