use svmscope::reconstruct::{reconstruct_account, RpcLedger};
use svmscope::Scope;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let rpc =
std::env::var("RPC").unwrap_or_else(|_| "https://api.mainnet-beta.solana.com".to_string());
let address = std::env::args().nth(1).expect("usage: … <address>");
let scope = Scope::new(&rpc);
let ledger = RpcLedger::new(&rpc);
let tip = scope.client().get_slot()?;
println!("reconstructing {address} up to current tip (slot {tip})…");
let recon = reconstruct_account(&scope, &ledger, &address, tip + 1, 80, 40)?;
println!(
" writes replayed: {} skipped: {} exists: {}",
recon.writes_replayed,
recon.writes_skipped,
recon.state.is_some()
);
let actual = scope.account_data(&address)?;
match (recon.state, actual) {
(Some(r), Some(a)) => {
let data_match = r.data == a.data;
println!(
" reconstructed data {} bytes · actual {} bytes",
r.data.len(),
a.data.len()
);
println!(
" DATA MATCH: {}{}",
if data_match {
"✅ exact"
} else {
"❌ differs"
},
if recon.writes_skipped > 0 {
" (writes were skipped — expected to differ)"
} else {
""
}
);
if !data_match {
let n = r.data.len().min(a.data.len());
let first_diff = (0..n).find(|&i| r.data[i] != a.data[i]);
println!(" first differing byte offset: {first_diff:?}");
}
}
(None, None) => println!(" both agree: account does not exist"),
(r, a) => println!(
" existence mismatch: reconstructed={} actual={}",
r.is_some(),
a.is_some()
),
}
Ok(())
}