fix: pointer ignored

This commit is contained in:
Ludo Galabru
2024-01-23 17:05:44 -05:00
parent 801dd3a795
commit 2db6f1fb44
7 changed files with 267 additions and 286 deletions

View File

@@ -164,6 +164,8 @@ struct ScanTransactionCommand {
pub block_height: u64,
/// Inscription Id
pub transaction_id: String,
/// Input index
pub input_index: usize,
/// Target Regtest network
#[clap(
long = "regtest",
@@ -675,10 +677,11 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
.await?;
let transaction_identifier = TransactionIdentifier::new(&cmd.transaction_id);
let cache = new_traversals_lazy_cache(100);
let (res, mut back_trace) = compute_satoshi_number(
let (res, _, mut back_trace) = compute_satoshi_number(
&config.get_ordhook_config().db_path,
&block.block_identifier,
&transaction_identifier,
cmd.input_index,
0,
&Arc::new(cache),
config.resources.ulimit,
@@ -687,8 +690,8 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> {
ctx,
)?;
back_trace.reverse();
for (block_height, tx) in back_trace.iter() {
println!("{}\t{}", block_height, hex::encode(tx));
for (block_height, tx, index) in back_trace.iter() {
println!("{}\t{}:{}", block_height, hex::encode(tx), index);
}
println!("{:?}", res);
}

View File

@@ -262,7 +262,7 @@ pub fn process_block(
block: &mut BitcoinBlockData,
next_blocks: &Vec<BitcoinBlockData>,
sequence_cursor: &mut SequenceCursor,
cache_l1: &mut BTreeMap<(TransactionIdentifier, usize), TraversalResult>,
cache_l1: &mut BTreeMap<(TransactionIdentifier, usize, u64), TraversalResult>,
cache_l2: &Arc<DashMap<(u32, [u8; 8]), TransactionBytesCursor, BuildHasherDefault<FxHasher>>>,
inscriptions_db_tx: &Transaction,
ordhook_config: &OrdhookConfig,

View File

@@ -8,8 +8,8 @@ use chainhook_sdk::{
bitcoincore_rpc_json::bitcoin::{Address, Network, ScriptBuf},
types::{
BitcoinBlockData, BitcoinNetwork, BitcoinTransactionData, BlockIdentifier,
OrdinalInscriptionCurseType, OrdinalInscriptionNumber, OrdinalOperation,
TransactionIdentifier,
OrdinalInscriptionCurseType, OrdinalInscriptionNumber,
OrdinalInscriptionTransferDestination, OrdinalOperation, TransactionIdentifier,
},
utils::Context,
};
@@ -23,8 +23,8 @@ use crate::{
db::{
find_blessed_inscription_with_ordinal_number, find_nth_classic_neg_number_at_block_height,
find_nth_classic_pos_number_at_block_height, find_nth_jubilee_number_at_block_height,
format_inscription_id, format_satpoint_to_watch, update_inscriptions_with_block,
update_sequence_metadata_with_block, TransactionBytesCursor, TraversalResult,
format_inscription_id, update_inscriptions_with_block, update_sequence_metadata_with_block,
TransactionBytesCursor, TraversalResult,
},
ord::height::Height,
};
@@ -37,7 +37,9 @@ use crate::db::find_all_inscriptions_in_block;
use super::{
inscription_parsing::get_inscriptions_revealed_in_block,
inscription_tracking::augment_transaction_with_ordinals_transfers_data,
inscription_tracking::{
augment_transaction_with_ordinals_transfers_data, compute_satpoint_post_transfer,
},
satoshi_numbering::compute_satoshi_number,
};
@@ -67,7 +69,7 @@ use super::{
pub fn parallelize_inscription_data_computations(
block: &BitcoinBlockData,
next_blocks: &Vec<BitcoinBlockData>,
cache_l1: &mut BTreeMap<(TransactionIdentifier, usize), TraversalResult>,
cache_l1: &mut BTreeMap<(TransactionIdentifier, usize, u64), TraversalResult>,
cache_l2: &Arc<DashMap<(u32, [u8; 8]), TransactionBytesCursor, BuildHasherDefault<FxHasher>>>,
inscriptions_db_tx: &Transaction,
ordhook_config: &OrdhookConfig,
@@ -118,20 +120,27 @@ pub fn parallelize_inscription_data_computations(
let handle = hiro_system_kit::thread_named("Worker")
.spawn(move || {
while let Ok(Some((transaction_id, block_identifier, input_index, prioritary))) =
rx.recv()
while let Ok(Some((
transaction_id,
block_identifier,
input_index,
inscription_pointer,
prioritary,
))) = rx.recv()
{
let traversal: Result<(TraversalResult, _), String> = compute_satoshi_number(
&moved_ordhook_db_path,
&block_identifier,
&transaction_id,
input_index,
&local_cache,
ulimit,
memory_available,
false,
&moved_ctx,
);
let traversal: Result<(TraversalResult, u64, _), String> =
compute_satoshi_number(
&moved_ordhook_db_path,
&block_identifier,
&transaction_id,
input_index,
inscription_pointer,
&local_cache,
ulimit,
memory_available,
false,
&moved_ctx,
);
let _ = moved_traversal_tx.send((traversal, prioritary, thread_index));
}
})
@@ -144,8 +153,11 @@ pub fn parallelize_inscription_data_computations(
let mut round_robin_thread_index = 0;
for key in l1_cache_hits.iter() {
if let Some(entry) = cache_l1.get(key) {
let _ =
traversal_tx.send((Ok((entry.clone(), vec![])), true, round_robin_thread_index));
let _ = traversal_tx.send((
Ok((entry.clone(), key.2, vec![])),
true,
round_robin_thread_index,
));
round_robin_thread_index = (round_robin_thread_index + 1) % thread_pool_capacity;
}
}
@@ -173,11 +185,12 @@ pub fn parallelize_inscription_data_computations(
let mut priority_queue = VecDeque::new();
let mut warmup_queue = VecDeque::new();
for (transaction_id, input_index) in transactions_ids.into_iter() {
for (transaction_id, input_index, inscription_pointer) in transactions_ids.into_iter() {
priority_queue.push_back((
transaction_id,
block.block_identifier.clone(),
input_index,
inscription_pointer,
true,
));
}
@@ -197,13 +210,14 @@ pub fn parallelize_inscription_data_computations(
traversals_received += 1;
}
match traversal_result {
Ok((traversal, _)) => {
Ok((traversal, inscription_pointer, _)) => {
inner_ctx.try_log(|logger| {
info!(
logger,
"Completed ordinal number retrieval for Satpoint {}:{}:0 (block: #{}:{}, transfers: {}, progress: {traversals_received}/{expected_traversals}, priority queue: {prioritary}, thread: {thread_index})",
"Completed ordinal number retrieval for Satpoint {}:{}:{} (block: #{}:{}, transfers: {}, progress: {traversals_received}/{expected_traversals}, priority queue: {prioritary}, thread: {thread_index})",
traversal.transaction_identifier_inscription.hash,
traversal.inscription_input_index,
inscription_pointer,
traversal.get_ordinal_coinbase_height(),
traversal.get_ordinal_coinbase_offset(),
traversal.transfers
@@ -213,6 +227,7 @@ pub fn parallelize_inscription_data_computations(
(
traversal.transaction_identifier_inscription.clone(),
traversal.inscription_input_index,
inscription_pointer,
),
traversal,
);
@@ -248,11 +263,14 @@ pub fn parallelize_inscription_data_computations(
});
transactions_ids.shuffle(&mut rng);
for (transaction_id, input_index) in transactions_ids.into_iter() {
for (transaction_id, input_index, inscription_pointer) in
transactions_ids.into_iter()
{
warmup_queue.push_back((
transaction_id,
next_block.block_identifier.clone(),
input_index,
inscription_pointer,
false,
));
}
@@ -272,13 +290,14 @@ pub fn parallelize_inscription_data_computations(
for tx in tx_thread_pool.iter() {
// Empty the queue
if let Ok((traversal_result, _prioritary, thread_index)) = traversal_rx.try_recv() {
if let Ok((traversal, _)) = traversal_result {
if let Ok((traversal, inscription_pointer, _)) = traversal_result {
inner_ctx.try_log(|logger| {
info!(
logger,
"Completed ordinal number retrieval for Satpoint {}:{}:0 (block: #{}:{}, transfers: {}, pre-retrieval, thread: {thread_index})",
"Completed ordinal number retrieval for Satpoint {}:{}:{} (block: #{}:{}, transfers: {}, pre-retrieval, thread: {thread_index})",
traversal.transaction_identifier_inscription.hash,
traversal.inscription_input_index,
inscription_pointer,
traversal.get_ordinal_coinbase_height(),
traversal.get_ordinal_coinbase_offset(),
traversal.transfers
@@ -288,6 +307,7 @@ pub fn parallelize_inscription_data_computations(
(
traversal.transaction_identifier_inscription.clone(),
traversal.inscription_input_index,
inscription_pointer,
),
traversal,
);
@@ -332,14 +352,14 @@ pub fn parallelize_inscription_data_computations(
///
fn get_transactions_to_process(
block: &BitcoinBlockData,
cache_l1: &mut BTreeMap<(TransactionIdentifier, usize), TraversalResult>,
cache_l1: &mut BTreeMap<(TransactionIdentifier, usize, u64), TraversalResult>,
inscriptions_db_tx: &Transaction,
ctx: &Context,
) -> (
Vec<(TransactionIdentifier, usize)>,
Vec<(TransactionIdentifier, usize)>,
Vec<(TransactionIdentifier, usize, u64)>,
Vec<(TransactionIdentifier, usize, u64)>,
) {
let mut transactions_ids: Vec<(TransactionIdentifier, usize)> = vec![];
let mut transactions_ids: Vec<(TransactionIdentifier, usize, u64)> = vec![];
let mut l1_cache_hits = vec![];
let known_transactions =
@@ -357,6 +377,7 @@ fn get_transactions_to_process(
let key = (
tx.transaction_identifier.clone(),
inscription_data.inscription_input_index,
inscription_data.inscription_pointer,
);
if cache_l1.contains_key(&key) {
l1_cache_hits.push(key);
@@ -371,6 +392,7 @@ fn get_transactions_to_process(
transactions_ids.push((
tx.transaction_identifier.clone(),
inscription_data.inscription_input_index,
inscription_data.inscription_pointer,
));
}
}
@@ -520,7 +542,7 @@ impl<'a> SequenceCursor<'a> {
pub fn augment_block_with_ordinals_inscriptions_data_and_write_to_db_tx(
block: &mut BitcoinBlockData,
sequence_cursor: &mut SequenceCursor,
inscriptions_data: &mut BTreeMap<(TransactionIdentifier, usize), TraversalResult>,
inscriptions_data: &mut BTreeMap<(TransactionIdentifier, usize, u64), TraversalResult>,
inscriptions_db_tx: &Transaction,
ctx: &Context,
) -> bool {
@@ -563,7 +585,7 @@ pub fn augment_block_with_ordinals_inscriptions_data_and_write_to_db_tx(
pub fn augment_block_with_ordinals_inscriptions_data(
block: &mut BitcoinBlockData,
sequence_cursor: &mut SequenceCursor,
inscriptions_data: &mut BTreeMap<(TransactionIdentifier, usize), TraversalResult>,
inscriptions_data: &mut BTreeMap<(TransactionIdentifier, usize, u64), TraversalResult>,
reinscriptions_data: &mut HashMap<u64, String>,
ctx: &Context,
) -> bool {
@@ -577,6 +599,9 @@ pub fn augment_block_with_ordinals_inscriptions_data(
BitcoinNetwork::Testnet => Network::Testnet,
BitcoinNetwork::Signet => Network::Signet,
};
let coinbase_subsidy = Height(block.block_identifier.index).subsidy();
let coinbase_txid = &block.transactions[0].transaction_identifier.clone();
let mut cumulated_fees = 0u64;
for (tx_index, tx) in block.transactions.iter_mut().enumerate() {
any_event |= augment_transaction_with_ordinals_inscriptions_data(
@@ -586,6 +611,9 @@ pub fn augment_block_with_ordinals_inscriptions_data(
sequence_cursor,
&network,
inscriptions_data,
coinbase_txid,
coinbase_subsidy,
&mut cumulated_fees,
&mut sats_overflows,
reinscriptions_data,
ctx,
@@ -637,14 +665,19 @@ fn augment_transaction_with_ordinals_inscriptions_data(
block_identifier: &BlockIdentifier,
sequence_cursor: &mut SequenceCursor,
network: &Network,
inscriptions_data: &mut BTreeMap<(TransactionIdentifier, usize), TraversalResult>,
inscriptions_data: &mut BTreeMap<(TransactionIdentifier, usize, u64), TraversalResult>,
coinbase_txid: &TransactionIdentifier,
coinbase_subsidy: u64,
cumulated_fees: &mut u64,
sats_overflows: &mut VecDeque<(usize, usize)>,
reinscriptions_data: &mut HashMap<u64, String>,
ctx: &Context,
) -> bool {
let any_event = tx.metadata.ordinal_operations.is_empty() == false;
let mut mutated_operations = vec![];
mutated_operations.append(&mut tx.metadata.ordinal_operations);
let mut inscription_subindex = 0;
for (op_index, op) in tx.metadata.ordinal_operations.iter_mut().enumerate() {
for (op_index, op) in mutated_operations.iter_mut().enumerate() {
let (mut is_cursed, inscription) = match op {
OrdinalOperation::InscriptionRevealed(inscription) => {
(inscription.curse_type.as_ref().is_some(), inscription)
@@ -654,9 +687,11 @@ fn augment_transaction_with_ordinals_inscriptions_data(
let transaction_identifier = tx.transaction_identifier.clone();
let inscription_id = format_inscription_id(&transaction_identifier, inscription_subindex);
let traversal = match inscriptions_data
.get(&(transaction_identifier, inscription.inscription_input_index))
{
let traversal = match inscriptions_data.get(&(
transaction_identifier,
inscription.inscription_input_index,
inscription.inscription_pointer,
)) {
Some(traversal) => traversal,
None => {
let err_msg = format!(
@@ -698,7 +733,6 @@ fn augment_transaction_with_ordinals_inscriptions_data(
inscription.inscription_id = inscription_id;
inscription.inscription_number = inscription_number;
let outputs = &tx.metadata.outputs;
inscription.ordinal_offset = traversal.get_ordinal_coinbase_offset();
inscription.ordinal_block_height = traversal.get_ordinal_coinbase_height();
inscription.ordinal_number = traversal.ordinal_number;
@@ -709,33 +743,29 @@ fn augment_transaction_with_ordinals_inscriptions_data(
Some(curse_type) => Some(curse_type),
None => inscription.curse_type.take(),
};
inscription.satpoint_post_inscription = format_satpoint_to_watch(
&traversal.transfer_data.transaction_identifier_location,
traversal.transfer_data.output_index,
traversal.transfer_data.inscription_offset_intra_output,
let (destination, satpoint_post_transfer, output_value) = compute_satpoint_post_transfer(
&&*tx,
traversal.inscription_input_index,
inscription.inscription_pointer,
network,
coinbase_txid,
coinbase_subsidy,
cumulated_fees,
ctx,
);
if let Some(output) = outputs.get(traversal.transfer_data.output_index) {
inscription.inscription_output_value = output.value;
inscription.inscriber_address = {
let script_pub_key = output.get_script_pubkey_hex();
match ScriptBuf::from_hex(&script_pub_key) {
Ok(script) => match Address::from_script(&script, network.clone()) {
Ok(a) => Some(a.to_string()),
_ => None,
},
_ => None,
}
};
} else {
ctx.try_log(|logger| {
warn!(
logger,
"Database corrupted, skipping cursed inscription => {:?} / {:?}",
traversal,
outputs
);
});
}
// Compute satpoint_post_inscription
inscription.satpoint_post_inscription = satpoint_post_transfer;
match destination {
OrdinalInscriptionTransferDestination::SpentInFees => {}
OrdinalInscriptionTransferDestination::Burnt(_) => {}
OrdinalInscriptionTransferDestination::Transferred(address) => {
inscription.inscription_output_value = output_value.unwrap_or(0);
inscription.inscriber_address = Some(address);
}
};
if traversal.ordinal_number == 0 {
// If the satoshi inscribed correspond to a sat overflow, we will store the inscription
@@ -770,6 +800,10 @@ fn augment_transaction_with_ordinals_inscriptions_data(
}
inscription_subindex += 1;
}
tx.metadata
.ordinal_operations
.append(&mut mutated_operations);
any_event
}
@@ -779,12 +813,17 @@ fn consolidate_transaction_with_pre_computed_inscription_data(
tx: &mut BitcoinTransactionData,
tx_index: usize,
coinbase_txid: &TransactionIdentifier,
coinbase_subsidy: u64,
cumulated_fees: &mut u64,
network: &Network,
inscriptions_data: &mut BTreeMap<String, TraversalResult>,
_ctx: &Context,
ctx: &Context,
) {
let mut subindex = 0;
for operation in tx.metadata.ordinal_operations.iter_mut() {
let mut mutated_operations = vec![];
mutated_operations.append(&mut tx.metadata.ordinal_operations);
for operation in mutated_operations.iter_mut() {
let inscription = match operation {
OrdinalOperation::InscriptionRevealed(ref mut inscription) => inscription,
OrdinalOperation::InscriptionTransferred(_) => continue,
@@ -805,42 +844,37 @@ fn consolidate_transaction_with_pre_computed_inscription_data(
inscription.transfers_pre_inscription = traversal.transfers;
inscription.inscription_fee = tx.metadata.fee;
inscription.tx_index = tx_index;
inscription.satpoint_post_inscription = format_satpoint_to_watch(
&traversal.transfer_data.transaction_identifier_location,
traversal.transfer_data.output_index,
traversal.transfer_data.inscription_offset_intra_output,
// Compute satpoint_post_inscription
let (destination, satpoint_post_transfer, output_value) = compute_satpoint_post_transfer(
tx,
traversal.inscription_input_index,
inscription.inscription_pointer,
network,
coinbase_txid,
coinbase_subsidy,
cumulated_fees,
ctx,
);
inscription.satpoint_post_inscription = satpoint_post_transfer;
if inscription.inscription_number.classic < 0 {
inscription.curse_type = Some(OrdinalInscriptionCurseType::Generic);
}
if traversal
.transfer_data
.transaction_identifier_location
.eq(coinbase_txid)
{
continue;
}
if let Some(output) = tx
.metadata
.outputs
.get(traversal.transfer_data.output_index)
{
inscription.inscription_output_value = output.value;
inscription.inscriber_address = {
let script_pub_key = output.get_script_pubkey_hex();
match ScriptBuf::from_hex(&script_pub_key) {
Ok(script) => match Address::from_script(&script, network.clone()) {
Ok(a) => Some(a.to_string()),
_ => None,
},
_ => None,
}
};
match destination {
OrdinalInscriptionTransferDestination::SpentInFees => continue,
OrdinalInscriptionTransferDestination::Burnt(_) => continue,
OrdinalInscriptionTransferDestination::Transferred(address) => {
inscription.inscription_output_value = output_value.unwrap_or(0);
inscription.inscriber_address = Some(address);
}
}
}
tx.metadata
.ordinal_operations
.append(&mut mutated_operations);
}
/// Best effort to re-augment a `BitcoinBlockData` with data coming from `inscriptions` and `locations` tables.
@@ -884,6 +918,8 @@ pub fn consolidate_block_with_pre_computed_ordinals_data(
tx,
tx_index,
coinbase_txid,
coinbase_subsidy,
&mut cumulated_fees,
&network,
&mut inscriptions_data,
ctx,

View File

@@ -66,6 +66,87 @@ pub fn augment_block_with_ordinals_transfer_data(
any_event
}
pub fn compute_satpoint_post_transfer(
tx: &BitcoinTransactionData,
input_index: usize,
inscription_pointer: u64,
network: &Network,
coinbase_txid: &TransactionIdentifier,
coinbase_subsidy: u64,
cumulated_fees: &mut u64,
ctx: &Context,
) -> (OrdinalInscriptionTransferDestination, String, Option<u64>) {
let inputs: Vec<u64> = tx
.metadata
.inputs
.iter()
.map(|o| o.previous_output.value)
.collect::<_>();
let outputs = tx.metadata.outputs.iter().map(|o| o.value).collect::<_>();
let post_transfer_data =
compute_next_satpoint_data(input_index, 0, &inputs, &outputs, inscription_pointer);
let (outpoint_post_transfer, offset_post_transfer, destination, post_transfer_output_value) =
match post_transfer_data {
SatPosition::Output((output_index, offset)) => {
let outpoint = format_outpoint_to_watch(&tx.transaction_identifier, output_index);
let script_pub_key_hex = tx.metadata.outputs[output_index].get_script_pubkey_hex();
let updated_address = match ScriptBuf::from_hex(&script_pub_key_hex) {
Ok(script) => match Address::from_script(&script, network.clone()) {
Ok(address) => {
OrdinalInscriptionTransferDestination::Transferred(address.to_string())
}
Err(e) => {
ctx.try_log(|logger| {
info!(
logger,
"unable to retrieve address from {script_pub_key_hex}: {}",
e.to_string()
)
});
OrdinalInscriptionTransferDestination::Burnt(script.to_string())
}
},
Err(e) => {
ctx.try_log(|logger| {
info!(
logger,
"unable to retrieve address from {script_pub_key_hex}: {}",
e.to_string()
)
});
OrdinalInscriptionTransferDestination::Burnt(script_pub_key_hex.to_string())
}
};
(
outpoint,
offset,
updated_address,
Some(tx.metadata.outputs[output_index].value),
)
}
SatPosition::Fee(offset) => {
// Get Coinbase TX
let total_offset = coinbase_subsidy + *cumulated_fees + offset;
let outpoint = format_outpoint_to_watch(&coinbase_txid, 0);
(
outpoint,
total_offset,
OrdinalInscriptionTransferDestination::SpentInFees,
None,
)
}
};
let satpoint_post_transfer = format!("{}:{}", outpoint_post_transfer, offset_post_transfer);
(
destination,
satpoint_post_transfer,
post_transfer_output_value,
)
}
pub fn augment_transaction_with_ordinals_transfers_data(
tx: &mut BitcoinTransactionData,
tx_index: usize,
@@ -93,109 +174,17 @@ pub fn augment_transaction_with_ordinals_transfers_data(
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 inputs = tx
.metadata
.inputs
.iter()
.map(|o| o.previous_output.value)
.collect::<_>();
let outputs = tx.metadata.outputs.iter().map(|o| o.value).collect::<_>();
let post_transfer_data = compute_next_satpoint_data(
input_index,
watched_satpoint.offset,
&inputs,
&outputs,
0,
);
let (
outpoint_post_transfer,
offset_post_transfer,
destination,
post_transfer_output_value,
) = match post_transfer_data {
SatPosition::Output((output_index, offset)) => {
let outpoint =
format_outpoint_to_watch(&tx.transaction_identifier, output_index);
let script_pub_key_hex =
tx.metadata.outputs[output_index].get_script_pubkey_hex();
let updated_address = match ScriptBuf::from_hex(&script_pub_key_hex) {
Ok(script) => match Address::from_script(&script, network.clone()) {
Ok(address) => OrdinalInscriptionTransferDestination::Transferred(
address.to_string(),
),
Err(e) => {
ctx.try_log(|logger| {
info!(
logger,
"unable to retrieve address from {script_pub_key_hex}: {}",
e.to_string()
)
});
OrdinalInscriptionTransferDestination::Burnt(script.to_string())
}
},
Err(e) => {
ctx.try_log(|logger| {
info!(
logger,
"unable to retrieve address from {script_pub_key_hex}: {}",
e.to_string()
)
});
OrdinalInscriptionTransferDestination::Burnt(
script_pub_key_hex.to_string(),
)
}
};
// At this point we know that inscriptions are being moved.
ctx.try_log(|logger| {
info!(
logger,
"Inscribed satoshi {} moved from {} to {} (block: {})",
watched_satpoint.ordinal_number,
satpoint_pre_transfer,
outpoint,
block_identifier.index,
)
});
(
outpoint,
offset,
updated_address,
Some(tx.metadata.outputs[output_index].value),
)
}
SatPosition::Fee(offset) => {
// Get Coinbase TX
let total_offset = coinbase_subsidy + *cumulated_fees + offset;
let outpoint = format_outpoint_to_watch(&coinbase_txid, 0);
ctx.try_log(|logger| {
info!(
logger,
"Inscribed satoshi {} spent in fees ({}+{}+{})",
watched_satpoint.ordinal_number,
coinbase_subsidy,
cumulated_fees,
offset
)
});
(
outpoint,
total_offset,
OrdinalInscriptionTransferDestination::SpentInFees,
None,
)
}
};
let satpoint_post_transfer =
format!("{}:{}", outpoint_post_transfer, offset_post_transfer);
let (destination, satpoint_post_transfer, post_transfer_output_value) =
compute_satpoint_post_transfer(
&&*tx,
input_index,
0,
network,
coinbase_txid,
coinbase_subsidy,
cumulated_fees,
ctx,
);
let transfer_data = OrdinalInscriptionTransferData {
ordinal_number: watched_satpoint.ordinal_number,

View File

@@ -8,7 +8,6 @@ use std::sync::Arc;
use crate::db::{
find_pinned_block_bytes_at_block_height, open_ordhook_db_conn_rocks_db_loop, BlockBytesCursor,
TransferData,
};
use crate::db::{TransactionBytesCursor, TraversalResult};
@@ -19,6 +18,7 @@ pub fn compute_satoshi_number(
block_identifier: &BlockIdentifier,
transaction_identifier: &TransactionIdentifier,
inscription_input_index: usize,
inscription_pointer: u64,
traversals_cache: &Arc<
DashMap<(u32, [u8; 8]), TransactionBytesCursor, BuildHasherDefault<FxHasher>>,
>,
@@ -26,25 +26,20 @@ pub fn compute_satoshi_number(
memory_available: usize,
_back_tracking: bool,
ctx: &Context,
) -> Result<(TraversalResult, Vec<(u32, [u8; 8])>), String> {
let mut inscription_offset_intra_output = 0;
let mut inscription_output_index: usize = 0;
let mut ordinal_offset = 0;
let mut ordinal_block_number = block_identifier.index as u32;
) -> Result<(TraversalResult, u64, Vec<(u32, [u8; 8], usize)>), String> {
let mut ordinal_offset = inscription_pointer;
let ordinal_block_number = block_identifier.index as u32;
let txid = transaction_identifier.get_8_hash_bytes();
let mut back_track = vec![];
let blocks_db =
open_ordhook_db_conn_rocks_db_loop(false, &blocks_db_dir, ulimit, memory_available, &ctx);
let (sats_ranges, inscription_offset_cross_outputs) = match traversals_cache
let (mut tx_cursor, mut ordinal_block_number) = match traversals_cache
.get(&(block_identifier.index as u32, txid.clone()))
{
Some(entry) => {
let tx = entry.value();
(
tx.get_sat_ranges(),
tx.get_cumulated_sats_in_until_input_index(inscription_input_index),
)
((tx.inputs[inscription_input_index].txin.clone(), tx.inputs[inscription_input_index].vout.into()), tx.inputs[inscription_input_index].block_height)
}
None => loop {
match find_pinned_block_bytes_at_block_height(ordinal_block_number, 3, &blocks_db, &ctx)
@@ -56,12 +51,7 @@ pub fn compute_satoshi_number(
let cursor = BlockBytesCursor::new(&block_bytes.as_ref());
match cursor.find_and_serialize_transaction_with_txid(&txid) {
Some(tx) => {
let sats_ranges = tx.get_sat_ranges();
let inscription_offset_cross_outputs =
tx.get_cumulated_sats_in_until_input_index(inscription_input_index);
traversals_cache.insert((ordinal_block_number, txid.clone()), tx);
back_track.push((ordinal_block_number, txid.clone()));
break (sats_ranges, inscription_offset_cross_outputs);
break ((tx.inputs[inscription_input_index].txin.clone(), tx.inputs[inscription_input_index].vout.into()), tx.inputs[inscription_input_index].block_height);
}
None => return Err(format!("txid not in block #{ordinal_block_number}")),
}
@@ -70,23 +60,6 @@ pub fn compute_satoshi_number(
},
};
for (i, (min, max)) in sats_ranges.into_iter().enumerate() {
if inscription_offset_cross_outputs >= min && inscription_offset_cross_outputs < max {
inscription_output_index = i;
inscription_offset_intra_output = inscription_offset_cross_outputs - min;
}
}
ctx.try_log(|logger| {
debug!(
logger,
"Start ordinal number retrieval for Satpoint {}:{}:0 (block #{})",
transaction_identifier.hash,
inscription_input_index,
block_identifier.index
)
});
let mut tx_cursor: ([u8; 8], usize) = (txid, inscription_input_index);
let mut hops: u32 = 0;
loop {
@@ -143,13 +116,8 @@ pub fn compute_satoshi_number(
transfers: 0,
inscription_input_index,
transaction_identifier_inscription: transaction_identifier.clone(),
transfer_data: TransferData {
inscription_offset_intra_output,
transaction_identifier_location: transaction_identifier.clone(),
output_index: inscription_output_index,
tx_index: 0,
},
},
inscription_pointer,
back_track,
));
}
@@ -231,7 +199,7 @@ pub fn compute_satoshi_number(
}
} else {
// isolate the target transaction
let lazy_tx = match block_cursor.find_and_serialize_transaction_with_txid(&txid) {
let tx_bytes_cursor = match block_cursor.find_and_serialize_transaction_with_txid(&txid) {
Some(entry) => entry,
None => {
ctx.try_log(|logger| {
@@ -247,7 +215,7 @@ pub fn compute_satoshi_number(
};
let mut sats_out = 0;
for (index, output_value) in lazy_tx.outputs.iter().enumerate() {
for (index, output_value) in tx_bytes_cursor.outputs.iter().enumerate() {
if index == tx_cursor.1 {
break;
}
@@ -256,12 +224,12 @@ pub fn compute_satoshi_number(
sats_out += ordinal_offset;
let mut sats_in = 0;
for input in lazy_tx.inputs.iter() {
for input in tx_bytes_cursor.inputs.iter() {
sats_in += input.txin_value;
if sats_out < sats_in {
back_track.push((ordinal_block_number, tx_cursor.0.clone()));
traversals_cache.insert((ordinal_block_number, tx_cursor.0), lazy_tx.clone());
back_track.push((ordinal_block_number, tx_cursor.0.clone(), tx_cursor.1));
traversals_cache.insert((ordinal_block_number, tx_cursor.0), tx_bytes_cursor.clone());
ordinal_offset = sats_out - (sats_in - input.txin_value);
ordinal_block_number = input.block_height;
tx_cursor = (input.txin.clone(), input.vout as usize);
@@ -284,13 +252,8 @@ pub fn compute_satoshi_number(
transfers: 0,
inscription_input_index,
transaction_identifier_inscription: transaction_identifier.clone(),
transfer_data: TransferData {
inscription_offset_intra_output,
transaction_identifier_location: transaction_identifier.clone(),
output_index: inscription_output_index,
tx_index: 0,
},
},
inscription_pointer,
back_track,
));
}
@@ -298,7 +261,7 @@ pub fn compute_satoshi_number(
}
let height = Height(ordinal_block_number.into());
let ordinal_number = height.starting_sat().0 + ordinal_offset + inscription_offset_intra_output;
let ordinal_number = height.starting_sat().0 + ordinal_offset;
Ok((
TraversalResult {
@@ -307,13 +270,8 @@ pub fn compute_satoshi_number(
transfers: hops,
inscription_input_index,
transaction_identifier_inscription: transaction_identifier.clone(),
transfer_data: TransferData {
inscription_offset_intra_output,
transaction_identifier_location: transaction_identifier.clone(),
output_index: inscription_output_index,
tx_index: 0,
},
},
inscription_pointer,
back_track,
))
}

View File

@@ -1091,11 +1091,6 @@ pub fn find_inscription_with_id(
));
};
let Some(transfer_data) =
find_initial_inscription_transfer_data(&ordinal_number, db_conn, ctx)?
else {
return Err(format!("unable to retrieve location for {inscription_id}"));
};
Ok(Some((
TraversalResult {
inscription_number,
@@ -1103,7 +1098,6 @@ pub fn find_inscription_with_id(
inscription_input_index,
transaction_identifier_inscription,
transfers: 0,
transfer_data,
},
block_height,
)))
@@ -1114,8 +1108,6 @@ pub fn find_all_inscriptions_in_block(
inscriptions_db_tx: &Connection,
ctx: &Context,
) -> BTreeMap<String, TraversalResult> {
let transfers_data = find_all_transfers_in_block(block_height, inscriptions_db_tx, ctx);
let args: &[&dyn ToSql] = &[&block_height.to_sql().unwrap()];
let mut stmt = loop {
@@ -1155,26 +1147,12 @@ pub fn find_all_inscriptions_in_block(
let inscription_input_index: usize = row.get(4).unwrap();
let (transaction_identifier_inscription, _) =
{ parse_inscription_id(&inscription_id) };
let Some(transfer_data) = transfers_data
.get(&ordinal_number)
.and_then(|entries| entries.first())
else {
ctx.try_log(|logger| {
error!(
logger,
"unable to retrieve inscription genesis transfer data: {}",
inscription_id,
)
});
continue;
};
let traversal = TraversalResult {
inscription_number,
ordinal_number,
inscription_input_index,
transfers: 0,
transaction_identifier_inscription: transaction_identifier_inscription.clone(),
transfer_data: transfer_data.clone(),
};
results.insert(inscription_id, traversal);
}
@@ -1333,7 +1311,6 @@ pub struct TraversalResult {
pub transaction_identifier_inscription: TransactionIdentifier,
pub ordinal_number: u64,
pub transfers: u32,
pub transfer_data: TransferData,
}
impl TraversalResult {

View File

@@ -35,7 +35,13 @@ pub fn update_observer_progress(
"UPDATE observers SET last_block_height_update = ? WHERE uuid = ?",
rusqlite::params![last_block_height_update, uuid],
) {
ctx.try_log(|logger| warn!(logger, "unable to query observers.sqlite: {}", e.to_string()));
ctx.try_log(|logger| {
warn!(
logger,
"unable to query observers.sqlite: {}",
e.to_string()
)
});
std::thread::sleep(std::time::Duration::from_secs(1));
}
}
@@ -50,7 +56,13 @@ pub fn update_observer_streaming_enabled(
"UPDATE observers SET streaming_enabled = ? WHERE uuid = ?",
rusqlite::params![streaming_enabled, uuid],
) {
ctx.try_log(|logger| warn!(logger, "unable to query observers.sqlite: {}", e.to_string()));
ctx.try_log(|logger| {
warn!(
logger,
"unable to query observers.sqlite: {}",
e.to_string()
)
});
std::thread::sleep(std::time::Duration::from_secs(1));
}
}
@@ -177,7 +189,13 @@ pub fn remove_entry_from_observers(uuid: &str, db_conn: &Connection, ctx: &Conte
"DELETE FROM observers WHERE uuid = ?1",
rusqlite::params![&uuid],
) {
ctx.try_log(|logger| warn!(logger, "unable to query observers.sqlite: {}", e.to_string()));
ctx.try_log(|logger| {
warn!(
logger,
"unable to query observers.sqlite: {}",
e.to_string()
)
});
std::thread::sleep(std::time::Duration::from_secs(1));
}
}