mirror of
https://github.com/alexgo-io/bitcoin-indexer.git
synced 2026-06-14 08:29:31 +08:00
feat: scan inscription revealed
This commit is contained in:
@@ -490,12 +490,13 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
|
||||
&hord_db_conn,
|
||||
&block_identifier,
|
||||
&transaction_identifier,
|
||||
0,
|
||||
&ctx,
|
||||
)?;
|
||||
info!(
|
||||
ctx.expect_logger(),
|
||||
"Satoshi #{} was minted in block #{} at offset {} and was transferred {} times.",
|
||||
traversal.ordinal_number, traversal.ordinal_block_number, traversal.ordinal_offset, traversal.transfers
|
||||
traversal.ordinal_number, traversal.get_ordinal_coinbase_height(), traversal.get_ordinal_coinbase_offset(), traversal.transfers
|
||||
);
|
||||
}
|
||||
FindCommand::Inscription(cmd) => {
|
||||
|
||||
@@ -12,6 +12,10 @@ use chainhook_event_observer::hord::db::{
|
||||
fetch_and_cache_blocks_in_hord_db, find_all_inscriptions, find_compacted_block_at_block_height,
|
||||
find_latest_compacted_block_known, open_readonly_hord_db_conn, open_readwrite_hord_db_conn,
|
||||
};
|
||||
use chainhook_event_observer::hord::{
|
||||
update_storage_and_augment_bitcoin_block_with_inscription_reveal_data,
|
||||
update_storage_and_augment_bitcoin_block_with_inscription_transfer_data, Storage,
|
||||
};
|
||||
use chainhook_event_observer::indexer;
|
||||
use chainhook_event_observer::indexer::bitcoin::{
|
||||
retrieve_block_hash_with_retry, retrieve_full_block_breakdown_with_retry,
|
||||
@@ -135,25 +139,44 @@ pub async fn scan_bitcoin_chain_with_predicate(
|
||||
|
||||
let event_observer_config = config.get_event_observer_config();
|
||||
let bitcoin_config = event_observer_config.get_bitcoin_config();
|
||||
|
||||
let mut traversals = HashMap::new();
|
||||
if is_predicate_evaluating_ordinals {
|
||||
for (cursor, _inscriptions) in inscriptions_cache.into_iter() {
|
||||
let hord_db_conn = open_readonly_hord_db_conn(&config.expected_cache_path(), ctx)?;
|
||||
|
||||
let mut storage = Storage::Memory(BTreeMap::new());
|
||||
for (cursor, local_traverals) in inscriptions_cache.into_iter() {
|
||||
// Only consider inscriptions in the interval specified
|
||||
if cursor < start_block || cursor > end_block {
|
||||
continue;
|
||||
}
|
||||
for (transaction_identifier, traversal_result) in local_traverals.into_iter() {
|
||||
traversals.insert(transaction_identifier, traversal_result);
|
||||
}
|
||||
|
||||
blocks_scanned += 1;
|
||||
|
||||
let block_hash = retrieve_block_hash_with_retry(&cursor, &bitcoin_config, ctx).await?;
|
||||
let block_breakdown =
|
||||
retrieve_full_block_breakdown_with_retry(&block_hash, &bitcoin_config, ctx).await?;
|
||||
let block = indexer::bitcoin::standardize_bitcoin_block(
|
||||
let mut block = indexer::bitcoin::standardize_bitcoin_block(
|
||||
block_breakdown,
|
||||
&event_observer_config.bitcoin_network,
|
||||
ctx,
|
||||
)?;
|
||||
|
||||
update_storage_and_augment_bitcoin_block_with_inscription_reveal_data(
|
||||
&mut block,
|
||||
&mut storage,
|
||||
&traversals,
|
||||
&hord_db_conn,
|
||||
&ctx,
|
||||
);
|
||||
|
||||
update_storage_and_augment_bitcoin_block_with_inscription_transfer_data(
|
||||
&mut block,
|
||||
&mut storage,
|
||||
&ctx,
|
||||
);
|
||||
let chain_event =
|
||||
BitcoinChainEvent::ChainUpdatedWithBlocks(BitcoinChainUpdatedWithBlocksData {
|
||||
new_blocks: vec![block],
|
||||
|
||||
@@ -20,7 +20,10 @@ use crate::{
|
||||
utils::Context,
|
||||
};
|
||||
|
||||
use super::{ord::height::Height, update_hord_db_and_augment_bitcoin_block};
|
||||
use super::{
|
||||
ord::{height::Height, sat::Sat},
|
||||
update_hord_db_and_augment_bitcoin_block,
|
||||
};
|
||||
|
||||
fn get_default_hord_db_file_path(base_dir: &PathBuf) -> PathBuf {
|
||||
let mut destination_path = base_dir.clone();
|
||||
@@ -350,30 +353,50 @@ pub fn find_inscription_with_ordinal_number(
|
||||
return None;
|
||||
}
|
||||
|
||||
pub fn find_all_inscriptions(hord_db_conn: &Connection) -> BTreeMap<u64, Vec<(String, u64, u64)>> {
|
||||
pub fn find_all_inscriptions(
|
||||
hord_db_conn: &Connection,
|
||||
) -> BTreeMap<u64, Vec<(TransactionIdentifier, TraversalResult)>> {
|
||||
let args: &[&dyn ToSql] = &[];
|
||||
let mut stmt = hord_db_conn
|
||||
.prepare("SELECT inscription_id, inscription_number, ordinal_number, block_height FROM inscriptions ORDER BY inscription_number ASC")
|
||||
.prepare("SELECT inscription_number, ordinal_number, block_height, inscription_id FROM inscriptions ORDER BY inscription_number ASC")
|
||||
.unwrap();
|
||||
let mut results: BTreeMap<u64, Vec<(String, u64, u64)>> = BTreeMap::new();
|
||||
let mut results: BTreeMap<u64, Vec<(TransactionIdentifier, TraversalResult)>> = BTreeMap::new();
|
||||
let mut rows = stmt.query(args).unwrap();
|
||||
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 block_height: u64 = row.get(3).unwrap();
|
||||
let inscription_number: u64 = row.get(0).unwrap();
|
||||
let ordinal_number: u64 = row.get(1).unwrap();
|
||||
let block_height: u64 = row.get(2).unwrap();
|
||||
let transaction_id = {
|
||||
let inscription_id: String = row.get(3).unwrap();
|
||||
TransactionIdentifier {
|
||||
hash: format!("0x{}", &inscription_id[0..inscription_id.len() - 2]),
|
||||
}
|
||||
};
|
||||
let traversal = TraversalResult {
|
||||
inscription_number,
|
||||
ordinal_number,
|
||||
transfers: 0,
|
||||
};
|
||||
results
|
||||
.entry(block_height)
|
||||
.and_modify(|v| v.push((inscription_id.clone(), inscription_number, ordinal_number)))
|
||||
.or_insert(vec![(inscription_id, inscription_number, ordinal_number)]);
|
||||
.and_modify(|v| v.push((transaction_id.clone(), traversal.clone())))
|
||||
.or_insert(vec![(transaction_id, traversal)]);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct WatchedSatpoint {
|
||||
pub inscription_id: String,
|
||||
pub inscription_number: u64,
|
||||
pub ordinal_number: u64,
|
||||
pub offset: u64,
|
||||
}
|
||||
|
||||
pub fn find_inscriptions_at_wached_outpoint(
|
||||
outpoint: &str,
|
||||
hord_db_conn: &Connection,
|
||||
) -> Vec<(String, u64, u64, u64)> {
|
||||
) -> Vec<WatchedSatpoint> {
|
||||
let args: &[&dyn ToSql] = &[&outpoint.to_sql().unwrap()];
|
||||
let mut stmt = hord_db_conn
|
||||
.prepare("SELECT inscription_id, inscription_number, ordinal_number, offset FROM inscriptions WHERE outpoint_to_watch = ? ORDER BY offset ASC")
|
||||
@@ -385,7 +408,12 @@ pub fn find_inscriptions_at_wached_outpoint(
|
||||
let inscription_number: u64 = row.get(1).unwrap();
|
||||
let ordinal_number: u64 = row.get(2).unwrap();
|
||||
let offset: u64 = row.get(3).unwrap();
|
||||
results.push((inscription_id, inscription_number, ordinal_number, offset));
|
||||
results.push(WatchedSatpoint {
|
||||
inscription_id,
|
||||
inscription_number,
|
||||
ordinal_number,
|
||||
offset,
|
||||
});
|
||||
}
|
||||
return results;
|
||||
}
|
||||
@@ -456,88 +484,6 @@ pub fn remove_entry_from_inscriptions(
|
||||
}
|
||||
}
|
||||
|
||||
// pub async fn update_hord_db(
|
||||
// bitcoin_config: &BitcoinConfig,
|
||||
// hord_db_path: &PathBuf,
|
||||
// start_block: u64,
|
||||
// end_block: u64,
|
||||
// _ctx: &Context,
|
||||
// network_thread: usize,
|
||||
// ) -> Result<(), String> {
|
||||
// let (block_tx, block_rx) = channel::<BitcoinBlockFullBreakdown>();
|
||||
// let first_inscription_block_height = 767430;
|
||||
// let ctx = _ctx.clone();
|
||||
// let network = bitcoin_config.network.clone();
|
||||
// let hord_db_path = hord_db_path.clone();
|
||||
// let handle = hiro_system_kit::thread_named("Inscriptions indexing")
|
||||
// .spawn(move || {
|
||||
// let mut cursor = first_inscription_block_height;
|
||||
// let mut inbox = HashMap::new();
|
||||
|
||||
// while let Ok(raw_block) = block_rx.recv() {
|
||||
// // Early return, only considering blocks after 1st inscription
|
||||
// if raw_block.height < first_inscription_block_height {
|
||||
// continue;
|
||||
// }
|
||||
// let block_height = raw_block.height;
|
||||
// inbox.insert(raw_block.height, raw_block);
|
||||
|
||||
// // In the context of ordinals, we're constrained to process blocks sequentially
|
||||
// // Blocks are processed by a threadpool and could be coming out of order.
|
||||
// // Inbox block for later if the current block is not the one we should be
|
||||
// // processing.
|
||||
// if block_height != cursor {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// // Is the action of processing a block allows us
|
||||
// // to process more blocks present in the inbox?
|
||||
// while let Some(next_block) = inbox.remove(&cursor) {
|
||||
// let mut new_block = match standardize_bitcoin_block(next_block, &network, &ctx)
|
||||
// {
|
||||
// Ok(block) => block,
|
||||
// Err(e) => {
|
||||
// ctx.try_log(|logger| {
|
||||
// slog::error!(logger, "Unable to standardize bitcoin block: {e}",)
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
// };
|
||||
|
||||
// if let Err(e) = update_hord_db_and_augment_bitcoin_block(
|
||||
// &mut new_block,
|
||||
// &hord_db_path,
|
||||
// &ctx,
|
||||
// ) {
|
||||
// ctx.try_log(|logger| {
|
||||
// slog::error!(
|
||||
// logger,
|
||||
// "Unable to augment bitcoin block with hord_db: {e}",
|
||||
// )
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
// cursor += 1;
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .expect("unable to detach thread");
|
||||
|
||||
// fetch_and_cache_blocks_in_hord_db(
|
||||
// bitcoin_config,
|
||||
// hord_db_conn,
|
||||
// start_block,
|
||||
// end_block,
|
||||
// &_ctx,
|
||||
// network_thread,
|
||||
// )
|
||||
// .await?;
|
||||
|
||||
// let _ = handle.join();
|
||||
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
pub fn delete_data_in_hord_db(
|
||||
start_block: u64,
|
||||
end_block: u64,
|
||||
@@ -698,17 +644,30 @@ pub async fn fetch_and_cache_blocks_in_hord_db(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TraversalResult {
|
||||
pub ordinal_block_number: u64,
|
||||
pub ordinal_offset: u64,
|
||||
pub inscription_number: u64,
|
||||
pub ordinal_number: u64,
|
||||
pub transfers: u32,
|
||||
}
|
||||
|
||||
impl TraversalResult {
|
||||
pub fn get_ordinal_coinbase_height(&self) -> u64 {
|
||||
let sat = Sat(self.ordinal_number);
|
||||
sat.height().n()
|
||||
}
|
||||
|
||||
pub fn get_ordinal_coinbase_offset(&self) -> u64 {
|
||||
let sat = Sat(self.ordinal_number);
|
||||
self.ordinal_number - sat.height().starting_sat().n()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn retrieve_satoshi_point_using_local_storage(
|
||||
hord_db_conn: &Connection,
|
||||
block_identifier: &BlockIdentifier,
|
||||
transaction_identifier: &TransactionIdentifier,
|
||||
inscription_number: u64,
|
||||
ctx: &Context,
|
||||
) -> Result<TraversalResult, String> {
|
||||
ctx.try_log(|logger| {
|
||||
@@ -851,8 +810,7 @@ pub fn retrieve_satoshi_point_using_local_storage(
|
||||
let ordinal_number = height.starting_sat().0 + ordinal_offset;
|
||||
|
||||
Ok(TraversalResult {
|
||||
ordinal_block_number: ordinal_block_number.into(),
|
||||
ordinal_offset,
|
||||
inscription_number,
|
||||
ordinal_number,
|
||||
transfers: hops,
|
||||
})
|
||||
|
||||
@@ -9,7 +9,7 @@ use chainhook_types::{
|
||||
};
|
||||
use hiro_system_kit::slog;
|
||||
use rusqlite::Connection;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::collections::{BTreeMap, HashMap, VecDeque};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::mpsc::channel;
|
||||
use threadpool::ThreadPool;
|
||||
@@ -29,7 +29,7 @@ use crate::{
|
||||
|
||||
use self::db::{
|
||||
open_readonly_hord_db_conn, remove_entry_from_blocks, remove_entry_from_inscriptions,
|
||||
TraversalResult,
|
||||
TraversalResult, WatchedSatpoint,
|
||||
};
|
||||
|
||||
pub fn revert_hord_db_with_augmented_bitcoin_block(
|
||||
@@ -94,13 +94,6 @@ pub fn update_hord_db_and_augment_bitcoin_block(
|
||||
);
|
||||
}
|
||||
|
||||
let mut cumulated_fees = 0;
|
||||
let coinbase_txid = &new_block.transactions[0]
|
||||
.transaction_identifier
|
||||
.hash
|
||||
.clone();
|
||||
let first_sat_post_subsidy = Height(new_block.block_identifier.index).starting_sat().0;
|
||||
|
||||
let mut transactions_ids = vec![];
|
||||
for new_tx in new_block.transactions.iter_mut().skip(1) {
|
||||
// Have a new inscription been revealed, if so, are looking at a re-inscription
|
||||
@@ -128,6 +121,7 @@ pub fn update_hord_db_and_augment_bitcoin_block(
|
||||
&hord_db_conn,
|
||||
&block_identifier,
|
||||
&transaction_id,
|
||||
0,
|
||||
&moved_ctx,
|
||||
)
|
||||
.unwrap();
|
||||
@@ -145,7 +139,38 @@ pub fn update_hord_db_and_augment_bitcoin_block(
|
||||
}
|
||||
}
|
||||
|
||||
for new_tx in new_block.transactions.iter_mut().skip(1) {
|
||||
let mut storage = Storage::Sqlite(rw_hord_db_conn);
|
||||
update_storage_and_augment_bitcoin_block_with_inscription_reveal_data(
|
||||
new_block,
|
||||
&mut storage,
|
||||
&traversals,
|
||||
rw_hord_db_conn,
|
||||
&ctx,
|
||||
);
|
||||
|
||||
// Have inscriptions been transfered?
|
||||
update_storage_and_augment_bitcoin_block_with_inscription_transfer_data(
|
||||
new_block,
|
||||
&mut Storage::Sqlite(rw_hord_db_conn),
|
||||
&ctx,
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Storage<'a> {
|
||||
Sqlite(&'a Connection),
|
||||
Memory(BTreeMap<String, Vec<WatchedSatpoint>>),
|
||||
}
|
||||
|
||||
pub fn update_storage_and_augment_bitcoin_block_with_inscription_reveal_data(
|
||||
block: &mut BitcoinBlockData,
|
||||
storage: &mut Storage,
|
||||
traversals: &HashMap<TransactionIdentifier, TraversalResult>,
|
||||
hord_db_conn: &Connection,
|
||||
ctx: &Context,
|
||||
) {
|
||||
for new_tx in block.transactions.iter_mut().skip(1) {
|
||||
let mut ordinals_events_indexes_to_discard = VecDeque::new();
|
||||
// Have a new inscription been revealed, if so, are looking at a re-inscription
|
||||
for (ordinal_event_index, ordinal_event) in
|
||||
@@ -161,64 +186,95 @@ pub fn update_hord_db_and_augment_bitcoin_block(
|
||||
continue;
|
||||
}
|
||||
};
|
||||
inscription.ordinal_offset = traversal.get_ordinal_coinbase_offset();
|
||||
inscription.ordinal_block_height = traversal.get_ordinal_coinbase_height();
|
||||
inscription.ordinal_number = traversal.ordinal_number;
|
||||
inscription.transfers_pre_inscription = traversal.transfers;
|
||||
|
||||
if let Some(_entry) = find_inscription_with_ordinal_number(
|
||||
&traversal.ordinal_number,
|
||||
&rw_hord_db_conn,
|
||||
&ctx,
|
||||
) {
|
||||
ctx.try_log(|logger| {
|
||||
slog::warn!(
|
||||
match storage {
|
||||
Storage::Sqlite(rw_hord_db_conn) => {
|
||||
if let Some(_entry) = find_inscription_with_ordinal_number(
|
||||
&traversal.ordinal_number,
|
||||
&hord_db_conn,
|
||||
&ctx,
|
||||
) {
|
||||
ctx.try_log(|logger| {
|
||||
slog::warn!(
|
||||
logger,
|
||||
"Transaction {} in block {} is overriding an existing inscription {}",
|
||||
new_tx.transaction_identifier.hash,
|
||||
new_block.block_identifier.index,
|
||||
block.block_identifier.index,
|
||||
traversal.ordinal_number
|
||||
);
|
||||
});
|
||||
ordinals_events_indexes_to_discard.push_front(ordinal_event_index);
|
||||
} else {
|
||||
inscription.ordinal_offset = traversal.ordinal_offset;
|
||||
inscription.ordinal_block_height = traversal.ordinal_block_number;
|
||||
inscription.ordinal_number = traversal.ordinal_number;
|
||||
inscription.transfers_pre_inscription = traversal.transfers;
|
||||
inscription.inscription_number =
|
||||
match find_latest_inscription_number(&rw_hord_db_conn, &ctx) {
|
||||
Ok(inscription_number) => inscription_number,
|
||||
Err(e) => {
|
||||
ctx.try_log(|logger| {
|
||||
slog::error!(
|
||||
logger,
|
||||
"unable to retrieve satoshi number: {}",
|
||||
e.to_string()
|
||||
);
|
||||
});
|
||||
continue;
|
||||
}
|
||||
};
|
||||
ctx.try_log(|logger| {
|
||||
slog::info!(
|
||||
});
|
||||
ordinals_events_indexes_to_discard.push_front(ordinal_event_index);
|
||||
} else {
|
||||
inscription.inscription_number =
|
||||
match find_latest_inscription_number(&hord_db_conn, &ctx) {
|
||||
Ok(inscription_number) => inscription_number,
|
||||
Err(e) => {
|
||||
ctx.try_log(|logger| {
|
||||
slog::error!(
|
||||
logger,
|
||||
"unable to retrieve satoshi number: {}",
|
||||
e.to_string()
|
||||
);
|
||||
});
|
||||
continue;
|
||||
}
|
||||
};
|
||||
ctx.try_log(|logger| {
|
||||
slog::info!(
|
||||
logger,
|
||||
"Transaction {} in block {} inscribed some content ({}) on Satoshi #{}",
|
||||
new_tx.transaction_identifier.hash,
|
||||
new_block.block_identifier.index,
|
||||
block.block_identifier.index,
|
||||
inscription.content_type,
|
||||
traversal.ordinal_number
|
||||
);
|
||||
});
|
||||
|
||||
{
|
||||
});
|
||||
}
|
||||
store_new_inscription(
|
||||
&inscription,
|
||||
&new_block.block_identifier,
|
||||
&block.block_identifier,
|
||||
&rw_hord_db_conn,
|
||||
&ctx,
|
||||
)
|
||||
);
|
||||
}
|
||||
Storage::Memory(map) => {
|
||||
let outpoint = inscription.satpoint_post_inscription
|
||||
[0..inscription.satpoint_post_inscription.len() - 2]
|
||||
.to_string();
|
||||
map.insert(
|
||||
outpoint,
|
||||
vec![WatchedSatpoint {
|
||||
inscription_id: inscription.inscription_id.clone(),
|
||||
inscription_number: inscription.inscription_number,
|
||||
ordinal_number: inscription.ordinal_number,
|
||||
offset: 0,
|
||||
}],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for index in ordinals_events_indexes_to_discard.into_iter() {
|
||||
new_tx.metadata.ordinal_operations.remove(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_storage_and_augment_bitcoin_block_with_inscription_transfer_data(
|
||||
block: &mut BitcoinBlockData,
|
||||
storage: &mut Storage,
|
||||
ctx: &Context,
|
||||
) {
|
||||
let mut cumulated_fees = 0;
|
||||
let first_sat_post_subsidy = Height(block.block_identifier.index).starting_sat().0;
|
||||
let coinbase_txid = &block.transactions[0].transaction_identifier.hash.clone();
|
||||
|
||||
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;
|
||||
@@ -233,26 +289,24 @@ pub fn update_hord_db_and_augment_bitcoin_block(
|
||||
|
||||
let mut post_transfer_output_index = 0;
|
||||
|
||||
let entries =
|
||||
find_inscriptions_at_wached_outpoint(&outpoint_pre_transfer, &rw_hord_db_conn);
|
||||
let entries = match storage {
|
||||
Storage::Sqlite(rw_hord_db_conn) => {
|
||||
find_inscriptions_at_wached_outpoint(&outpoint_pre_transfer, &rw_hord_db_conn)
|
||||
}
|
||||
Storage::Memory(ref mut map) => match map.remove(&outpoint_pre_transfer) {
|
||||
Some(entries) => entries,
|
||||
None => vec![],
|
||||
},
|
||||
};
|
||||
|
||||
// ctx.try_log(|logger| {
|
||||
// slog::info!(
|
||||
// logger,
|
||||
// "Checking if {} is part of our watch outpoints set: {}",
|
||||
// outpoint_pre_transfer,
|
||||
// entries.len(),
|
||||
// )
|
||||
// });
|
||||
|
||||
for (inscription_id, inscription_number, ordinal_number, offset) in entries.into_iter()
|
||||
{
|
||||
let satpoint_pre_transfer = format!("{}:{}", outpoint_pre_transfer, offset);
|
||||
for mut watched_satpoint in entries.into_iter() {
|
||||
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 + offset {
|
||||
if sats_out_offset >= sats_in_offset + watched_satpoint.offset {
|
||||
break Some(post_transfer_output_index);
|
||||
}
|
||||
if post_transfer_output_index + 1 >= new_tx.metadata.outputs.len() {
|
||||
@@ -322,31 +376,39 @@ pub fn update_hord_db_and_augment_bitcoin_block(
|
||||
logger,
|
||||
"Transaction {} in block {} moved inscribed Satoshi #{} from {} to {}",
|
||||
new_tx.transaction_identifier.hash,
|
||||
new_block.block_identifier.index,
|
||||
ordinal_number,
|
||||
block.block_identifier.index,
|
||||
watched_satpoint.ordinal_number,
|
||||
satpoint_pre_transfer,
|
||||
outpoint_post_transfer,
|
||||
)
|
||||
});
|
||||
|
||||
// Update watched outpoint
|
||||
{
|
||||
update_transfered_inscription(
|
||||
&inscription_id,
|
||||
&outpoint_post_transfer,
|
||||
offset_post_transfer,
|
||||
&rw_hord_db_conn,
|
||||
&ctx,
|
||||
);
|
||||
}
|
||||
match storage {
|
||||
Storage::Sqlite(rw_hord_db_conn) => {
|
||||
update_transfered_inscription(
|
||||
&watched_satpoint.inscription_id,
|
||||
&outpoint_post_transfer,
|
||||
offset_post_transfer,
|
||||
&rw_hord_db_conn,
|
||||
&ctx,
|
||||
);
|
||||
}
|
||||
Storage::Memory(ref mut map) => {
|
||||
watched_satpoint.offset = offset_post_transfer;
|
||||
map.entry(outpoint_post_transfer.clone())
|
||||
.and_modify(|v| v.push(watched_satpoint.clone()))
|
||||
.or_insert(vec![watched_satpoint.clone()]);
|
||||
}
|
||||
};
|
||||
|
||||
let satpoint_post_transfer =
|
||||
format!("{}:{}", outpoint_post_transfer, offset_post_transfer);
|
||||
|
||||
let event_data = OrdinalInscriptionTransferData {
|
||||
inscription_id,
|
||||
inscription_number,
|
||||
ordinal_number,
|
||||
inscription_id: watched_satpoint.inscription_id.clone(),
|
||||
inscription_number: watched_satpoint.inscription_number,
|
||||
ordinal_number: watched_satpoint.ordinal_number,
|
||||
updated_address,
|
||||
satpoint_pre_transfer,
|
||||
satpoint_post_transfer,
|
||||
@@ -358,16 +420,8 @@ pub fn update_hord_db_and_augment_bitcoin_block(
|
||||
.ordinal_operations
|
||||
.push(OrdinalOperation::InscriptionTransferred(event_data));
|
||||
}
|
||||
|
||||
sats_in_offset += input.previous_output.value;
|
||||
}
|
||||
|
||||
// - clean new_tx.metadata.ordinal_operations with ordinals_events_indexes_to_ignore
|
||||
for index in ordinals_events_indexes_to_discard.into_iter() {
|
||||
new_tx.metadata.ordinal_operations.remove(index);
|
||||
}
|
||||
|
||||
cumulated_fees += new_tx.metadata.fee;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user