mirror of
https://github.com/alexgo-io/bitcoin-indexer.git
synced 2026-04-30 04:35:04 +08:00
fix: better handling of database locks (#200)
This commit is contained in:
@@ -9,24 +9,26 @@ use ordhook::chainhook_sdk::chainhooks::types::{
|
||||
ChainhookFullSpecification, HookAction, OrdinalOperations,
|
||||
};
|
||||
use ordhook::chainhook_sdk::indexer::bitcoin::{
|
||||
download_and_parse_block_with_retry, retrieve_block_hash_with_retry,
|
||||
build_http_client, download_and_parse_block_with_retry, retrieve_block_hash_with_retry,
|
||||
};
|
||||
use ordhook::chainhook_sdk::observer::BitcoinConfig;
|
||||
use ordhook::chainhook_sdk::types::BitcoinBlockData;
|
||||
use ordhook::chainhook_sdk::types::{BitcoinBlockData, TransactionIdentifier};
|
||||
use ordhook::chainhook_sdk::utils::BlockHeights;
|
||||
use ordhook::chainhook_sdk::utils::Context;
|
||||
use ordhook::config::Config;
|
||||
use ordhook::core::new_traversals_lazy_cache;
|
||||
use ordhook::core::pipeline::download_and_pipeline_blocks;
|
||||
use ordhook::core::pipeline::processors::block_archiving::start_block_archiving_processor;
|
||||
use ordhook::core::pipeline::processors::start_inscription_indexing_processor;
|
||||
use ordhook::core::protocol::inscription_parsing::parse_inscriptions_and_standardize_block;
|
||||
use ordhook::core::protocol::satoshi_numbering::compute_satoshi_number;
|
||||
use ordhook::db::{
|
||||
delete_data_in_ordhook_db, find_all_inscription_transfers, find_all_inscriptions_in_block,
|
||||
find_all_transfers_in_block, find_inscription_with_id, find_last_block_inserted,
|
||||
find_latest_inscription_block_height, find_lazy_block_at_block_height,
|
||||
get_default_ordhook_db_file_path, initialize_ordhook_db, open_readonly_ordhook_db_conn,
|
||||
open_readonly_ordhook_db_conn_rocks_db, open_readwrite_ordhook_db_conn,
|
||||
open_readwrite_ordhook_db_conn_rocks_db,
|
||||
open_readonly_ordhook_db_conn_rocks_db, open_readwrite_ordhook_db_conn, open_ordhook_db_conn_rocks_db_loop,
|
||||
|
||||
};
|
||||
use ordhook::download::download_ordinals_dataset_if_required;
|
||||
use ordhook::scan::bitcoin::scan_bitcoin_chainstate_via_rpc_using_predicate;
|
||||
@@ -36,6 +38,9 @@ use std::collections::BTreeMap;
|
||||
use std::io::{BufReader, Read};
|
||||
use std::path::PathBuf;
|
||||
use std::process;
|
||||
use std::sync::Arc;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[clap(author, version, about, long_about = None)]
|
||||
@@ -68,14 +73,19 @@ enum ScanCommand {
|
||||
/// Retrieve activities for a given inscription
|
||||
#[clap(name = "inscription", bin_name = "inscription")]
|
||||
Inscription(ScanInscriptionCommand),
|
||||
/// Retrieve activities for a given inscription
|
||||
#[clap(name = "transaction", bin_name = "transaction")]
|
||||
Transaction(ScanTransactionCommand),
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Clone, Debug)]
|
||||
struct ScanBlocksCommand {
|
||||
/// Starting block
|
||||
pub start_block: u64,
|
||||
/// Ending block
|
||||
pub end_block: u64,
|
||||
/// Interval of blocks (--interval 767430:800000)
|
||||
#[clap(long = "interval", conflicts_with = "blocks")]
|
||||
pub blocks_interval: Option<String>,
|
||||
/// List of blocks (--blocks 767430,767431,767433,800000)
|
||||
#[clap(long = "blocks", conflicts_with = "interval")]
|
||||
pub blocks: Option<String>,
|
||||
/// Target Regtest network
|
||||
#[clap(
|
||||
long = "regtest",
|
||||
@@ -148,6 +158,43 @@ struct ScanInscriptionCommand {
|
||||
pub config_path: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Parser, PartialEq, Clone, Debug)]
|
||||
struct ScanTransactionCommand {
|
||||
/// Block Hash
|
||||
pub block_height: u64,
|
||||
/// Inscription Id
|
||||
pub transaction_id: String,
|
||||
/// Target Regtest network
|
||||
#[clap(
|
||||
long = "regtest",
|
||||
conflicts_with = "testnet",
|
||||
conflicts_with = "mainnet"
|
||||
)]
|
||||
pub regtest: bool,
|
||||
/// Target Testnet network
|
||||
#[clap(
|
||||
long = "testnet",
|
||||
conflicts_with = "regtest",
|
||||
conflicts_with = "mainnet"
|
||||
)]
|
||||
pub testnet: bool,
|
||||
/// Target Mainnet network
|
||||
#[clap(
|
||||
long = "mainnet",
|
||||
conflicts_with = "testnet",
|
||||
conflicts_with = "regtest"
|
||||
)]
|
||||
pub mainnet: bool,
|
||||
/// Load config file path
|
||||
#[clap(
|
||||
long = "config-path",
|
||||
conflicts_with = "mainnet",
|
||||
conflicts_with = "testnet",
|
||||
conflicts_with = "regtest"
|
||||
)]
|
||||
pub config_path: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, PartialEq, Clone, Debug)]
|
||||
enum RepairCommand {
|
||||
/// Rewrite blocks data in hord.rocksdb
|
||||
@@ -187,9 +234,9 @@ impl RepairStorageCommand {
|
||||
pub fn get_blocks(&self) -> Vec<u64> {
|
||||
let blocks = match (&self.blocks_interval, &self.blocks) {
|
||||
(Some(interval), None) => {
|
||||
let blocks = interval.split(":").collect::<Vec<_>>();
|
||||
let blocks = interval.split(':').collect::<Vec<_>>();
|
||||
let start_block: u64 = blocks
|
||||
.get(0)
|
||||
.first()
|
||||
.expect("unable to get start_block")
|
||||
.parse::<u64>()
|
||||
.expect("unable to parse start_block");
|
||||
@@ -202,7 +249,7 @@ impl RepairStorageCommand {
|
||||
}
|
||||
(None, Some(blocks)) => {
|
||||
let blocks = blocks
|
||||
.split(",")
|
||||
.split(',')
|
||||
.map(|b| b.parse::<u64>().expect("unable to parse block"))
|
||||
.collect::<Vec<_>>();
|
||||
BlockHeights::Blocks(blocks).get_sorted_entries()
|
||||
@@ -467,13 +514,10 @@ pub fn main() {
|
||||
}
|
||||
};
|
||||
|
||||
match hiro_system_kit::nestable_block_on(handle_command(opts, &ctx)) {
|
||||
Err(e) => {
|
||||
error!(ctx.expect_logger(), "{e}");
|
||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
process::exit(1);
|
||||
}
|
||||
Ok(_) => {}
|
||||
if let Err(e) = hiro_system_kit::nestable_block_on(handle_command(opts, &ctx)) {
|
||||
error!(ctx.expect_logger(), "{e}");
|
||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,9 +531,8 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
// - Replay based on SQLite queries
|
||||
// If post-to:
|
||||
// - Replay that requires connection to bitcoind
|
||||
let mut block_range =
|
||||
BlockHeights::BlockRange(cmd.start_block, cmd.end_block).get_sorted_entries();
|
||||
|
||||
let block_heights = parse_blocks_heights_spec(&cmd.blocks_interval, &cmd.blocks);
|
||||
let mut block_range = block_heights.get_sorted_entries();
|
||||
if let Some(ref post_to) = cmd.post_to {
|
||||
info!(ctx.expect_logger(), "A fully synchronized bitcoind node is required for retrieving inscriptions content.");
|
||||
info!(
|
||||
@@ -497,17 +540,20 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
"Checking {}...", config.network.bitcoind_rpc_url
|
||||
);
|
||||
let tip = check_bitcoind_connection(&config).await?;
|
||||
if tip < cmd.end_block {
|
||||
error!(ctx.expect_logger(), "Unable to scan block range [{}, {}]: underlying bitcoind synchronized until block #{} ", cmd.start_block, cmd.end_block, tip);
|
||||
} else {
|
||||
info!(ctx.expect_logger(), "Starting scan");
|
||||
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);
|
||||
} else {
|
||||
info!(ctx.expect_logger(), "Starting scan");
|
||||
}
|
||||
block_range.push_back(highest_desired);
|
||||
}
|
||||
|
||||
let predicate_spec = build_predicate_from_cli(
|
||||
&config,
|
||||
&post_to,
|
||||
cmd.start_block,
|
||||
Some(cmd.end_block),
|
||||
post_to,
|
||||
Some(&block_heights),
|
||||
None,
|
||||
cmd.auth_token,
|
||||
)?
|
||||
.into_selected_network_specification(&config.network.bitcoin_network)?;
|
||||
@@ -515,7 +561,7 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
&predicate_spec,
|
||||
&config,
|
||||
None,
|
||||
&ctx,
|
||||
ctx,
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
@@ -524,12 +570,12 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
let mut total_transfers = 0;
|
||||
|
||||
let inscriptions_db_conn =
|
||||
initialize_ordhook_db(&config.expected_cache_path(), &ctx);
|
||||
initialize_ordhook_db(&config.expected_cache_path(), ctx);
|
||||
while let Some(block_height) = block_range.pop_front() {
|
||||
let inscriptions =
|
||||
find_all_inscriptions_in_block(&block_height, &inscriptions_db_conn, &ctx);
|
||||
find_all_inscriptions_in_block(&block_height, &inscriptions_db_conn, ctx);
|
||||
let mut locations =
|
||||
find_all_transfers_in_block(&block_height, &inscriptions_db_conn, &ctx);
|
||||
find_all_transfers_in_block(&block_height, &inscriptions_db_conn, ctx);
|
||||
|
||||
let mut total_transfers_in_block = 0;
|
||||
|
||||
@@ -556,7 +602,7 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
);
|
||||
}
|
||||
}
|
||||
if total_transfers_in_block > 0 && inscriptions.len() > 0 {
|
||||
if total_transfers_in_block > 0 && !inscriptions.is_empty() {
|
||||
println!(
|
||||
"Inscriptions revealed: {}, inscriptions transferred: {total_transfers_in_block}",
|
||||
inscriptions.len()
|
||||
@@ -581,9 +627,9 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
let _ = download_ordinals_dataset_if_required(&config, ctx).await;
|
||||
|
||||
let inscriptions_db_conn =
|
||||
open_readonly_ordhook_db_conn(&config.expected_cache_path(), &ctx)?;
|
||||
open_readonly_ordhook_db_conn(&config.expected_cache_path(), ctx)?;
|
||||
let (inscription, block_height) =
|
||||
match find_inscription_with_id(&cmd.inscription_id, &inscriptions_db_conn, &ctx)? {
|
||||
match find_inscription_with_id(&cmd.inscription_id, &inscriptions_db_conn, ctx)? {
|
||||
Some(entry) => entry,
|
||||
_ => {
|
||||
return Err(format!(
|
||||
@@ -602,7 +648,7 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
let transfers = find_all_inscription_transfers(
|
||||
&inscription.get_inscription_id(),
|
||||
&inscriptions_db_conn,
|
||||
&ctx,
|
||||
ctx,
|
||||
);
|
||||
for (transfer, block_height) in transfers.iter().skip(1) {
|
||||
println!(
|
||||
@@ -612,20 +658,51 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
}
|
||||
println!("Number of transfers: {}", transfers.len() - 1);
|
||||
}
|
||||
Command::Scan(ScanCommand::Transaction(cmd)) => {
|
||||
let config: Config =
|
||||
ConfigFile::default(cmd.regtest, cmd.testnet, cmd.mainnet, &cmd.config_path)?;
|
||||
let http_client = build_http_client();
|
||||
let block = fetch_and_standardize_block(
|
||||
&http_client,
|
||||
cmd.block_height,
|
||||
&config.get_event_observer_config().get_bitcoin_config(),
|
||||
ctx,
|
||||
)
|
||||
.await?;
|
||||
let transaction_identifier = TransactionIdentifier::new(&cmd.transaction_id);
|
||||
let cache = new_traversals_lazy_cache(100);
|
||||
let res = compute_satoshi_number(
|
||||
&config.get_ordhook_config().db_path,
|
||||
&block.block_identifier,
|
||||
&transaction_identifier,
|
||||
0,
|
||||
0,
|
||||
&Arc::new(cache),
|
||||
ctx,
|
||||
)?;
|
||||
println!("{:?}", res);
|
||||
}
|
||||
Command::Service(subcmd) => match subcmd {
|
||||
ServiceCommand::Start(cmd) => {
|
||||
let maintenance_enabled =
|
||||
std::env::var("ORDHOOK_MAINTENANCE").unwrap_or("0".into());
|
||||
if maintenance_enabled.eq("1") {
|
||||
info!(ctx.expect_logger(), "Entering maintenance mode (default duration = 7 days). Unset ORDHOOK_MAINTENANCE and reboot to resume operations");
|
||||
sleep(Duration::from_secs(3600 * 24 * 7))
|
||||
}
|
||||
|
||||
let config =
|
||||
ConfigFile::default(cmd.regtest, cmd.testnet, cmd.mainnet, &cmd.config_path)?;
|
||||
|
||||
let _ = initialize_ordhook_db(&config.expected_cache_path(), &ctx);
|
||||
let _ = initialize_ordhook_db(&config.expected_cache_path(), ctx);
|
||||
|
||||
let inscriptions_db_conn =
|
||||
open_readonly_ordhook_db_conn(&config.expected_cache_path(), &ctx)?;
|
||||
open_readonly_ordhook_db_conn(&config.expected_cache_path(), ctx)?;
|
||||
|
||||
let last_known_block =
|
||||
find_latest_inscription_block_height(&inscriptions_db_conn, &ctx)?;
|
||||
find_latest_inscription_block_height(&inscriptions_db_conn, ctx)?;
|
||||
if last_known_block.is_none() {
|
||||
open_readwrite_ordhook_db_conn_rocks_db(&config.expected_cache_path(), &ctx)?;
|
||||
open_ordhook_db_conn_rocks_db_loop(true, &config.expected_cache_path(), ctx);
|
||||
}
|
||||
|
||||
let ordhook_config = config.get_ordhook_config();
|
||||
@@ -653,19 +730,13 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
let predicate = build_predicate_from_cli(
|
||||
&config,
|
||||
post_to,
|
||||
start_block,
|
||||
None,
|
||||
Some(start_block),
|
||||
cmd.auth_token.clone(),
|
||||
)?;
|
||||
predicates.push(ChainhookFullSpecification::Bitcoin(predicate));
|
||||
}
|
||||
|
||||
// let predicates = cmd
|
||||
// .predicates_paths
|
||||
// .iter()
|
||||
// .map(|p| load_predicate_from_path(p))
|
||||
// .collect::<Result<Vec<ChainhookFullSpecification>, _>>()?;
|
||||
|
||||
let mut service = Service::new(config, ctx.clone());
|
||||
return service.run(predicates, None).await;
|
||||
}
|
||||
@@ -687,12 +758,12 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
},
|
||||
Command::Db(OrdhookDbCommand::New(cmd)) => {
|
||||
let config = ConfigFile::default(false, false, false, &cmd.config_path)?;
|
||||
initialize_ordhook_db(&config.expected_cache_path(), &ctx);
|
||||
open_readwrite_ordhook_db_conn_rocks_db(&config.expected_cache_path(), &ctx)?;
|
||||
initialize_ordhook_db(&config.expected_cache_path(), ctx);
|
||||
open_ordhook_db_conn_rocks_db_loop(true, &config.expected_cache_path(), ctx);
|
||||
}
|
||||
Command::Db(OrdhookDbCommand::Sync(cmd)) => {
|
||||
let config = ConfigFile::default(false, false, false, &cmd.config_path)?;
|
||||
initialize_ordhook_db(&config.expected_cache_path(), &ctx);
|
||||
initialize_ordhook_db(&config.expected_cache_path(), ctx);
|
||||
let service = Service::new(config, ctx.clone());
|
||||
service.update_state(None).await?;
|
||||
}
|
||||
@@ -715,7 +786,7 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
ordhook_config.first_inscription_height,
|
||||
Some(&block_ingestion_processor),
|
||||
10_000,
|
||||
&ctx,
|
||||
ctx,
|
||||
)
|
||||
.await?;
|
||||
if let Some(true) = cmd.debug {
|
||||
@@ -749,7 +820,7 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
let block_post_processor = match cmd.repair_observers {
|
||||
Some(true) => {
|
||||
let tx_replayer =
|
||||
start_observer_forwarding(&config.get_event_observer_config(), &ctx);
|
||||
start_observer_forwarding(&config.get_event_observer_config(), ctx);
|
||||
Some(tx_replayer)
|
||||
}
|
||||
_ => None,
|
||||
@@ -764,7 +835,7 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
ordhook_config.first_inscription_height,
|
||||
Some(&inscription_indexing_processor),
|
||||
10_000,
|
||||
&ctx,
|
||||
ctx,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
@@ -773,7 +844,7 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
let block_post_processor = match cmd.repair_observers {
|
||||
Some(true) => {
|
||||
let tx_replayer =
|
||||
start_observer_forwarding(&config.get_event_observer_config(), &ctx);
|
||||
start_observer_forwarding(&config.get_event_observer_config(), ctx);
|
||||
Some(tx_replayer)
|
||||
}
|
||||
_ => None,
|
||||
@@ -796,13 +867,13 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
let config = ConfigFile::default(false, false, false, &cmd.config_path)?;
|
||||
{
|
||||
let blocks_db =
|
||||
open_readonly_ordhook_db_conn_rocks_db(&config.expected_cache_path(), &ctx)?;
|
||||
open_readonly_ordhook_db_conn_rocks_db(&config.expected_cache_path(), ctx)?;
|
||||
let tip = find_last_block_inserted(&blocks_db) as u64;
|
||||
println!("Tip: {}", tip);
|
||||
|
||||
let mut missing_blocks = vec![];
|
||||
for i in cmd.start_block..=cmd.end_block {
|
||||
if find_lazy_block_at_block_height(i as u32, 0, false, &blocks_db, &ctx)
|
||||
if find_lazy_block_at_block_height(i as u32, 0, false, &blocks_db, ctx)
|
||||
.is_none()
|
||||
{
|
||||
println!("Missing block #{i}");
|
||||
@@ -815,16 +886,16 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
Command::Db(OrdhookDbCommand::Drop(cmd)) => {
|
||||
let config = ConfigFile::default(false, false, false, &cmd.config_path)?;
|
||||
let blocks_db =
|
||||
open_readwrite_ordhook_db_conn_rocks_db(&config.expected_cache_path(), &ctx)?;
|
||||
open_ordhook_db_conn_rocks_db_loop(true, &config.expected_cache_path(), ctx);
|
||||
let inscriptions_db_conn_rw =
|
||||
open_readwrite_ordhook_db_conn(&config.expected_cache_path(), &ctx)?;
|
||||
open_readwrite_ordhook_db_conn(&config.expected_cache_path(), ctx)?;
|
||||
|
||||
delete_data_in_ordhook_db(
|
||||
cmd.start_block,
|
||||
cmd.end_block,
|
||||
&blocks_db,
|
||||
&inscriptions_db_conn_rw,
|
||||
&ctx,
|
||||
ctx,
|
||||
)?;
|
||||
info!(
|
||||
ctx.expect_logger(),
|
||||
@@ -839,7 +910,7 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
|
||||
pub fn load_predicate_from_path(
|
||||
predicate_path: &str,
|
||||
) -> Result<ChainhookFullSpecification, String> {
|
||||
let file = std::fs::File::open(&predicate_path)
|
||||
let file = std::fs::File::open(predicate_path)
|
||||
.map_err(|e| format!("unable to read file {}\n{:?}", predicate_path, e))?;
|
||||
let mut file_reader = BufReader::new(file);
|
||||
let mut file_buffer = vec![];
|
||||
@@ -858,30 +929,35 @@ pub async fn fetch_and_standardize_block(
|
||||
ctx: &Context,
|
||||
) -> Result<BitcoinBlockData, String> {
|
||||
let block_hash =
|
||||
retrieve_block_hash_with_retry(http_client, &block_height, &bitcoin_config, &ctx).await?;
|
||||
retrieve_block_hash_with_retry(http_client, &block_height, bitcoin_config, ctx).await?;
|
||||
let block_breakdown =
|
||||
download_and_parse_block_with_retry(http_client, &block_hash, &bitcoin_config, &ctx)
|
||||
.await?;
|
||||
download_and_parse_block_with_retry(http_client, &block_hash, bitcoin_config, ctx).await?;
|
||||
|
||||
parse_inscriptions_and_standardize_block(block_breakdown, &bitcoin_config.network, &ctx)
|
||||
parse_inscriptions_and_standardize_block(block_breakdown, &bitcoin_config.network, ctx)
|
||||
.map_err(|(e, _)| e)
|
||||
}
|
||||
|
||||
pub fn build_predicate_from_cli(
|
||||
config: &Config,
|
||||
post_to: &str,
|
||||
start_block: u64,
|
||||
end_block: Option<u64>,
|
||||
block_heights: Option<&BlockHeights>,
|
||||
start_block: Option<u64>,
|
||||
auth_token: Option<String>,
|
||||
) -> Result<BitcoinChainhookFullSpecification, String> {
|
||||
let mut networks = BTreeMap::new();
|
||||
// Retrieve last block height known, and display it
|
||||
let (start_block, end_block, blocks) = match (start_block, block_heights) {
|
||||
(None, Some(BlockHeights::BlockRange(start, end))) => (Some(*start), Some(*end), None),
|
||||
(None, Some(BlockHeights::Blocks(blocks))) => (None, None, Some(blocks.clone())),
|
||||
(Some(start), None) => (Some(start), None, None),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
networks.insert(
|
||||
config.network.bitcoin_network.clone(),
|
||||
BitcoinChainhookNetworkSpecification {
|
||||
start_block: Some(start_block),
|
||||
start_block,
|
||||
end_block,
|
||||
blocks: None,
|
||||
blocks,
|
||||
expire_after_occurrence: None,
|
||||
include_proof: None,
|
||||
include_inputs: None,
|
||||
@@ -914,19 +990,47 @@ pub async fn check_bitcoind_connection(config: &Config) -> Result<u64, String> {
|
||||
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.to_string()
|
||||
));
|
||||
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.to_string()));
|
||||
return Err(format!("unable to connect to bitcoind: {}", e));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(end_block)
|
||||
}
|
||||
|
||||
fn parse_blocks_heights_spec(
|
||||
blocks_interval: &Option<String>,
|
||||
blocks: &Option<String>,
|
||||
) -> BlockHeights {
|
||||
let blocks = match (blocks_interval, blocks) {
|
||||
(Some(interval), None) => {
|
||||
let blocks = interval.split(':').collect::<Vec<_>>();
|
||||
let start_block: u64 = blocks
|
||||
.first()
|
||||
.expect("unable to get start_block")
|
||||
.parse::<u64>()
|
||||
.expect("unable to parse start_block");
|
||||
let end_block: u64 = blocks
|
||||
.get(1)
|
||||
.expect("unable to get end_block")
|
||||
.parse::<u64>()
|
||||
.expect("unable to parse end_block");
|
||||
BlockHeights::BlockRange(start_block, end_block)
|
||||
}
|
||||
(None, Some(blocks)) => {
|
||||
let blocks = blocks
|
||||
.split(',')
|
||||
.map(|b| b.parse::<u64>().expect("unable to parse block"))
|
||||
.collect::<Vec<_>>();
|
||||
BlockHeights::Blocks(blocks)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
blocks
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ impl ConfigFile {
|
||||
let config_file: ConfigFile = match toml::from_slice(&file_buffer) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
return Err(format!("Config file malformatted {}", e.to_string()));
|
||||
return Err(format!("Config file malformatted {}", e));
|
||||
}
|
||||
};
|
||||
ConfigFile::from_config_file(config_file)
|
||||
@@ -153,7 +153,7 @@ impl ConfigFile {
|
||||
(true, false, false, _) => Config::devnet_default(),
|
||||
(false, true, false, _) => Config::testnet_default(),
|
||||
(false, false, true, _) => Config::mainnet_default(),
|
||||
(false, false, false, Some(config_path)) => ConfigFile::from_file_path(&config_path)?,
|
||||
(false, false, false, Some(config_path)) => ConfigFile::from_file_path(config_path)?,
|
||||
_ => Err("Invalid combination of arguments".to_string())?,
|
||||
};
|
||||
Ok(config)
|
||||
|
||||
@@ -45,5 +45,5 @@ chainhook_internals = true
|
||||
"#,
|
||||
network = network.to_lowercase(),
|
||||
);
|
||||
return conf;
|
||||
conf
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ use chainhook_sdk::{
|
||||
|
||||
use crate::{
|
||||
config::{Config, LogConfig},
|
||||
db::{find_lazy_block_at_block_height, open_readwrite_ordhook_db_conn_rocks_db},
|
||||
db::{find_lazy_block_at_block_height, open_ordhook_db_conn_rocks_db_loop},
|
||||
};
|
||||
|
||||
use crate::db::{
|
||||
@@ -95,7 +95,7 @@ pub fn compute_next_satpoint_data(
|
||||
}
|
||||
|
||||
pub fn should_sync_rocks_db(config: &Config, ctx: &Context) -> Result<Option<(u64, u64)>, String> {
|
||||
let blocks_db = open_readwrite_ordhook_db_conn_rocks_db(&config.expected_cache_path(), &ctx)?;
|
||||
let blocks_db = open_ordhook_db_conn_rocks_db_loop(true, &config.expected_cache_path(), &ctx);
|
||||
let inscriptions_db_conn = open_readonly_ordhook_db_conn(&config.expected_cache_path(), &ctx)?;
|
||||
let last_compressed_block = find_last_block_inserted(&blocks_db) as u64;
|
||||
let last_indexed_block = match find_latest_inscription_block_height(&inscriptions_db_conn, ctx)?
|
||||
@@ -128,7 +128,7 @@ pub fn should_sync_ordhook_db(
|
||||
}
|
||||
};
|
||||
|
||||
let blocks_db = open_readwrite_ordhook_db_conn_rocks_db(&config.expected_cache_path(), &ctx)?;
|
||||
let blocks_db = open_ordhook_db_conn_rocks_db_loop(true, &config.expected_cache_path(), &ctx);
|
||||
let mut start_block = find_last_block_inserted(&blocks_db) as u64;
|
||||
|
||||
if start_block == 0 {
|
||||
|
||||
@@ -9,7 +9,7 @@ use std::{
|
||||
use crate::{
|
||||
config::Config,
|
||||
core::pipeline::{PostProcessorCommand, PostProcessorController, PostProcessorEvent},
|
||||
db::{insert_entry_in_blocks, open_readwrite_ordhook_db_conn_rocks_db, LazyBlock},
|
||||
db::{insert_entry_in_blocks, LazyBlock, open_ordhook_db_conn_rocks_db_loop},
|
||||
};
|
||||
|
||||
pub fn start_block_archiving_processor(
|
||||
@@ -26,18 +26,15 @@ pub fn start_block_archiving_processor(
|
||||
let handle: JoinHandle<()> = hiro_system_kit::thread_named("Processor Runloop")
|
||||
.spawn(move || {
|
||||
let blocks_db_rw =
|
||||
open_readwrite_ordhook_db_conn_rocks_db(&config.expected_cache_path(), &ctx)
|
||||
.unwrap();
|
||||
open_ordhook_db_conn_rocks_db_loop(true, &config.expected_cache_path(), &ctx);
|
||||
let mut processed_blocks = 0;
|
||||
|
||||
loop {
|
||||
debug!(ctx.expect_logger(), "Tick");
|
||||
let (compacted_blocks, _) = match commands_rx.try_recv() {
|
||||
Ok(PostProcessorCommand::ProcessBlocks(compacted_blocks, blocks)) => {
|
||||
(compacted_blocks, blocks)
|
||||
}
|
||||
Ok(PostProcessorCommand::Terminate) => {
|
||||
debug!(ctx.expect_logger(), "Terminating block processor");
|
||||
let _ = events_tx.send(PostProcessorEvent::Terminated);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,6 @@ pub fn start_inscription_indexing_processor(
|
||||
(compacted_blocks, blocks)
|
||||
}
|
||||
Ok(PostProcessorCommand::Terminate) => {
|
||||
debug!(ctx.expect_logger(), "Terminating block processor");
|
||||
let _ = events_tx.send(PostProcessorEvent::Terminated);
|
||||
break;
|
||||
}
|
||||
@@ -91,7 +90,9 @@ pub fn start_inscription_indexing_processor(
|
||||
TryRecvError::Empty => {
|
||||
empty_cycles += 1;
|
||||
if empty_cycles == 180 {
|
||||
warn!(ctx.expect_logger(), "Block processor reached expiration");
|
||||
ctx.try_log(|logger| {
|
||||
info!(logger, "Block processor reached expiration")
|
||||
});
|
||||
let _ = events_tx.send(PostProcessorEvent::Expired);
|
||||
break;
|
||||
}
|
||||
@@ -117,7 +118,7 @@ pub fn start_inscription_indexing_processor(
|
||||
);
|
||||
}
|
||||
|
||||
info!(ctx.expect_logger(), "Processing {} blocks", blocks.len());
|
||||
ctx.try_log(|logger| info!(logger, "Processing {} blocks", blocks.len()));
|
||||
|
||||
blocks = process_blocks(
|
||||
&mut blocks,
|
||||
@@ -132,19 +133,19 @@ pub fn start_inscription_indexing_processor(
|
||||
garbage_collect_nth_block += blocks.len();
|
||||
|
||||
if garbage_collect_nth_block > garbage_collect_every_n_blocks {
|
||||
ctx.try_log(|logger| info!(logger, "Performing garbage collecting"));
|
||||
|
||||
// Clear L2 cache on a regular basis
|
||||
info!(
|
||||
ctx.expect_logger(),
|
||||
"Clearing cache L2 ({} entries)",
|
||||
cache_l2.len()
|
||||
);
|
||||
ctx.try_log(|logger| {
|
||||
info!(logger, "Clearing cache L2 ({} entries)", cache_l2.len())
|
||||
});
|
||||
cache_l2.clear();
|
||||
|
||||
// Recreate sqlite db connection on a regular basis
|
||||
inscriptions_db_conn_rw =
|
||||
open_readwrite_ordhook_db_conn(&config.expected_cache_path(), &ctx)
|
||||
.unwrap();
|
||||
|
||||
inscriptions_db_conn_rw.flush_prepared_statement_cache();
|
||||
garbage_collect_nth_block = 0;
|
||||
}
|
||||
}
|
||||
@@ -215,7 +216,7 @@ pub fn process_blocks(
|
||||
|
||||
if any_existing_activity {
|
||||
ctx.try_log(|logger| {
|
||||
warn!(
|
||||
error!(
|
||||
logger,
|
||||
"Dropping updates for block #{}, activities present in database",
|
||||
block.block_identifier.index,
|
||||
|
||||
@@ -44,7 +44,6 @@ pub fn start_transfers_recomputing_processor(
|
||||
blocks
|
||||
}
|
||||
Ok(PostProcessorCommand::Terminate) => {
|
||||
debug!(ctx.expect_logger(), "Terminating block processor");
|
||||
let _ = events_tx.send(PostProcessorEvent::Terminated);
|
||||
break;
|
||||
}
|
||||
@@ -52,7 +51,9 @@ pub fn start_transfers_recomputing_processor(
|
||||
TryRecvError::Empty => {
|
||||
empty_cycles += 1;
|
||||
if empty_cycles == 10 {
|
||||
warn!(ctx.expect_logger(), "Block processor reached expiration");
|
||||
ctx.try_log(|logger| {
|
||||
warn!(logger, "Block processor reached expiration")
|
||||
});
|
||||
let _ = events_tx.send(PostProcessorEvent::Expired);
|
||||
break;
|
||||
}
|
||||
@@ -65,7 +66,7 @@ pub fn start_transfers_recomputing_processor(
|
||||
},
|
||||
};
|
||||
|
||||
info!(ctx.expect_logger(), "Processing {} blocks", blocks.len());
|
||||
ctx.try_log(|logger| info!(logger, "Processing {} blocks", blocks.len()));
|
||||
let inscriptions_db_tx = inscriptions_db_conn_rw.transaction().unwrap();
|
||||
|
||||
for block in blocks.iter_mut() {
|
||||
|
||||
@@ -2,8 +2,6 @@ use std::{
|
||||
collections::{BTreeMap, HashMap, VecDeque},
|
||||
hash::BuildHasherDefault,
|
||||
sync::Arc,
|
||||
thread::sleep,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use chainhook_sdk::{
|
||||
@@ -784,8 +782,6 @@ pub fn consolidate_block_with_pre_computed_ordinals_data(
|
||||
if results.len() == expected_inscriptions_count {
|
||||
break results;
|
||||
}
|
||||
// Handle race conditions: if the db is being updated, the number of expected entries could be un-met.
|
||||
sleep(Duration::from_secs(3));
|
||||
ctx.try_log(|logger| {
|
||||
warn!(
|
||||
logger,
|
||||
|
||||
@@ -2,7 +2,8 @@ use chainhook_sdk::{
|
||||
bitcoincore_rpc_json::bitcoin::{hashes::hex::FromHex, Address, Network, Script},
|
||||
types::{
|
||||
BitcoinBlockData, BitcoinNetwork, BitcoinTransactionData, BlockIdentifier,
|
||||
OrdinalInscriptionTransferData, OrdinalOperation, TransactionIdentifier, OrdinalInscriptionTransferDestination,
|
||||
OrdinalInscriptionTransferData, OrdinalInscriptionTransferDestination, OrdinalOperation,
|
||||
TransactionIdentifier,
|
||||
},
|
||||
utils::Context,
|
||||
};
|
||||
@@ -84,14 +85,7 @@ pub fn augment_transaction_with_ordinals_transfers_data(
|
||||
);
|
||||
|
||||
let entries =
|
||||
match find_inscriptions_at_wached_outpoint(&outpoint_pre_transfer, &inscriptions_db_tx)
|
||||
{
|
||||
Ok(entries) => entries,
|
||||
Err(e) => {
|
||||
ctx.try_log(|logger| warn!(logger, "unable query inscriptions: {e}"));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
find_inscriptions_at_wached_outpoint(&outpoint_pre_transfer, &inscriptions_db_tx, ctx);
|
||||
// For each satpoint inscribed retrieved, we need to compute the next
|
||||
// outpoint to watch
|
||||
for watched_satpoint in entries.into_iter() {
|
||||
@@ -124,10 +118,12 @@ pub fn augment_transaction_with_ordinals_transfers_data(
|
||||
tx.metadata.outputs[output_index].get_script_pubkey_hex();
|
||||
let updated_address = match Script::from_hex(&script_pub_key_hex) {
|
||||
Ok(script) => match Address::from_script(&script, network.clone()) {
|
||||
Ok(address) => OrdinalInscriptionTransferDestination::Transferred(address.to_string()),
|
||||
Ok(address) => OrdinalInscriptionTransferDestination::Transferred(
|
||||
address.to_string(),
|
||||
),
|
||||
Err(e) => {
|
||||
ctx.try_log(|logger| {
|
||||
warn!(
|
||||
info!(
|
||||
logger,
|
||||
"unable to retrieve address from {script_pub_key_hex}: {}",
|
||||
e.to_string()
|
||||
@@ -138,13 +134,15 @@ pub fn augment_transaction_with_ordinals_transfers_data(
|
||||
},
|
||||
Err(e) => {
|
||||
ctx.try_log(|logger| {
|
||||
warn!(
|
||||
info!(
|
||||
logger,
|
||||
"unable to retrieve address from {script_pub_key_hex}: {}",
|
||||
e.to_string()
|
||||
)
|
||||
});
|
||||
OrdinalInscriptionTransferDestination::Burnt(script_pub_key_hex.to_string())
|
||||
OrdinalInscriptionTransferDestination::Burnt(
|
||||
script_pub_key_hex.to_string(),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -181,7 +179,12 @@ pub fn augment_transaction_with_ordinals_transfers_data(
|
||||
offset
|
||||
)
|
||||
});
|
||||
(outpoint, total_offset, OrdinalInscriptionTransferDestination::SpentInFees, None)
|
||||
(
|
||||
outpoint,
|
||||
total_offset,
|
||||
OrdinalInscriptionTransferDestination::SpentInFees,
|
||||
None,
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
use crate::config::{Config, PredicatesApi};
|
||||
use crate::core::protocol::inscription_parsing::{
|
||||
get_inscriptions_revealed_in_block, parse_inscriptions_and_standardize_block,
|
||||
get_inscriptions_revealed_in_block, get_inscriptions_transferred_in_block,
|
||||
parse_inscriptions_and_standardize_block,
|
||||
};
|
||||
use crate::core::protocol::inscription_sequencing::consolidate_block_with_pre_computed_ordinals_data;
|
||||
use crate::db::{get_any_entry_in_ordinal_activities, open_readonly_ordhook_db_conn};
|
||||
@@ -75,9 +76,6 @@ pub async fn scan_bitcoin_chainstate_via_rpc_using_predicate(
|
||||
BlockHeights::BlockRange(start_block, end_block).get_sorted_entries()
|
||||
};
|
||||
|
||||
let mut inscriptions_db_conn =
|
||||
open_readonly_ordhook_db_conn(&config.expected_cache_path(), ctx)?;
|
||||
|
||||
info!(
|
||||
ctx.expect_logger(),
|
||||
"Starting predicate evaluation on Bitcoin blocks",
|
||||
@@ -96,6 +94,9 @@ pub async fn scan_bitcoin_chainstate_via_rpc_using_predicate(
|
||||
let http_client = build_http_client();
|
||||
|
||||
while let Some(current_block_height) = block_heights_to_scan.pop_front() {
|
||||
let mut inscriptions_db_conn =
|
||||
open_readonly_ordhook_db_conn(&config.expected_cache_path(), ctx)?;
|
||||
|
||||
number_of_blocks_scanned += 1;
|
||||
|
||||
if !get_any_entry_in_ordinal_activities(¤t_block_height, &inscriptions_db_conn, &ctx)
|
||||
@@ -143,9 +144,11 @@ pub async fn scan_bitcoin_chainstate_via_rpc_using_predicate(
|
||||
.map(|d| d.inscription_number.to_string())
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
let inscriptions_transferred = get_inscriptions_transferred_in_block(&block).len();
|
||||
|
||||
info!(
|
||||
ctx.expect_logger(),
|
||||
"Processing block #{current_block_height} through {} predicate ({} inscriptions revealed: [{}])",
|
||||
"Processing block #{current_block_height} through {} predicate revealed {} new inscriptions [{}] and {inscriptions_transferred} transfers",
|
||||
predicate_spec.uuid,
|
||||
inscriptions_revealed.len(),
|
||||
inscriptions_revealed.join(", ")
|
||||
|
||||
@@ -278,19 +278,23 @@ pub fn get_entries_from_predicates_db(
|
||||
let chainhook = match get_entry_from_predicates_db(predicate_key, predicate_db_conn, ctx) {
|
||||
Ok(Some((spec, status))) => (spec, status),
|
||||
Ok(None) => {
|
||||
warn!(
|
||||
ctx.expect_logger(),
|
||||
"unable to load predicate associated with key {}", predicate_key,
|
||||
);
|
||||
ctx.try_log(|logger| {
|
||||
warn!(
|
||||
logger,
|
||||
"unable to load predicate associated with key {}", predicate_key,
|
||||
)
|
||||
});
|
||||
continue;
|
||||
}
|
||||
Err(e) => {
|
||||
error!(
|
||||
ctx.expect_logger(),
|
||||
"unable to load predicate associated with key {}: {}",
|
||||
predicate_key,
|
||||
e.to_string()
|
||||
);
|
||||
ctx.try_log(|logger| {
|
||||
error!(
|
||||
logger,
|
||||
"unable to load predicate associated with key {}: {}",
|
||||
predicate_key,
|
||||
e.to_string()
|
||||
)
|
||||
});
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,13 +9,14 @@ use crate::core::pipeline::processors::inscription_indexing::process_block;
|
||||
use crate::core::pipeline::processors::start_inscription_indexing_processor;
|
||||
use crate::core::pipeline::processors::transfers_recomputing::start_transfers_recomputing_processor;
|
||||
use crate::core::protocol::inscription_parsing::{
|
||||
get_inscriptions_revealed_in_block, parse_inscriptions_in_standardized_block,
|
||||
get_inscriptions_revealed_in_block, get_inscriptions_transferred_in_block,
|
||||
parse_inscriptions_in_standardized_block,
|
||||
};
|
||||
use crate::core::protocol::inscription_sequencing::SequenceCursor;
|
||||
use crate::core::{new_traversals_lazy_cache, should_sync_ordhook_db, should_sync_rocks_db};
|
||||
use crate::db::{
|
||||
delete_data_in_ordhook_db, insert_entry_in_blocks, open_readwrite_ordhook_db_conn,
|
||||
open_readwrite_ordhook_db_conn_rocks_db, open_readwrite_ordhook_dbs,
|
||||
open_ordhook_db_conn_rocks_db_loop, open_readwrite_ordhook_dbs,
|
||||
update_inscriptions_with_block, update_locations_with_block, LazyBlock, LazyBlockTransaction,
|
||||
};
|
||||
use crate::scan::bitcoin::process_block_with_predicates;
|
||||
@@ -441,16 +442,17 @@ impl Service {
|
||||
event_observer_config: &EventObserverConfig,
|
||||
) -> Result<(), String> {
|
||||
if rebuild_from_scratch {
|
||||
let blocks_db = open_readwrite_ordhook_db_conn_rocks_db(
|
||||
let blocks_db = open_ordhook_db_conn_rocks_db_loop(
|
||||
true,
|
||||
&self.config.expected_cache_path(),
|
||||
&self.ctx,
|
||||
)?;
|
||||
);
|
||||
let inscriptions_db_conn_rw =
|
||||
open_readwrite_ordhook_db_conn(&self.config.expected_cache_path(), &self.ctx)?;
|
||||
|
||||
delete_data_in_ordhook_db(
|
||||
767430,
|
||||
800000,
|
||||
820000,
|
||||
&blocks_db,
|
||||
&inscriptions_db_conn_rw,
|
||||
&self.ctx,
|
||||
@@ -574,10 +576,12 @@ fn chainhook_sidecar_mutate_ordhook_db(command: HandleBlock, config: &Config, ct
|
||||
|
||||
match command {
|
||||
HandleBlock::UndoBlock(block) => {
|
||||
info!(
|
||||
ctx.expect_logger(),
|
||||
"Re-org handling: reverting changes in block #{}", block.block_identifier.index
|
||||
);
|
||||
ctx.try_log(|logger| {
|
||||
info!(
|
||||
logger,
|
||||
"Re-org handling: reverting changes in block #{}", block.block_identifier.index
|
||||
)
|
||||
});
|
||||
if let Err(e) = delete_data_in_ordhook_db(
|
||||
block.block_identifier.index,
|
||||
block.block_identifier.index,
|
||||
@@ -685,7 +689,7 @@ pub fn chainhook_sidecar_mutate_blocks(
|
||||
block_id_to_rollback.index,
|
||||
&blocks_db_rw,
|
||||
&inscriptions_db_tx,
|
||||
&Context::empty(),
|
||||
&ctx,
|
||||
) {
|
||||
ctx.try_log(|logger| {
|
||||
error!(
|
||||
@@ -750,10 +754,13 @@ pub fn chainhook_sidecar_mutate_blocks(
|
||||
.map(|d| d.inscription_number.to_string())
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
let inscriptions_transferred =
|
||||
get_inscriptions_transferred_in_block(&cache.block).len();
|
||||
|
||||
ctx.try_log(|logger| {
|
||||
info!(
|
||||
logger,
|
||||
"Block #{} processed, mutated and revealed {} inscriptions [{}]",
|
||||
"Block #{} processed, mutated and revealed {} inscriptions [{}] and {inscriptions_transferred} transfers",
|
||||
cache.block.block_identifier.index,
|
||||
inscriptions_revealed.len(),
|
||||
inscriptions_revealed.join(", ")
|
||||
|
||||
@@ -39,10 +39,12 @@ pub fn start_bitcoin_scan_runloop(
|
||||
match hiro_system_kit::nestable_block_on(op) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
error!(
|
||||
moved_ctx.expect_logger(),
|
||||
"Unable to evaluate predicate on Bitcoin chainstate: {e}",
|
||||
);
|
||||
moved_ctx.try_log(|logger| {
|
||||
error!(
|
||||
logger,
|
||||
"Unable to evaluate predicate on Bitcoin chainstate: {e}",
|
||||
)
|
||||
});
|
||||
|
||||
// Update predicate status in redis
|
||||
if let PredicatesApi::On(ref api_config) = moved_config.http_api {
|
||||
|
||||
@@ -52,11 +52,6 @@ impl OrdinalsIndexingRunloop {
|
||||
tracer: false,
|
||||
};
|
||||
|
||||
// Initialize service
|
||||
// {
|
||||
// let _ = initialize_ordhook_db(&ordhook_config.expected_cache_path(), &ctx);
|
||||
// let _ = open_readwrite_ordhook_db_conn_rocks_db(&ordhook_config.expected_cache_path(), &ctx);
|
||||
// }
|
||||
let mut service: Service = Service::new(ordhook_config, ctx);
|
||||
|
||||
// Set-up the observer sidecar - used for augmenting the bitcoin blocks with
|
||||
@@ -91,14 +86,18 @@ impl OrdinalsIndexingRunloop {
|
||||
for to_rollback in payload.rollback.into_iter() {
|
||||
loop {
|
||||
let (tx, rx) = crossbeam_channel::bounded(1);
|
||||
callback.call_with_return_value::<bool, _>(to_rollback.clone(), ThreadsafeFunctionCallMode::Blocking, move |p| {
|
||||
let _ = tx.send(p);
|
||||
Ok(())
|
||||
});
|
||||
callback.call_with_return_value::<bool, _>(
|
||||
to_rollback.clone(),
|
||||
ThreadsafeFunctionCallMode::Blocking,
|
||||
move |p| {
|
||||
let _ = tx.send(p);
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
match rx.recv() {
|
||||
Ok(true) => break,
|
||||
Ok(false) => continue,
|
||||
_ => panic!(),
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,14 +107,18 @@ impl OrdinalsIndexingRunloop {
|
||||
for to_apply in payload.apply.into_iter() {
|
||||
loop {
|
||||
let (tx, rx) = crossbeam_channel::bounded(1);
|
||||
callback.call_with_return_value::<bool, _>(to_apply.clone(), ThreadsafeFunctionCallMode::Blocking, move |p| {
|
||||
let _ = tx.send(p);
|
||||
Ok(())
|
||||
});
|
||||
callback.call_with_return_value::<bool, _>(
|
||||
to_apply.clone(),
|
||||
ThreadsafeFunctionCallMode::Blocking,
|
||||
move |p| {
|
||||
let _ = tx.send(p);
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
match rx.recv() {
|
||||
Ok(true) => break,
|
||||
Ok(false) => continue,
|
||||
_ => panic!(),
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user