Skip to content

Commit

Permalink
fix: transfer tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
Ludo Galabru committed May 2, 2023
1 parent 247df20 commit 0cd29f5
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 18 deletions.
42 changes: 42 additions & 0 deletions components/chainhook-event-observer/src/hord/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,48 @@ pub struct WatchedSatpoint {
pub offset: u64,
}

impl WatchedSatpoint {
pub fn get_genesis_satpoint(&self) -> String {
format!(
"{}:0",
&self.inscription_id[0..self.inscription_id.len() - 2]
)
}
}

pub fn find_watched_satpoint_for_inscription(
inscription_id: &str,
inscriptions_db_conn: &Connection,
) -> Result<(u64, WatchedSatpoint), String> {
let args: &[&dyn ToSql] = &[&inscription_id.to_sql().unwrap()];
let mut stmt = inscriptions_db_conn
.prepare("SELECT inscription_id, inscription_number, ordinal_number, offset, block_height FROM inscriptions WHERE inscription_id = ? ORDER BY offset ASC")
.map_err(|e| format!("unable to query inscriptions table: {}", e.to_string()))?;
let mut rows = stmt
.query(args)
.map_err(|e| format!("unable to query inscriptions table: {}", e.to_string()))?;
while let Ok(Some(row)) = rows.next() {
let inscription_id: String = row.get(0).unwrap();
let inscription_number: u64 = row.get(1).unwrap();
let ordinal_number: u64 = row.get(2).unwrap();
let offset: u64 = row.get(3).unwrap();
let block_height: u64 = row.get(4).unwrap();
return Ok((
block_height,
WatchedSatpoint {
inscription_id,
inscription_number,
ordinal_number,
offset,
},
));
}
return Err(format!(
"unable to find inscription with id {}",
inscription_id
));
}

pub fn find_inscriptions_at_wached_outpoint(
outpoint: &str,
hord_db_conn: &Connection,
Expand Down
37 changes: 19 additions & 18 deletions components/chainhook-event-observer/src/hord/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,13 @@ pub fn update_storage_and_augment_bitcoin_block_with_inscription_reveal_data(
}
}

/// For each input of each transaction in the block, we retrieve the UTXO spent (outpoint_pre_transfer)
/// and we check using a `storage` (in-memory or sqlite) absctraction if we have some existing inscriptions
/// for this entry.
/// When this is the case, it means that an inscription_transfer event needs to be produced. We need to
/// compute the output index (if any) `post_transfer_output` that will now include the inscription.
/// When identifying the output index, we will also need to provide an updated offset for pin pointing
/// the satoshi location.
pub fn update_storage_and_augment_bitcoin_block_with_inscription_transfer_data(
block: &mut BitcoinBlockData,
storage: &mut Storage,
Expand All @@ -409,7 +416,6 @@ pub fn update_storage_and_augment_bitcoin_block_with_inscription_transfer_data(
for new_tx in block.transactions.iter_mut().skip(1) {
// Have inscriptions been transfered?
let mut sats_in_offset = 0;
let mut sats_out_offset = new_tx.metadata.outputs[0].value;

for input in new_tx.metadata.inputs.iter() {
// input.previous_output.txid
Expand All @@ -419,8 +425,6 @@ pub fn update_storage_and_augment_bitcoin_block_with_inscription_transfer_data(
input.previous_output.vout
);

let mut post_transfer_output_index = 0;

let entries = match storage {
Storage::Sqlite(rw_hord_db_conn) => {
find_inscriptions_at_wached_outpoint(&outpoint_pre_transfer, &rw_hord_db_conn)?
Expand All @@ -432,20 +436,25 @@ pub fn update_storage_and_augment_bitcoin_block_with_inscription_transfer_data(
};

for mut watched_satpoint in entries.into_iter() {
let mut post_transfer_output_index = 0;
let mut sats_out_offset = 0;
let mut next_output_value = new_tx.metadata.outputs[0].value;
let satpoint_pre_transfer =
format!("{}:{}", outpoint_pre_transfer, watched_satpoint.offset);

// Question is: are inscriptions moving to a new output,
// burnt or lost in fees and transfered to the miner?
let post_transfer_output = loop {
if sats_out_offset >= sats_in_offset + watched_satpoint.offset {

let post_transfer_output: Option<usize> = loop {
if sats_out_offset + next_output_value > sats_in_offset + watched_satpoint.offset {
break Some(post_transfer_output_index);
}
if post_transfer_output_index + 1 >= new_tx.metadata.outputs.len() {
sats_out_offset += next_output_value;
post_transfer_output_index += 1;
if post_transfer_output_index >= new_tx.metadata.outputs.len() {
break None;
} else {
post_transfer_output_index += 1;
sats_out_offset +=
next_output_value =
new_tx.metadata.outputs[post_transfer_output_index].value;
}
};
Expand All @@ -459,7 +468,7 @@ pub fn update_storage_and_augment_bitcoin_block_with_inscription_transfer_data(
Some(index) => {
let outpoint =
format!("{}:{}", &new_tx.transaction_identifier.hash[2..], index);
let offset = 0;
let offset = (sats_in_offset + watched_satpoint.offset) - sats_out_offset;
let script_pub_key_hex =
new_tx.metadata.outputs[index].get_script_pubkey_hex();
let updated_address = match Script::from_hex(&script_pub_key_hex) {
Expand Down Expand Up @@ -498,19 +507,11 @@ pub fn update_storage_and_augment_bitcoin_block_with_inscription_transfer_data(
None => {
// Get Coinbase TX
let offset = first_sat_post_subsidy + cumulated_fees;
let outpoint = coinbase_txid.clone();
let outpoint = format!("{}:0", &coinbase_txid[2..]);
(outpoint, offset, None, None)
}
};

// ctx.try_log(|logger| {
// slog::info!(
// logger,
// "Updating watched outpoint {} to outpoint {}",
// outpoint_post_transfer,
// outpoint_pre_transfer,
// )
// });
// At this point we know that inscriptions are being moved.
ctx.try_log(|logger| {
slog::info!(
Expand Down

0 comments on commit 0cd29f5

Please sign in to comment.