mirror of
https://github.com/alexgo-io/bitcoin-indexer.git
synced 2026-06-14 08:29:31 +08:00
feat: polish hord find sat_point command
This commit is contained in:
@@ -13,8 +13,8 @@ use chainhook_event_observer::chainhooks::types::{
|
||||
StacksPrintEventBasedPredicate,
|
||||
};
|
||||
use chainhook_event_observer::hord::db::{
|
||||
fetch_and_cache_blocks_in_hord_db, find_inscriptions_at_wached_outpoint, initialize_hord_db,
|
||||
open_readonly_hord_db_conn, open_readwrite_hord_db_conn,
|
||||
fetch_and_cache_blocks_in_hord_db, find_inscriptions_at_wached_outpoint,
|
||||
find_latest_compacted_block_known, open_readonly_hord_db_conn, open_readwrite_hord_db_conn,
|
||||
retrieve_satoshi_point_using_local_storage,
|
||||
};
|
||||
use chainhook_event_observer::observer::BitcoinConfig;
|
||||
@@ -203,8 +203,6 @@ struct FindSatPointCommand {
|
||||
pub block_height: u64,
|
||||
/// Txid
|
||||
pub txid: String,
|
||||
/// Output index
|
||||
pub output_index: usize,
|
||||
/// Target Devnet network
|
||||
#[clap(
|
||||
long = "devnet",
|
||||
@@ -455,6 +453,21 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
|
||||
FindCommand::SatPoint(cmd) => {
|
||||
let config =
|
||||
Config::default(cmd.devnet, cmd.testnet, cmd.mainnet, &cmd.config_path)?;
|
||||
|
||||
info!(
|
||||
ctx.expect_logger(),
|
||||
"Computing satoshi number for satoshi at offet 0 in 1st output of transaction {} (block ${})", cmd.txid, cmd.block_height
|
||||
);
|
||||
|
||||
let hord_db_conn =
|
||||
open_readonly_hord_db_conn(&config.expected_cache_path(), &ctx).unwrap();
|
||||
|
||||
let tip_height = find_latest_compacted_block_known(&hord_db_conn) as u64;
|
||||
|
||||
if cmd.block_height > tip_height {
|
||||
perform_hord_db_update(tip_height, cmd.block_height, 8, &config, &ctx).await?;
|
||||
}
|
||||
|
||||
let transaction_identifier = TransactionIdentifier {
|
||||
hash: cmd.txid.clone(),
|
||||
};
|
||||
@@ -463,10 +476,7 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
|
||||
hash: "".into(),
|
||||
};
|
||||
|
||||
let hord_db_conn =
|
||||
open_readonly_hord_db_conn(&config.expected_cache_path(), &ctx).unwrap();
|
||||
|
||||
let (block_height, offset, ordinal_number) =
|
||||
let (block_height, offset, ordinal_number, hops) =
|
||||
retrieve_satoshi_point_using_local_storage(
|
||||
&hord_db_conn,
|
||||
&block_identifier,
|
||||
@@ -475,7 +485,7 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
|
||||
)?;
|
||||
info!(
|
||||
ctx.expect_logger(),
|
||||
"Block: {block_height}, Offset {offset}:, Ordinal number: {ordinal_number}",
|
||||
"Satoshi #{ordinal_number} was minted in block #{block_height} at offset {offset} and was transferred {hops} times.",
|
||||
);
|
||||
}
|
||||
FindCommand::Inscription(cmd) => {
|
||||
@@ -491,14 +501,6 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
|
||||
Command::Hord(HordCommand::Db(subcmd)) => match subcmd {
|
||||
DbCommand::Init(cmd) => {
|
||||
let config = Config::default(false, false, false, &cmd.config_path)?;
|
||||
|
||||
let bitcoin_config = BitcoinConfig {
|
||||
username: config.network.bitcoin_node_rpc_username.clone(),
|
||||
password: config.network.bitcoin_node_rpc_password.clone(),
|
||||
rpc_url: config.network.bitcoin_node_rpc_url.clone(),
|
||||
network: config.network.bitcoin_network.clone(),
|
||||
};
|
||||
|
||||
let auth = Auth::UserPass(
|
||||
config.network.bitcoin_node_rpc_username.clone(),
|
||||
config.network.bitcoin_node_rpc_password.clone(),
|
||||
@@ -521,38 +523,16 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
|
||||
}
|
||||
};
|
||||
|
||||
let rw_hord_db_conn = initialize_hord_db(&config.expected_cache_path(), &ctx);
|
||||
|
||||
let _ = fetch_and_cache_blocks_in_hord_db(
|
||||
&bitcoin_config,
|
||||
&rw_hord_db_conn,
|
||||
0,
|
||||
end_block,
|
||||
&ctx,
|
||||
cmd.network_threads,
|
||||
)
|
||||
.await?;
|
||||
perform_hord_db_update(0, end_block, cmd.network_threads, &config, &ctx).await?;
|
||||
}
|
||||
DbCommand::Update(cmd) => {
|
||||
let config = Config::default(false, false, false, &cmd.config_path)?;
|
||||
|
||||
let bitcoin_config = BitcoinConfig {
|
||||
username: config.network.bitcoin_node_rpc_username.clone(),
|
||||
password: config.network.bitcoin_node_rpc_password.clone(),
|
||||
rpc_url: config.network.bitcoin_node_rpc_url.clone(),
|
||||
network: config.network.bitcoin_network.clone(),
|
||||
};
|
||||
|
||||
let rw_hord_db_conn =
|
||||
open_readwrite_hord_db_conn(&config.expected_cache_path(), &ctx)?;
|
||||
|
||||
let _ = fetch_and_cache_blocks_in_hord_db(
|
||||
&bitcoin_config,
|
||||
&rw_hord_db_conn,
|
||||
perform_hord_db_update(
|
||||
cmd.start_block,
|
||||
cmd.end_block,
|
||||
&ctx,
|
||||
cmd.network_threads,
|
||||
&config,
|
||||
&ctx,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
@@ -561,6 +541,40 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn perform_hord_db_update(
|
||||
start_block: u64,
|
||||
end_block: u64,
|
||||
network_threads: usize,
|
||||
config: &Config,
|
||||
ctx: &Context,
|
||||
) -> Result<(), String> {
|
||||
info!(
|
||||
ctx.expect_logger(),
|
||||
"Syncing hord_db: {} blocks to download ({start_block}: {end_block}), using {network_threads} network threads", end_block - start_block
|
||||
);
|
||||
|
||||
let bitcoin_config = BitcoinConfig {
|
||||
username: config.network.bitcoin_node_rpc_username.clone(),
|
||||
password: config.network.bitcoin_node_rpc_password.clone(),
|
||||
rpc_url: config.network.bitcoin_node_rpc_url.clone(),
|
||||
network: config.network.bitcoin_network.clone(),
|
||||
};
|
||||
|
||||
let rw_hord_db_conn = open_readwrite_hord_db_conn(&config.expected_cache_path(), &ctx)?;
|
||||
|
||||
let _ = fetch_and_cache_blocks_in_hord_db(
|
||||
&bitcoin_config,
|
||||
&rw_hord_db_conn,
|
||||
start_block,
|
||||
end_block,
|
||||
&ctx,
|
||||
network_threads,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn install_ctrlc_handler(terminate_tx: Sender<DigestingCommand>, ctx: Context) {
|
||||
ctrlc::set_handler(move || {
|
||||
|
||||
@@ -302,7 +302,23 @@ pub fn update_transfered_inscription(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_last_inscription_number(
|
||||
pub fn find_latest_inscription_block_height(
|
||||
hord_db_conn: &Connection,
|
||||
_ctx: &Context,
|
||||
) -> Result<u64, String> {
|
||||
let args: &[&dyn ToSql] = &[];
|
||||
let mut stmt = hord_db_conn
|
||||
.prepare("SELECT block_height FROM inscriptions ORDER BY block_height DESC LIMIT 1")
|
||||
.unwrap();
|
||||
let mut rows = stmt.query(args).unwrap();
|
||||
while let Ok(Some(row)) = rows.next() {
|
||||
let block_height: u64 = row.get(0).unwrap();
|
||||
return Ok(block_height);
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub fn find_latest_inscription_number(
|
||||
hord_db_conn: &Connection,
|
||||
_ctx: &Context,
|
||||
) -> Result<u64, String> {
|
||||
@@ -513,7 +529,7 @@ pub async fn fetch_and_cache_blocks_in_hord_db(
|
||||
let (block_compressed_tx, block_compressed_rx) = crossbeam_channel::unbounded();
|
||||
let first_inscription_block_height = 767430;
|
||||
|
||||
for block_cursor in start_block..end_block {
|
||||
for block_cursor in start_block..=end_block {
|
||||
let block_height = block_cursor.clone();
|
||||
let block_hash_tx = block_hash_tx.clone();
|
||||
let config = bitcoin_config.clone();
|
||||
@@ -573,7 +589,8 @@ pub async fn fetch_and_cache_blocks_in_hord_db(
|
||||
.expect("unable to spawn thread");
|
||||
|
||||
let mut blocks_stored = 0;
|
||||
let mut cursor = first_inscription_block_height;
|
||||
let mut cursor = find_latest_inscription_block_height(&rw_hord_db_conn, &ctx)
|
||||
.unwrap_or(first_inscription_block_height) as usize;
|
||||
let mut inbox = HashMap::new();
|
||||
|
||||
while let Ok(Some((block_height, compacted_block, raw_block))) = block_compressed_rx.recv() {
|
||||
@@ -582,7 +599,7 @@ pub async fn fetch_and_cache_blocks_in_hord_db(
|
||||
insert_entry_in_blocks(block_height, &compacted_block, &rw_hord_db_conn, &ctx);
|
||||
|
||||
// Early return, only considering blocks after 1st inscription
|
||||
if raw_block.height < first_inscription_block_height {
|
||||
if raw_block.height < cursor {
|
||||
continue;
|
||||
}
|
||||
let block_height = raw_block.height;
|
||||
@@ -645,7 +662,7 @@ pub fn retrieve_satoshi_point_using_local_storage(
|
||||
block_identifier: &BlockIdentifier,
|
||||
transaction_identifier: &TransactionIdentifier,
|
||||
ctx: &Context,
|
||||
) -> Result<(u64, u64, u64), String> {
|
||||
) -> Result<(u64, u64, u64, u32), String> {
|
||||
let mut ordinal_offset = 0;
|
||||
let mut ordinal_block_number = block_identifier.index as u32;
|
||||
let txid = {
|
||||
@@ -653,8 +670,9 @@ pub fn retrieve_satoshi_point_using_local_storage(
|
||||
[bytes[0], bytes[1], bytes[2], bytes[3]]
|
||||
};
|
||||
let mut tx_cursor = (txid, 0);
|
||||
|
||||
let mut hops: u32 = 0;
|
||||
loop {
|
||||
hops += 1;
|
||||
let res = match find_compacted_block_at_block_height(ordinal_block_number, &hord_db_conn) {
|
||||
Some(res) => res,
|
||||
None => {
|
||||
@@ -776,5 +794,10 @@ pub fn retrieve_satoshi_point_using_local_storage(
|
||||
let height = Height(ordinal_block_number.into());
|
||||
let ordinal_number = height.starting_sat().0 + ordinal_offset;
|
||||
|
||||
Ok((ordinal_block_number.into(), ordinal_offset, ordinal_number))
|
||||
Ok((
|
||||
ordinal_block_number.into(),
|
||||
ordinal_offset,
|
||||
ordinal_number,
|
||||
hops,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ use crate::{
|
||||
hord::{
|
||||
db::{
|
||||
find_inscription_with_ordinal_number, find_inscriptions_at_wached_outpoint,
|
||||
find_last_inscription_number, insert_entry_in_blocks,
|
||||
find_latest_inscription_number, insert_entry_in_blocks,
|
||||
retrieve_satoshi_point_using_local_storage, store_new_inscription,
|
||||
update_transfered_inscription, CompactedBlock,
|
||||
},
|
||||
@@ -98,7 +98,7 @@ pub fn update_hord_db_and_augment_bitcoin_block(
|
||||
new_tx.metadata.ordinal_operations.iter_mut().enumerate()
|
||||
{
|
||||
if let OrdinalOperation::InscriptionRevealed(inscription) = ordinal_event {
|
||||
let (ordinal_block_height, ordinal_offset, ordinal_number) = {
|
||||
let (ordinal_block_height, ordinal_offset, ordinal_number, _) = {
|
||||
// Are we looking at a re-inscription?
|
||||
let res = retrieve_satoshi_point_using_local_storage(
|
||||
&rw_hord_db_conn,
|
||||
@@ -140,7 +140,7 @@ pub fn update_hord_db_and_augment_bitcoin_block(
|
||||
inscription.ordinal_block_height = ordinal_block_height;
|
||||
inscription.ordinal_number = ordinal_number;
|
||||
inscription.inscription_number =
|
||||
match find_last_inscription_number(&rw_hord_db_conn, &ctx) {
|
||||
match find_latest_inscription_number(&rw_hord_db_conn, &ctx) {
|
||||
Ok(inscription_number) => inscription_number,
|
||||
Err(e) => {
|
||||
ctx.try_log(|logger| {
|
||||
|
||||
Reference in New Issue
Block a user