mirror of
https://github.com/alexgo-io/bitcoin-indexer.git
synced 2026-06-14 00:22:19 +08:00
fix: additional fixes (network, address, offsets)
This commit is contained in:
@@ -455,15 +455,18 @@ pub fn find_inscription_with_id(
|
||||
if block_hash.eq(&inscription_block_hash) {
|
||||
let inscription_number: i64 = row.get(0).unwrap();
|
||||
let ordinal_number: u64 = row.get(1).unwrap();
|
||||
let inscription_offset: u64 = row.get(3).unwrap();
|
||||
let inscription_offset_intra_output: u64 = row.get(3).unwrap();
|
||||
let outpoint_to_watch: String = row.get(4).unwrap();
|
||||
let (transaction_identifier, output_index) =
|
||||
parse_outpoint_to_watch(&outpoint_to_watch);
|
||||
let (_, input_index) = parse_inscription_id(inscription_id);
|
||||
let traversal = TraversalResult {
|
||||
inscription_number,
|
||||
ordinal_number,
|
||||
input_index,
|
||||
inscription_offset,
|
||||
outpoint_to_watch,
|
||||
inscription_offset_intra_output,
|
||||
transaction_identifier,
|
||||
output_index,
|
||||
transfers: 0,
|
||||
};
|
||||
return Some(traversal);
|
||||
@@ -490,15 +493,18 @@ pub fn find_all_inscriptions_in_block(
|
||||
let inscription_id: String = row.get(3).unwrap();
|
||||
parse_inscription_id(&inscription_id)
|
||||
};
|
||||
let inscription_offset: u64 = row.get(4).unwrap();
|
||||
let inscription_offset_intra_output: u64 = row.get(4).unwrap();
|
||||
let outpoint_to_watch: String = row.get(5).unwrap();
|
||||
let (transaction_identifier, output_index) = parse_outpoint_to_watch(&outpoint_to_watch);
|
||||
|
||||
let traversal = TraversalResult {
|
||||
inscription_number,
|
||||
ordinal_number,
|
||||
input_index,
|
||||
transfers: 0,
|
||||
inscription_offset,
|
||||
outpoint_to_watch,
|
||||
inscription_offset_intra_output,
|
||||
transaction_identifier,
|
||||
output_index,
|
||||
};
|
||||
results
|
||||
.entry(block_height)
|
||||
@@ -849,9 +855,10 @@ pub async fn fetch_and_cache_blocks_in_hord_db(
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TraversalResult {
|
||||
pub inscription_number: i64,
|
||||
pub inscription_offset: u64,
|
||||
pub inscription_offset_intra_output: u64,
|
||||
pub input_index: usize,
|
||||
pub outpoint_to_watch: String,
|
||||
pub output_index: usize,
|
||||
pub transaction_identifier: TransactionIdentifier,
|
||||
pub ordinal_number: u64,
|
||||
pub transfers: u32,
|
||||
}
|
||||
@@ -939,14 +946,45 @@ pub fn retrieve_satoshi_point_using_lazy_storage(
|
||||
block_identifier.index
|
||||
)
|
||||
});
|
||||
let mut inscription_localized = false;
|
||||
let mut inscription_offset = 0;
|
||||
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;
|
||||
let txid = transaction_identifier.get_8_hash_bytes();
|
||||
let mut tx_cursor = (txid, input_index);
|
||||
|
||||
let (sats_ranges, inscription_offset_cross_outputs) =
|
||||
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(input_index),
|
||||
)
|
||||
}
|
||||
None => match find_lazy_block_at_block_height(ordinal_block_number, 10, &blocks_db) {
|
||||
None => {
|
||||
return Err(format!("block #{ordinal_block_number} not in database"));
|
||||
}
|
||||
Some(block) => match block.find_and_serialize_transaction_with_txid(&txid) {
|
||||
Some(tx) => (
|
||||
tx.get_sat_ranges(),
|
||||
tx.get_cumulated_sats_in_until_input_index(input_index),
|
||||
),
|
||||
None => return Err(format!("block #{ordinal_block_number} not in database")),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
let mut tx_cursor: ([u8; 8], usize) = (txid, input_index);
|
||||
let mut hops: u32 = 0;
|
||||
|
||||
loop {
|
||||
hops += 1;
|
||||
if hops as u64 > block_identifier.index {
|
||||
@@ -959,30 +997,6 @@ pub fn retrieve_satoshi_point_using_lazy_storage(
|
||||
if let Some(cached_tx) = traversals_cache.get(&(ordinal_block_number, tx_cursor.0)) {
|
||||
let tx = cached_tx.value();
|
||||
|
||||
if !inscription_localized {
|
||||
inscription_localized = true;
|
||||
let mut sats_ranges = vec![];
|
||||
let mut bound = 0;
|
||||
for output_value in tx.outputs.iter() {
|
||||
sats_ranges.push((bound, bound + output_value));
|
||||
bound += output_value;
|
||||
}
|
||||
let mut input_offset = 0;
|
||||
for (i, input) in tx.inputs.iter().enumerate() {
|
||||
if i == input_index {
|
||||
break;
|
||||
}
|
||||
input_offset += input.txin_value;
|
||||
}
|
||||
|
||||
for (i, (min, max)) in sats_ranges.into_iter().enumerate() {
|
||||
if input_offset >= min && input_offset < max {
|
||||
inscription_output_index = i;
|
||||
inscription_offset = input_offset - min;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut next_found_in_cache = false;
|
||||
let mut sats_out = 0;
|
||||
for (index, output_value) in tx.outputs.iter().enumerate() {
|
||||
@@ -1022,12 +1036,10 @@ pub fn retrieve_satoshi_point_using_lazy_storage(
|
||||
inscription_number: 0,
|
||||
ordinal_number: 0,
|
||||
transfers: 0,
|
||||
inscription_offset,
|
||||
inscription_offset_intra_output,
|
||||
input_index,
|
||||
outpoint_to_watch: format_outpoint_to_watch(
|
||||
&transaction_identifier,
|
||||
inscription_output_index,
|
||||
),
|
||||
transaction_identifier: transaction_identifier.clone(),
|
||||
output_index: inscription_output_index,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1095,30 +1107,6 @@ pub fn retrieve_satoshi_point_using_lazy_storage(
|
||||
None => unreachable!(),
|
||||
};
|
||||
|
||||
if !inscription_localized {
|
||||
inscription_localized = true;
|
||||
let mut sats_ranges = vec![];
|
||||
let mut bound = 0;
|
||||
for output_value in lazy_tx.outputs.iter() {
|
||||
sats_ranges.push((bound, bound + output_value));
|
||||
bound += output_value;
|
||||
}
|
||||
let mut input_offset = 0;
|
||||
for (i, input) in lazy_tx.inputs.iter().enumerate() {
|
||||
if i == input_index {
|
||||
break;
|
||||
}
|
||||
input_offset += input.txin_value;
|
||||
}
|
||||
|
||||
for (i, (min, max)) in sats_ranges.into_iter().enumerate() {
|
||||
if input_offset >= min && input_offset < max {
|
||||
inscription_output_index = i;
|
||||
inscription_offset = input_offset - min;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut sats_out = 0;
|
||||
for (index, output_value) in lazy_tx.outputs.iter().enumerate() {
|
||||
if index == tx_cursor.1 {
|
||||
@@ -1153,30 +1141,27 @@ pub fn retrieve_satoshi_point_using_lazy_storage(
|
||||
inscription_number: 0,
|
||||
ordinal_number: 0,
|
||||
transfers: 0,
|
||||
inscription_offset,
|
||||
inscription_offset_intra_output,
|
||||
input_index,
|
||||
outpoint_to_watch: format_outpoint_to_watch(
|
||||
&transaction_identifier,
|
||||
inscription_output_index,
|
||||
),
|
||||
transaction_identifier: transaction_identifier.clone(),
|
||||
output_index: inscription_output_index,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let height = Height(ordinal_block_number.into());
|
||||
let ordinal_number = height.starting_sat().0 + ordinal_offset + inscription_offset;
|
||||
let ordinal_number =
|
||||
height.starting_sat().0 + ordinal_offset + inscription_offset_cross_outputs;
|
||||
|
||||
Ok(TraversalResult {
|
||||
inscription_number,
|
||||
ordinal_number,
|
||||
transfers: hops,
|
||||
inscription_offset,
|
||||
inscription_offset_intra_output,
|
||||
input_index,
|
||||
outpoint_to_watch: format_outpoint_to_watch(
|
||||
&transaction_identifier,
|
||||
inscription_output_index,
|
||||
),
|
||||
transaction_identifier: transaction_identifier.clone(),
|
||||
output_index: inscription_output_index,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1197,6 +1182,27 @@ impl LazyBlockTransaction {
|
||||
pub fn get_average_bytes_size() -> usize {
|
||||
TXID_LEN + 3 * LazyBlockTransactionInput::get_average_bytes_size() + 3 * SATS_LEN
|
||||
}
|
||||
|
||||
pub fn get_sat_ranges(&self) -> Vec<(u64, u64)> {
|
||||
let mut sats_ranges = vec![];
|
||||
let mut bound = 0u64;
|
||||
for output_value in self.outputs.iter() {
|
||||
sats_ranges.push((bound, bound + output_value));
|
||||
bound += output_value;
|
||||
}
|
||||
sats_ranges
|
||||
}
|
||||
|
||||
pub fn get_cumulated_sats_in_until_input_index(&self, input_index: usize) -> u64 {
|
||||
let mut cumulated_sats_in = 0;
|
||||
for (i, input) in self.inputs.iter().enumerate() {
|
||||
if i == input_index {
|
||||
break;
|
||||
}
|
||||
cumulated_sats_in += input.txin_value;
|
||||
}
|
||||
cumulated_sats_in
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
||||
@@ -6,7 +6,7 @@ use bitcoincore_rpc::bitcoin::hashes::hex::FromHex;
|
||||
use bitcoincore_rpc::bitcoin::{Address, Network, Script};
|
||||
use bitcoincore_rpc_json::bitcoin::Witness;
|
||||
use chainhook_types::{
|
||||
BitcoinBlockData, OrdinalInscriptionCurseType, OrdinalInscriptionRevealData,
|
||||
BitcoinBlockData, BitcoinNetwork, OrdinalInscriptionCurseType, OrdinalInscriptionRevealData,
|
||||
OrdinalInscriptionTransferData, OrdinalOperation, TransactionIdentifier,
|
||||
};
|
||||
use dashmap::DashMap;
|
||||
@@ -96,21 +96,6 @@ pub fn parse_ordinal_operations(
|
||||
index: input_index as u32,
|
||||
};
|
||||
|
||||
let inscription_output_value = tx
|
||||
.vout
|
||||
.get(0)
|
||||
.and_then(|o| Some(o.value.to_sat()))
|
||||
.unwrap_or(0);
|
||||
|
||||
let inscriber_address = if let Ok(authors) = Address::from_script(
|
||||
&tx.vout[0].script_pub_key.script().unwrap(),
|
||||
bitcoincore_rpc::bitcoin::Network::Bitcoin,
|
||||
) {
|
||||
Some(authors.to_string())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if input_index > 0 {
|
||||
inscription.curse = Some(OrdinalInscriptionCurseType::Batch);
|
||||
}
|
||||
@@ -123,16 +108,16 @@ pub fn parse_ordinal_operations(
|
||||
content_bytes: format!("0x{}", hex::encode(&inscription_content_bytes)),
|
||||
content_length: inscription_content_bytes.len(),
|
||||
inscription_id: inscription_id.to_string(),
|
||||
inscriber_address,
|
||||
inscription_output_value,
|
||||
inscription_fee: 0,
|
||||
inscription_input_index: input_index,
|
||||
inscription_output_value: 0,
|
||||
inscription_fee: 0,
|
||||
inscription_number: 0,
|
||||
inscriber_address: None,
|
||||
ordinal_number: 0,
|
||||
ordinal_block_height: 0,
|
||||
ordinal_offset: 0,
|
||||
transfers_pre_inscription: 0,
|
||||
satpoint_post_inscription: format!("{}:0:0", tx.txid.clone()),
|
||||
satpoint_post_inscription: format!(""),
|
||||
curse_type: inscription.curse.take(),
|
||||
};
|
||||
|
||||
@@ -435,7 +420,11 @@ pub fn update_storage_and_augment_bitcoin_block_with_inscription_reveal_data(
|
||||
ctx: &Context,
|
||||
) -> Result<bool, String> {
|
||||
let mut storage_updated = false;
|
||||
|
||||
let network = match block.metadata.network {
|
||||
BitcoinNetwork::Mainnet => Network::Bitcoin,
|
||||
BitcoinNetwork::Regtest => Network::Regtest,
|
||||
BitcoinNetwork::Testnet => Network::Testnet,
|
||||
};
|
||||
let mut latest_inscription_number = match find_latest_inscription_number_at_block_height(
|
||||
&block.block_identifier.index,
|
||||
&inscriptions_db_conn,
|
||||
@@ -499,9 +488,24 @@ pub fn update_storage_and_augment_bitcoin_block_with_inscription_reveal_data(
|
||||
inscription.transfers_pre_inscription = traversal.transfers;
|
||||
inscription.inscription_fee = new_tx.metadata.fee;
|
||||
inscription.satpoint_post_inscription = format!(
|
||||
"{}:{}",
|
||||
traversal.outpoint_to_watch, traversal.inscription_offset
|
||||
"{}:{}:{}",
|
||||
traversal.transaction_identifier.hash,
|
||||
traversal.output_index,
|
||||
traversal.inscription_offset_intra_output
|
||||
);
|
||||
inscription.inscription_output_value =
|
||||
new_tx.metadata.outputs[traversal.output_index].value;
|
||||
inscription.inscriber_address = {
|
||||
let script_pub_key =
|
||||
new_tx.metadata.outputs[traversal.output_index].get_script_pubkey_hex();
|
||||
match Script::from_hex(&script_pub_key) {
|
||||
Ok(script) => match Address::from_script(&script, network) {
|
||||
Ok(a) => Some(a.to_string()),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
|
||||
match storage {
|
||||
Storage::Sqlite(rw_hord_db_conn) => {
|
||||
|
||||
@@ -445,7 +445,9 @@ pub fn standardize_bitcoin_block(
|
||||
index: block_height - 1,
|
||||
},
|
||||
timestamp: block.time as u32,
|
||||
metadata: BitcoinBlockMetadata {},
|
||||
metadata: BitcoinBlockMetadata {
|
||||
network: network.clone()
|
||||
},
|
||||
transactions,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -123,7 +123,9 @@ pub struct BitcoinBlockData {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||
pub struct BitcoinBlockMetadata {}
|
||||
pub struct BitcoinBlockMetadata {
|
||||
pub network: BitcoinNetwork,
|
||||
}
|
||||
|
||||
/// The timestamp of the block in milliseconds since the Unix Epoch. The
|
||||
/// timestamp is stored in milliseconds because some blockchains produce blocks
|
||||
|
||||
Reference in New Issue
Block a user