Skip to content

Commit

Permalink
feat: polish hord find sat_point command
Browse files Browse the repository at this point in the history
  • Loading branch information
Ludo Galabru committed Mar 27, 2023
1 parent c49b54d commit d071484
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 53 deletions.
100 changes: 57 additions & 43 deletions components/chainhook-cli/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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(),
};
Expand All @@ -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,
Expand All @@ -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) => {
Expand All @@ -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(),
Expand All @@ -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?;
}
Expand All @@ -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 || {
Expand Down
37 changes: 30 additions & 7 deletions components/chainhook-event-observer/src/hord/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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() {
Expand All @@ -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;
Expand Down Expand Up @@ -645,16 +662,17 @@ 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 = {
let bytes = hex::decode(&transaction_identifier.hash[2..]).unwrap();
[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 => {
Expand Down Expand Up @@ -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,
))
}
6 changes: 3 additions & 3 deletions components/chainhook-event-observer/src/hord/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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| {
Expand Down

0 comments on commit d071484

Please sign in to comment.