Skip to content

Commit

Permalink
feat: add command to check stacks db integrity
Browse files Browse the repository at this point in the history
  • Loading branch information
lgalabru committed Jun 9, 2023
1 parent 6dacc3a commit 322f473
Showing 1 changed file with 61 additions and 12 deletions.
73 changes: 61 additions & 12 deletions components/chainhook-cli/src/cli/mod.rs
Expand Up @@ -4,6 +4,9 @@ use crate::config::{Config, PredicatesApi};
use crate::scan::bitcoin::scan_bitcoin_chainstate_via_rpc_using_predicate;
use crate::scan::stacks::scan_stacks_chainstate_via_csv_using_predicate;
use crate::service::Service;
use crate::storage::{
get_last_block_height_inserted, is_stacks_block_present, open_readonly_stacks_db_conn,
};

use chainhook_sdk::bitcoincore_rpc::{Auth, Client, RpcApi};
use chainhook_sdk::chainhooks::types::{
Expand Down Expand Up @@ -59,9 +62,12 @@ enum Command {
/// Run a service streaming blocks and evaluating registered predicates
#[clap(subcommand)]
Service(ServiceCommand),
/// Explore the Ordinal Theory
/// Ordinals related subcommands
#[clap(subcommand)]
Hord(HordCommand),
/// Stacks related subcommands
#[clap(subcommand)]
Stacks(StacksCommand),
}

#[derive(Subcommand, PartialEq, Clone, Debug)]
Expand Down Expand Up @@ -192,14 +198,14 @@ struct StartCommand {
enum HordCommand {
/// Db maintenance related commands
#[clap(subcommand)]
Db(DbCommand),
Db(HordDbCommand),
/// Db maintenance related commands
#[clap(subcommand)]
Scan(ScanCommand),
}

#[derive(Subcommand, PartialEq, Clone, Debug)]
enum DbCommand {
enum HordDbCommand {
/// Rewrite hord db
#[clap(name = "rewrite", bin_name = "rewrite")]
Rewrite(UpdateHordDbCommand),
Expand All @@ -211,7 +217,7 @@ enum DbCommand {
Drop(DropHordDbCommand),
/// Check integrity
#[clap(name = "check", bin_name = "check")]
Check(CheckHordDbCommand),
Check(CheckDbCommand),
/// Patch DB
#[clap(name = "patch", bin_name = "patch")]
Patch(PatchHordDbCommand),
Expand All @@ -220,6 +226,20 @@ enum DbCommand {
Migrate(MigrateHordDbCommand),
}

#[derive(Subcommand, PartialEq, Clone, Debug)]
enum StacksCommand {
/// Db maintenance related commands
#[clap(subcommand)]
Db(StacksDbCommand),
}

#[derive(Subcommand, PartialEq, Clone, Debug)]
enum StacksDbCommand {
/// Check integrity
#[clap(name = "check", bin_name = "check")]
Check(CheckDbCommand),
}

#[derive(Subcommand, PartialEq, Clone, Debug)]
enum ScanCommand {
/// Compute ordinal number of the 1st satoshi of the 1st input of a given transaction
Expand Down Expand Up @@ -348,7 +368,7 @@ struct MigrateHordDbCommand {
}

#[derive(Parser, PartialEq, Clone, Debug)]
struct CheckHordDbCommand {
struct CheckDbCommand {
/// Load config file path
#[clap(long = "config-path")]
pub config_path: Option<String>,
Expand Down Expand Up @@ -752,7 +772,7 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
}
},
Command::Hord(HordCommand::Db(subcmd)) => match subcmd {
DbCommand::Sync(cmd) => {
HordDbCommand::Sync(cmd) => {
let config = Config::default(false, false, false, &cmd.config_path)?;
if let Some((start_block, end_block)) = should_sync_hord_db(&config, &ctx)? {
if start_block == 0 {
Expand All @@ -778,7 +798,7 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
info!(ctx.expect_logger(), "Database hord up to date");
}
}
DbCommand::Rewrite(cmd) => {
HordDbCommand::Rewrite(cmd) => {
let config = Config::default(false, false, false, &cmd.config_path)?;
// Delete data, if any
{
Expand All @@ -805,15 +825,15 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
)
.await?;
}
DbCommand::Check(cmd) => {
HordDbCommand::Check(cmd) => {
let config = Config::default(false, false, false, &cmd.config_path)?;
// Delete data, if any
{
let blocks_db_rw =
open_readwrite_hord_db_conn_rocks_db(&config.expected_cache_path(), &ctx)?;

let mut missing_blocks = vec![];
for i in 1..=780000 {
for i in 1..=790000 {
if find_lazy_block_at_block_height(i, 3, &blocks_db_rw).is_none() {
println!("Missing block {i}");
missing_blocks.push(i);
Expand All @@ -822,7 +842,7 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
println!("{:?}", missing_blocks);
}
}
DbCommand::Drop(cmd) => {
HordDbCommand::Drop(cmd) => {
let config = Config::default(false, false, false, &cmd.config_path)?;
let blocks_db =
open_readwrite_hord_db_conn_rocks_db(&config.expected_cache_path(), &ctx)?;
Expand All @@ -842,13 +862,42 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
cmd.end_block - cmd.start_block + 1
);
}
DbCommand::Patch(_cmd) => {
HordDbCommand::Patch(_cmd) => {
unimplemented!()
}
DbCommand::Migrate(_cmd) => {
HordDbCommand::Migrate(_cmd) => {
unimplemented!()
}
},
Command::Stacks(StacksCommand::Db(StacksDbCommand::Check(cmd))) => {
let config = Config::default(false, false, false, &cmd.config_path)?;
// Delete data, if any
{
let stacks_db = open_readonly_stacks_db_conn(&config.expected_cache_path(), &ctx)?;
let mut missing_blocks = vec![];
if let Some(tip) = get_last_block_height_inserted(&stacks_db, &ctx) {
for index in 1..=tip {
let block_identifier = BlockIdentifier {
index: i,
hash: "".into(),
};
if !is_stacks_block_present(&block_identifier, 3, &stacks_db) {
missing_blocks.push(i);
}
}
}
if missing_blocks.is_empty() {
info!(ctx.expect_logger(), "Stacks db successfully checked");
} else {
warn!(
ctx.expect_logger(),
"Stacks db includes {} missing entries: {:?}",
missing_blocks.len(),
missing_blocks
);
}
}
}
}
Ok(())
}
Expand Down

0 comments on commit 322f473

Please sign in to comment.