mirror of
https://github.com/alexgo-io/bitcoin-indexer.git
synced 2026-01-12 22:43:06 +08:00
fix: validate and wait for bitcoind block height responses (#340)
* fix: validate and wait for bitcoind block height responses * chore: comments
This commit is contained in:
@@ -2,7 +2,6 @@ use crate::config::file::ConfigFile;
|
||||
use crate::config::generator::generate_config;
|
||||
use clap::{Parser, Subcommand};
|
||||
use hiro_system_kit;
|
||||
use ordhook::chainhook_sdk::bitcoincore_rpc::{Auth, Client, RpcApi};
|
||||
use ordhook::chainhook_sdk::chainhooks::types::{
|
||||
BitcoinChainhookSpecification, HttpHook, InscriptionFeedData, OrdinalsMetaProtocol,
|
||||
};
|
||||
@@ -35,6 +34,7 @@ use ordhook::download::download_ordinals_dataset_if_required;
|
||||
use ordhook::scan::bitcoin::scan_bitcoin_chainstate_via_rpc_using_predicate;
|
||||
use ordhook::service::observers::initialize_observers_db;
|
||||
use ordhook::service::{start_observer_forwarding, Service};
|
||||
use ordhook::utils::bitcoind::bitcoind_get_block_height;
|
||||
use ordhook::{hex, initialize_db};
|
||||
use reqwest::Client as HttpClient;
|
||||
use std::collections::HashSet;
|
||||
@@ -553,7 +553,7 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
ctx.expect_logger(),
|
||||
"Checking {}...", config.network.bitcoind_rpc_url
|
||||
);
|
||||
let tip = check_bitcoind_connection(&config).await?;
|
||||
let tip = bitcoind_get_block_height(&config, ctx);
|
||||
if let Some(highest_desired) = block_range.pop_back() {
|
||||
if tip < highest_desired {
|
||||
error!(ctx.expect_logger(), "Unable to scan desired block range: underlying bitcoind synchronized until block #{} ", tip);
|
||||
@@ -1035,29 +1035,6 @@ pub fn build_predicate_from_cli(
|
||||
Ok(predicate)
|
||||
}
|
||||
|
||||
pub async fn check_bitcoind_connection(config: &Config) -> Result<u64, String> {
|
||||
let auth = Auth::UserPass(
|
||||
config.network.bitcoind_rpc_username.clone(),
|
||||
config.network.bitcoind_rpc_password.clone(),
|
||||
);
|
||||
|
||||
let bitcoin_rpc = match Client::new(&config.network.bitcoind_rpc_url, auth) {
|
||||
Ok(con) => con,
|
||||
Err(message) => {
|
||||
return Err(format!("unable to connect to bitcoind: {}", message));
|
||||
}
|
||||
};
|
||||
|
||||
let end_block = match bitcoin_rpc.get_blockchain_info() {
|
||||
Ok(result) => result.blocks,
|
||||
Err(e) => {
|
||||
return Err(format!("unable to connect to bitcoind: {}", e));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(end_block)
|
||||
}
|
||||
|
||||
fn parse_blocks_heights_spec(
|
||||
blocks_interval: &Option<String>,
|
||||
blocks: &Option<String>,
|
||||
|
||||
@@ -8,14 +8,11 @@ use std::hash::BuildHasherDefault;
|
||||
use std::ops::Div;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use chainhook_sdk::{
|
||||
bitcoincore_rpc::{Auth, Client, RpcApi},
|
||||
utils::Context,
|
||||
};
|
||||
use chainhook_sdk::utils::Context;
|
||||
|
||||
use crate::{
|
||||
config::{Config, LogConfig, MetaProtocolsConfig, ResourcesConfig},
|
||||
db::{find_pinned_block_bytes_at_block_height, open_ordhook_db_conn_rocks_db_loop},
|
||||
db::{find_pinned_block_bytes_at_block_height, open_ordhook_db_conn_rocks_db_loop}, utils::bitcoind::bitcoind_get_block_height,
|
||||
};
|
||||
|
||||
use crate::db::{
|
||||
@@ -144,18 +141,6 @@ pub fn should_sync_ordhook_db(
|
||||
config: &Config,
|
||||
ctx: &Context,
|
||||
) -> Result<Option<(u64, u64, usize)>, String> {
|
||||
let auth = Auth::UserPass(
|
||||
config.network.bitcoind_rpc_username.clone(),
|
||||
config.network.bitcoind_rpc_password.clone(),
|
||||
);
|
||||
|
||||
let bitcoin_rpc = match Client::new(&config.network.bitcoind_rpc_url, auth) {
|
||||
Ok(con) => con,
|
||||
Err(message) => {
|
||||
return Err(format!("Bitcoin RPC error: {}", message.to_string()));
|
||||
}
|
||||
};
|
||||
|
||||
let blocks_db = open_ordhook_db_conn_rocks_db_loop(
|
||||
true,
|
||||
&config.expected_cache_path(),
|
||||
@@ -186,17 +171,8 @@ pub fn should_sync_ordhook_db(
|
||||
}
|
||||
};
|
||||
|
||||
let end_block = match bitcoin_rpc.get_blockchain_info() {
|
||||
Ok(result) => result.blocks,
|
||||
Err(e) => {
|
||||
return Err(format!(
|
||||
"unable to retrieve Bitcoin chain tip ({})",
|
||||
e.to_string()
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: Gracefully handle Regtest, Testnet and Signet
|
||||
let end_block = bitcoind_get_block_height(config, ctx);
|
||||
let (mut end_block, speed) = if start_block < 200_000 {
|
||||
(end_block.min(200_000), 10_000)
|
||||
} else if start_block < 550_000 {
|
||||
|
||||
@@ -22,9 +22,8 @@ use chainhook_sdk::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
config::Config,
|
||||
core::{
|
||||
meta_protocols::brc20::db::{delete_activity_in_block_range, open_readwrite_brc20_db_conn},
|
||||
meta_protocols::brc20::db::delete_activity_in_block_range,
|
||||
protocol::inscription_parsing::{
|
||||
get_inscriptions_revealed_in_block, get_inscriptions_transferred_in_block,
|
||||
},
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::config::Config;
|
||||
use crate::core::meta_protocols::brc20::brc20_activation_height;
|
||||
use crate::core::meta_protocols::brc20::db::open_readonly_brc20_db_conn;
|
||||
use crate::core::protocol::inscription_parsing::{
|
||||
get_inscriptions_revealed_in_block, get_inscriptions_transferred_in_block,
|
||||
@@ -11,8 +10,7 @@ use crate::download::download_ordinals_dataset_if_required;
|
||||
use crate::service::observers::{
|
||||
open_readwrite_observers_db_conn_or_panic, update_observer_progress,
|
||||
};
|
||||
use chainhook_sdk::bitcoincore_rpc::RpcApi;
|
||||
use chainhook_sdk::bitcoincore_rpc::{Auth, Client};
|
||||
use crate::utils::bitcoind::bitcoind_get_block_height;
|
||||
use chainhook_sdk::chainhooks::bitcoin::{
|
||||
evaluate_bitcoin_chainhooks_on_chain_event, handle_bitcoin_hook_action,
|
||||
BitcoinChainhookOccurrence, BitcoinTriggerChainhook,
|
||||
@@ -37,18 +35,6 @@ pub async fn scan_bitcoin_chainstate_via_rpc_using_predicate(
|
||||
ctx: &Context,
|
||||
) -> Result<(), String> {
|
||||
let _ = download_ordinals_dataset_if_required(config, ctx).await;
|
||||
|
||||
let auth = Auth::UserPass(
|
||||
config.network.bitcoind_rpc_username.clone(),
|
||||
config.network.bitcoind_rpc_password.clone(),
|
||||
);
|
||||
|
||||
let bitcoin_rpc = match Client::new(&config.network.bitcoind_rpc_url, auth) {
|
||||
Ok(con) => con,
|
||||
Err(message) => {
|
||||
return Err(format!("Bitcoin RPC error: {}", message.to_string()));
|
||||
}
|
||||
};
|
||||
let mut floating_end_block = false;
|
||||
|
||||
let block_heights_to_scan_res = if let Some(ref blocks) = predicate_spec.blocks {
|
||||
@@ -65,15 +51,7 @@ pub async fn scan_bitcoin_chainstate_via_rpc_using_predicate(
|
||||
};
|
||||
let (end_block, update_end_block) = match predicate_spec.end_block {
|
||||
Some(end_block) => (end_block, false),
|
||||
None => match bitcoin_rpc.get_blockchain_info() {
|
||||
Ok(result) => (result.blocks, true),
|
||||
Err(e) => {
|
||||
return Err(format!(
|
||||
"unable to retrieve Bitcoin chain tip ({})",
|
||||
e.to_string()
|
||||
));
|
||||
}
|
||||
},
|
||||
None => (bitcoind_get_block_height(config, ctx), true),
|
||||
};
|
||||
floating_end_block = update_end_block;
|
||||
BlockHeights::BlockRange(start_block, end_block).get_sorted_entries()
|
||||
@@ -195,20 +173,16 @@ pub async fn scan_bitcoin_chainstate_via_rpc_using_predicate(
|
||||
)
|
||||
}
|
||||
if block_heights_to_scan.is_empty() && floating_end_block {
|
||||
let new_tip = match bitcoin_rpc.get_blockchain_info() {
|
||||
Ok(result) => match predicate_spec.end_block {
|
||||
Some(end_block) => {
|
||||
if end_block > result.blocks {
|
||||
result.blocks
|
||||
} else {
|
||||
end_block
|
||||
}
|
||||
let bitcoind_chain_tip = bitcoind_get_block_height(config, ctx);
|
||||
let new_tip = match predicate_spec.end_block {
|
||||
Some(end_block) => {
|
||||
if end_block > bitcoind_chain_tip {
|
||||
bitcoind_chain_tip
|
||||
} else {
|
||||
end_block
|
||||
}
|
||||
None => result.blocks,
|
||||
},
|
||||
Err(_e) => {
|
||||
continue;
|
||||
}
|
||||
None => bitcoind_chain_tip,
|
||||
};
|
||||
|
||||
for entry in (current_block_height + 1)..new_tip {
|
||||
|
||||
41
components/ordhook-core/src/utils/bitcoind.rs
Normal file
41
components/ordhook-core/src/utils/bitcoind.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
use chainhook_sdk::{bitcoincore_rpc::{Auth, Client, RpcApi}, utils::Context};
|
||||
|
||||
use crate::{config::Config, try_error};
|
||||
|
||||
fn bitcoind_get_client(config: &Config, ctx: &Context) -> Client {
|
||||
loop {
|
||||
let auth = Auth::UserPass(
|
||||
config.network.bitcoind_rpc_username.clone(),
|
||||
config.network.bitcoind_rpc_password.clone(),
|
||||
);
|
||||
match Client::new(&config.network.bitcoind_rpc_url, auth) {
|
||||
Ok(con) => {
|
||||
return con;
|
||||
}
|
||||
Err(e) => {
|
||||
try_error!(ctx, "bitcoind unable to get client: {}", e.to_string());
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieves the block height from bitcoind.
|
||||
pub fn bitcoind_get_block_height(config: &Config, ctx: &Context) -> u64 {
|
||||
let bitcoin_rpc = bitcoind_get_client(config, ctx);
|
||||
loop {
|
||||
match bitcoin_rpc.get_blockchain_info() {
|
||||
Ok(result) => {
|
||||
return result.blocks;
|
||||
}
|
||||
Err(e) => {
|
||||
try_error!(
|
||||
ctx,
|
||||
"bitcoind unable to get block height: {}",
|
||||
e.to_string()
|
||||
);
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
39
components/ordhook-core/src/utils/logger.rs
Normal file
39
components/ordhook-core/src/utils/logger.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
#[macro_export]
|
||||
macro_rules! try_info {
|
||||
($a:expr, $tag:expr, $($args:tt)*) => {
|
||||
$a.try_log(|l| info!(l, $tag, $($args)*));
|
||||
};
|
||||
($a:expr, $tag:expr) => {
|
||||
$a.try_log(|l| info!(l, $tag));
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! try_debug {
|
||||
($a:expr, $tag:expr, $($args:tt)*) => {
|
||||
$a.try_log(|l| debug!(l, $tag, $($args)*));
|
||||
};
|
||||
($a:expr, $tag:expr) => {
|
||||
$a.try_log(|l| debug!(l, $tag));
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! try_warn {
|
||||
($a:expr, $tag:expr, $($args:tt)*) => {
|
||||
$a.try_log(|l| warn!(l, $tag, $($args)*));
|
||||
};
|
||||
($a:expr, $tag:expr) => {
|
||||
$a.try_log(|l| warn!(l, $tag));
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! try_error {
|
||||
($a:expr, $tag:expr, $($args:tt)*) => {
|
||||
$a.try_log(|l| error!(l, $tag, $($args)*));
|
||||
};
|
||||
($a:expr, $tag:expr) => {
|
||||
$a.try_log(|l| error!(l, $tag));
|
||||
};
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
pub mod bitcoind;
|
||||
pub mod logger;
|
||||
|
||||
use std::{
|
||||
fs,
|
||||
io::{Read, Write},
|
||||
|
||||
Reference in New Issue
Block a user