From 1b06226c17d04684059efb2690da5d7a9b3e6acb Mon Sep 17 00:00:00 2001 From: Roman Zeyde Date: Mon, 28 Aug 2023 13:55:41 +0300 Subject: [PATCH] Add txid collision scanner (#928) --- examples/tx_collisions.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 examples/tx_collisions.rs diff --git a/examples/tx_collisions.rs b/examples/tx_collisions.rs new file mode 100644 index 0000000..54aee00 --- /dev/null +++ b/examples/tx_collisions.rs @@ -0,0 +1,31 @@ +use anyhow::{Context, Result}; +use electrs_rocksdb::{ColumnFamilyDescriptor, IteratorMode, Options, DB}; + +fn main() -> Result<()> { + let path = std::env::args().skip(1).next().context("missing DB path")?; + let cf_names = DB::list_cf(&Options::default(), &path)?; + let cfs: Vec<_> = cf_names + .iter() + .map(|name| ColumnFamilyDescriptor::new(name, Options::default())) + .collect(); + let db = DB::open_cf_descriptors(&Options::default(), &path, cfs)?; + let cf = db.cf_handle("txid").context("missing column family")?; + + let mut state: Option<(u64, u32)> = None; + for row in db.iterator_cf(cf, IteratorMode::Start) { + let (curr, _value) = row?; + let curr_prefix = u64::from_le_bytes(curr[..8].try_into()?); + let curr_height = u32::from_le_bytes(curr[8..].try_into()?); + + if let Some((prev_prefix, prev_height)) = state { + if prev_prefix == curr_prefix { + eprintln!( + "prefix={:x} heights: {} {}", + curr_prefix, prev_height, curr_height + ); + }; + } + state = Some((curr_prefix, curr_height)); + } + Ok(()) +}