diff --git a/components/ordhook-cli/src/cli/mod.rs b/components/ordhook-cli/src/cli/mod.rs index c675d8c1..1b03980c 100644 --- a/components/ordhook-cli/src/cli/mod.rs +++ b/components/ordhook-cli/src/cli/mod.rs @@ -178,6 +178,9 @@ struct RepairStorageCommand { /// Cascade to observers #[clap(short, long, action = clap::ArgAction::SetTrue)] pub repair_observers: Option, + /// Display debug logs + #[clap(short, long, action = clap::ArgAction::SetTrue)] + pub debug: Option, } impl RepairStorageCommand { @@ -714,7 +717,28 @@ async fn handle_command(opts: Opts, ctx: &Context) -> Result<(), String> { 10_000, &ctx, ) - .await? + .await?; + if let Some(true) = cmd.debug { + let blocks_db = open_ordhook_db_conn_rocks_db_loop(false, &config.get_ordhook_config().db_path, ctx); + for i in cmd.get_blocks().into_iter() { + let block = find_lazy_block_at_block_height(i as u32, 10, false, &blocks_db, ctx).expect("unable to retrieve block {i}"); + info!( + ctx.expect_logger(), + "--------------------" + ); + info!( + ctx.expect_logger(), + "Block: {i}" + ); + for tx in block.iter_tx() { + info!( + ctx.expect_logger(), + "Tx: {}", + ordhook::hex::encode(tx.txid) + ); + } + } + } } RepairCommand::Inscriptions(cmd) => { let config = ConfigFile::default(false, false, false, &cmd.config_path)?; diff --git a/components/ordhook-core/src/core/protocol/satoshi_numbering.rs b/components/ordhook-core/src/core/protocol/satoshi_numbering.rs index 297c4f81..362ae9d0 100644 --- a/components/ordhook-core/src/core/protocol/satoshi_numbering.rs +++ b/components/ordhook-core/src/core/protocol/satoshi_numbering.rs @@ -234,7 +234,17 @@ pub fn compute_satoshi_number( // isolate the target transaction let lazy_tx = match lazy_block.find_and_serialize_transaction_with_txid(&txid) { Some(entry) => entry, - None => break, + None => { + ctx.try_log(|logger| { + error!( + logger, + "fatal: unable to retrieve tx ancestor {} in block {ordinal_block_number} (satpoint {}:{inscription_input_index})", + hex::encode(txid), + transaction_identifier.get_hash_bytes_str(), + ) + }); + std::process::exit(1); + }, }; let mut sats_out = 0; diff --git a/components/ordhook-core/src/db/mod.rs b/components/ordhook-core/src/db/mod.rs index 148658c5..0c75c746 100644 --- a/components/ordhook-core/src/db/mod.rs +++ b/components/ordhook-core/src/db/mod.rs @@ -1300,9 +1300,18 @@ impl LazyBlock { let tx_len = block.tx.len() as u16 - 1; buffer.write(&tx_len.to_be_bytes())?; // For each transaction: + let u16_max = u16::MAX as usize; for tx in block.tx.iter().skip(1) { - let inputs_len = tx.vin.len() as u16; - let outputs_len = tx.vout.len() as u16; + let inputs_len = if tx.vin.len() > u16_max { + 0 + } else { + tx.vin.len() as u16 + }; + let outputs_len = if tx.vout.len() > u16_max { + 0 + } else { + tx.vout.len() as u16 + }; // Number of inputs buffer.write(&inputs_len.to_be_bytes())?; // Number of outputs @@ -1332,8 +1341,21 @@ impl LazyBlock { ] }; buffer.write_all(&txid)?; + + let inputs_len = if tx.vin.len() > u16_max { + 0 + } else { + tx.vin.len() as usize + }; + let outputs_len = if tx.vout.len() > u16_max { + 0 + } else { + tx.vout.len() as usize + }; + // For each transaction input: - for input in tx.vin.iter() { + for i in 0..inputs_len { + let input = &tx.vin[i]; // txin - 8 first bytes let txin = { let txid = hex::decode(input.txid.as_ref().unwrap().to_string()).unwrap(); @@ -1353,7 +1375,8 @@ impl LazyBlock { buffer.write(&sats.to_be_bytes())?; } // For each transaction output: - for output in tx.vout.iter() { + for i in 0..outputs_len { + let output = &tx.vout[i]; let sats = output.value.to_sat(); buffer.write(&sats.to_be_bytes())?; } diff --git a/components/ordhook-core/src/lib.rs b/components/ordhook-core/src/lib.rs index aadaed27..7158994d 100644 --- a/components/ordhook-core/src/lib.rs +++ b/components/ordhook-core/src/lib.rs @@ -10,6 +10,7 @@ extern crate serde_derive; extern crate serde; pub extern crate chainhook_sdk; +pub extern crate hex; pub mod config; pub mod core;