use anyhow::Context;
use blvm_node::node::parallel_ibd::local_block::{
probe_confirmed_body_height, probe_highest_stored_body_height,
};
use blvm_node::storage::Storage;
use std::path::PathBuf;
fn main() -> anyhow::Result<()> {
let mut args = std::env::args().skip(1);
let data_dir = PathBuf::from(
args.next()
.context("usage: strip_bodies_above DATA_DIR KEEP_BODY_MAX_HEIGHT")?,
);
let keep_max: u64 = args
.next()
.context("missing KEEP_BODY_MAX_HEIGHT")?
.parse()
.context("KEEP_BODY_MAX_HEIGHT")?;
let storage = Storage::new(&data_dir)?;
let blockstore = storage.blocks();
let confirmed = probe_confirmed_body_height(&blockstore)?;
let highest = probe_highest_stored_body_height(&blockstore)?;
let before = confirmed.max(highest);
let header_max = blockstore.highest_stored_height()?.unwrap_or(0);
println!(
"before confirmed_body={confirmed} highest_body={highest} strip_to={before} header_max={header_max} keep_max={keep_max}"
);
if before <= keep_max {
println!("noop: body tip already ≤ keep_max");
return Ok(());
}
let start = keep_max.saturating_add(1);
let removed = blockstore.remove_blocks_by_height_range(start, before)?;
for h in start..=before {
if let Some(hash) = blockstore.get_hash_by_height(h)? {
let _ = blockstore.remove_witness(&hash);
}
}
let after_c = probe_confirmed_body_height(&blockstore)?;
let after_h = probe_highest_stored_body_height(&blockstore)?;
println!("removed_bodies≈{removed} after confirmed_body={after_c} highest_body={after_h}");
if after_c.max(after_h) > keep_max {
anyhow::bail!(
"strip failed: confirmed={after_c} highest={after_h} still > keep_max={keep_max}"
);
}
Ok(())
}