Skip to content

Commit

Permalink
Add --check-index subcommand to passively check the index file.
Browse files Browse the repository at this point in the history
  • Loading branch information
gmart7t2 committed Aug 3, 2023
1 parent 5bb9432 commit 0890d9c
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 10 deletions.
22 changes: 12 additions & 10 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,16 +178,8 @@ impl Index {
}
};

if let Ok(mut file) = fs::OpenOptions::new().read(true).open(&path) {
// use cberner's quick hack to check the redb recovery bit
// https://github.com/cberner/redb/issues/639#issuecomment-1628037591
const MAGICNUMBER: [u8; 9] = [b'r', b'e', b'd', b'b', 0x1A, 0x0A, 0xA9, 0x0D, 0x0A];
const RECOVERY_REQUIRED: u8 = 2;

let mut buffer = [0; MAGICNUMBER.len() + 1];
file.read_exact(&mut buffer).unwrap();

if buffer[MAGICNUMBER.len()] & RECOVERY_REQUIRED != 0 {
if let Ok(file) = fs::OpenOptions::new().read(true).open(&path) {
if Self::is_index_file_corrupted(file) {
println!("Index file {:?} needs recovery. This can take a long time, especially for the --index-sats index.", path);
}
}
Expand Down Expand Up @@ -1337,6 +1329,16 @@ impl Index {

Ok(result)
}

pub(crate) fn is_index_file_corrupted(mut file: File) -> bool {
// use cberner's quick hack to check the redb recovery bit
// https://github.com/cberner/redb/issues/639#issuecomment-1628037591
const MAGICNUMBER: [u8; 9] = [b'r', b'e', b'd', b'b', 0x1A, 0x0A, 0xA9, 0x0D, 0x0A];
const RECOVERY_REQUIRED: u8 = 2;

let mut buffer = [0; MAGICNUMBER.len() + 1];
file.read_exact(&mut buffer).is_err() || buffer[MAGICNUMBER.len()] & RECOVERY_REQUIRED != 0
}
}

#[cfg(test)]
Expand Down
4 changes: 4 additions & 0 deletions src/subcommand.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::*;

pub mod check_index;
pub mod decode;
pub mod epochs;
pub mod find;
Expand All @@ -24,6 +25,8 @@ fn print_json(output: impl Serialize) -> Result {

#[derive(Debug, Parser)]
pub(crate) enum Subcommand {
#[clap(about = "Check whether the index file needs recovery without attempting recovery")]
CheckIndex(check_index::CheckIndex),
#[clap(about = "Decode inscription data from a transaction output")]
Decode(decode::Decode),
#[clap(about = "List the first satoshis of each reward epoch")]
Expand Down Expand Up @@ -59,6 +62,7 @@ pub(crate) enum Subcommand {
impl Subcommand {
pub(crate) fn run(self, options: Options) -> Result {
match self {
Self::CheckIndex(check_index) => check_index.run(options),
Self::Decode(decode) => decode.run(options),
Self::Epochs => epochs::run(),
Self::Preview(preview) => preview.run(),
Expand Down
27 changes: 27 additions & 0 deletions src/subcommand/check_index.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use super::*;

#[derive(Debug, Parser)]
pub(crate) struct CheckIndex {
}

impl CheckIndex {
pub(crate) fn run(self, options: Options) -> Result {
let path = if let Some(path) = &options.index {
path.clone()
} else {
options.data_dir()?.join("index.redb")
};

if let Ok(file) = fs::OpenOptions::new().read(true).open(&path) {
if Index::is_index_file_corrupted(file) {
println!("Index file {:?} needs recovery.", path);
} else {
println!("Index file {:?} doesn't need recovery.", path);
}
} else {
println!("Can't open {:?} for reading", path);
}

Ok(())
}
}

0 comments on commit 0890d9c

Please sign in to comment.