Skip to content

Commit 8006000

Browse files
author
Ludo Galabru
committed
fix: additional fixes (network, address, offsets)
1 parent f5cb516 commit 8006000

File tree

4 files changed

+114
-100
lines changed

4 files changed

+114
-100
lines changed

components/chainhook-sdk/src/hord/db/mod.rs

+81-75
Original file line numberDiff line numberDiff line change
@@ -455,15 +455,18 @@ pub fn find_inscription_with_id(
455455
if block_hash.eq(&inscription_block_hash) {
456456
let inscription_number: i64 = row.get(0).unwrap();
457457
let ordinal_number: u64 = row.get(1).unwrap();
458-
let inscription_offset: u64 = row.get(3).unwrap();
458+
let inscription_offset_intra_output: u64 = row.get(3).unwrap();
459459
let outpoint_to_watch: String = row.get(4).unwrap();
460+
let (transaction_identifier, output_index) =
461+
parse_outpoint_to_watch(&outpoint_to_watch);
460462
let (_, input_index) = parse_inscription_id(inscription_id);
461463
let traversal = TraversalResult {
462464
inscription_number,
463465
ordinal_number,
464466
input_index,
465-
inscription_offset,
466-
outpoint_to_watch,
467+
inscription_offset_intra_output,
468+
transaction_identifier,
469+
output_index,
467470
transfers: 0,
468471
};
469472
return Some(traversal);
@@ -490,15 +493,18 @@ pub fn find_all_inscriptions_in_block(
490493
let inscription_id: String = row.get(3).unwrap();
491494
parse_inscription_id(&inscription_id)
492495
};
493-
let inscription_offset: u64 = row.get(4).unwrap();
496+
let inscription_offset_intra_output: u64 = row.get(4).unwrap();
494497
let outpoint_to_watch: String = row.get(5).unwrap();
498+
let (transaction_identifier, output_index) = parse_outpoint_to_watch(&outpoint_to_watch);
499+
495500
let traversal = TraversalResult {
496501
inscription_number,
497502
ordinal_number,
498503
input_index,
499504
transfers: 0,
500-
inscription_offset,
501-
outpoint_to_watch,
505+
inscription_offset_intra_output,
506+
transaction_identifier,
507+
output_index,
502508
};
503509
results
504510
.entry(block_height)
@@ -849,9 +855,10 @@ pub async fn fetch_and_cache_blocks_in_hord_db(
849855
#[derive(Clone, Debug)]
850856
pub struct TraversalResult {
851857
pub inscription_number: i64,
852-
pub inscription_offset: u64,
858+
pub inscription_offset_intra_output: u64,
853859
pub input_index: usize,
854-
pub outpoint_to_watch: String,
860+
pub output_index: usize,
861+
pub transaction_identifier: TransactionIdentifier,
855862
pub ordinal_number: u64,
856863
pub transfers: u32,
857864
}
@@ -939,14 +946,45 @@ pub fn retrieve_satoshi_point_using_lazy_storage(
939946
block_identifier.index
940947
)
941948
});
942-
let mut inscription_localized = false;
943-
let mut inscription_offset = 0;
949+
let mut inscription_offset_intra_output = 0;
944950
let mut inscription_output_index: usize = 0;
945951
let mut ordinal_offset = 0;
946952
let mut ordinal_block_number = block_identifier.index as u32;
947953
let txid = transaction_identifier.get_8_hash_bytes();
948-
let mut tx_cursor = (txid, input_index);
954+
955+
let (sats_ranges, inscription_offset_cross_outputs) =
956+
match traversals_cache.get(&(block_identifier.index as u32, txid.clone())) {
957+
Some(entry) => {
958+
let tx = entry.value();
959+
(
960+
tx.get_sat_ranges(),
961+
tx.get_cumulated_sats_in_until_input_index(input_index),
962+
)
963+
}
964+
None => match find_lazy_block_at_block_height(ordinal_block_number, 10, &blocks_db) {
965+
None => {
966+
return Err(format!("block #{ordinal_block_number} not in database"));
967+
}
968+
Some(block) => match block.find_and_serialize_transaction_with_txid(&txid) {
969+
Some(tx) => (
970+
tx.get_sat_ranges(),
971+
tx.get_cumulated_sats_in_until_input_index(input_index),
972+
),
973+
None => return Err(format!("block #{ordinal_block_number} not in database")),
974+
},
975+
},
976+
};
977+
978+
for (i, (min, max)) in sats_ranges.into_iter().enumerate() {
979+
if inscription_offset_cross_outputs >= min && inscription_offset_cross_outputs < max {
980+
inscription_output_index = i;
981+
inscription_offset_intra_output = inscription_offset_cross_outputs - min;
982+
}
983+
}
984+
985+
let mut tx_cursor: ([u8; 8], usize) = (txid, input_index);
949986
let mut hops: u32 = 0;
987+
950988
loop {
951989
hops += 1;
952990
if hops as u64 > block_identifier.index {
@@ -959,30 +997,6 @@ pub fn retrieve_satoshi_point_using_lazy_storage(
959997
if let Some(cached_tx) = traversals_cache.get(&(ordinal_block_number, tx_cursor.0)) {
960998
let tx = cached_tx.value();
961999

962-
if !inscription_localized {
963-
inscription_localized = true;
964-
let mut sats_ranges = vec![];
965-
let mut bound = 0;
966-
for output_value in tx.outputs.iter() {
967-
sats_ranges.push((bound, bound + output_value));
968-
bound += output_value;
969-
}
970-
let mut input_offset = 0;
971-
for (i, input) in tx.inputs.iter().enumerate() {
972-
if i == input_index {
973-
break;
974-
}
975-
input_offset += input.txin_value;
976-
}
977-
978-
for (i, (min, max)) in sats_ranges.into_iter().enumerate() {
979-
if input_offset >= min && input_offset < max {
980-
inscription_output_index = i;
981-
inscription_offset = input_offset - min;
982-
}
983-
}
984-
}
985-
9861000
let mut next_found_in_cache = false;
9871001
let mut sats_out = 0;
9881002
for (index, output_value) in tx.outputs.iter().enumerate() {
@@ -1022,12 +1036,10 @@ pub fn retrieve_satoshi_point_using_lazy_storage(
10221036
inscription_number: 0,
10231037
ordinal_number: 0,
10241038
transfers: 0,
1025-
inscription_offset,
1039+
inscription_offset_intra_output,
10261040
input_index,
1027-
outpoint_to_watch: format_outpoint_to_watch(
1028-
&transaction_identifier,
1029-
inscription_output_index,
1030-
),
1041+
transaction_identifier: transaction_identifier.clone(),
1042+
output_index: inscription_output_index,
10311043
});
10321044
}
10331045
}
@@ -1095,30 +1107,6 @@ pub fn retrieve_satoshi_point_using_lazy_storage(
10951107
None => unreachable!(),
10961108
};
10971109

1098-
if !inscription_localized {
1099-
inscription_localized = true;
1100-
let mut sats_ranges = vec![];
1101-
let mut bound = 0;
1102-
for output_value in lazy_tx.outputs.iter() {
1103-
sats_ranges.push((bound, bound + output_value));
1104-
bound += output_value;
1105-
}
1106-
let mut input_offset = 0;
1107-
for (i, input) in lazy_tx.inputs.iter().enumerate() {
1108-
if i == input_index {
1109-
break;
1110-
}
1111-
input_offset += input.txin_value;
1112-
}
1113-
1114-
for (i, (min, max)) in sats_ranges.into_iter().enumerate() {
1115-
if input_offset >= min && input_offset < max {
1116-
inscription_output_index = i;
1117-
inscription_offset = input_offset - min;
1118-
}
1119-
}
1120-
}
1121-
11221110
let mut sats_out = 0;
11231111
for (index, output_value) in lazy_tx.outputs.iter().enumerate() {
11241112
if index == tx_cursor.1 {
@@ -1153,30 +1141,27 @@ pub fn retrieve_satoshi_point_using_lazy_storage(
11531141
inscription_number: 0,
11541142
ordinal_number: 0,
11551143
transfers: 0,
1156-
inscription_offset,
1144+
inscription_offset_intra_output,
11571145
input_index,
1158-
outpoint_to_watch: format_outpoint_to_watch(
1159-
&transaction_identifier,
1160-
inscription_output_index,
1161-
),
1146+
transaction_identifier: transaction_identifier.clone(),
1147+
output_index: inscription_output_index,
11621148
});
11631149
}
11641150
}
11651151
}
11661152

11671153
let height = Height(ordinal_block_number.into());
1168-
let ordinal_number = height.starting_sat().0 + ordinal_offset + inscription_offset;
1154+
let ordinal_number =
1155+
height.starting_sat().0 + ordinal_offset + inscription_offset_cross_outputs;
11691156

11701157
Ok(TraversalResult {
11711158
inscription_number,
11721159
ordinal_number,
11731160
transfers: hops,
1174-
inscription_offset,
1161+
inscription_offset_intra_output,
11751162
input_index,
1176-
outpoint_to_watch: format_outpoint_to_watch(
1177-
&transaction_identifier,
1178-
inscription_output_index,
1179-
),
1163+
transaction_identifier: transaction_identifier.clone(),
1164+
output_index: inscription_output_index,
11801165
})
11811166
}
11821167

@@ -1197,6 +1182,27 @@ impl LazyBlockTransaction {
11971182
pub fn get_average_bytes_size() -> usize {
11981183
TXID_LEN + 3 * LazyBlockTransactionInput::get_average_bytes_size() + 3 * SATS_LEN
11991184
}
1185+
1186+
pub fn get_sat_ranges(&self) -> Vec<(u64, u64)> {
1187+
let mut sats_ranges = vec![];
1188+
let mut bound = 0u64;
1189+
for output_value in self.outputs.iter() {
1190+
sats_ranges.push((bound, bound + output_value));
1191+
bound += output_value;
1192+
}
1193+
sats_ranges
1194+
}
1195+
1196+
pub fn get_cumulated_sats_in_until_input_index(&self, input_index: usize) -> u64 {
1197+
let mut cumulated_sats_in = 0;
1198+
for (i, input) in self.inputs.iter().enumerate() {
1199+
if i == input_index {
1200+
break;
1201+
}
1202+
cumulated_sats_in += input.txin_value;
1203+
}
1204+
cumulated_sats_in
1205+
}
12001206
}
12011207

12021208
#[derive(Debug, Clone)]

components/chainhook-sdk/src/hord/mod.rs

+27-23
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use bitcoincore_rpc::bitcoin::hashes::hex::FromHex;
66
use bitcoincore_rpc::bitcoin::{Address, Network, Script};
77
use bitcoincore_rpc_json::bitcoin::Witness;
88
use chainhook_types::{
9-
BitcoinBlockData, OrdinalInscriptionCurseType, OrdinalInscriptionRevealData,
9+
BitcoinBlockData, BitcoinNetwork, OrdinalInscriptionCurseType, OrdinalInscriptionRevealData,
1010
OrdinalInscriptionTransferData, OrdinalOperation, TransactionIdentifier,
1111
};
1212
use dashmap::DashMap;
@@ -96,21 +96,6 @@ pub fn parse_ordinal_operations(
9696
index: input_index as u32,
9797
};
9898

99-
let inscription_output_value = tx
100-
.vout
101-
.get(0)
102-
.and_then(|o| Some(o.value.to_sat()))
103-
.unwrap_or(0);
104-
105-
let inscriber_address = if let Ok(authors) = Address::from_script(
106-
&tx.vout[0].script_pub_key.script().unwrap(),
107-
bitcoincore_rpc::bitcoin::Network::Bitcoin,
108-
) {
109-
Some(authors.to_string())
110-
} else {
111-
None
112-
};
113-
11499
if input_index > 0 {
115100
inscription.curse = Some(OrdinalInscriptionCurseType::Batch);
116101
}
@@ -123,16 +108,16 @@ pub fn parse_ordinal_operations(
123108
content_bytes: format!("0x{}", hex::encode(&inscription_content_bytes)),
124109
content_length: inscription_content_bytes.len(),
125110
inscription_id: inscription_id.to_string(),
126-
inscriber_address,
127-
inscription_output_value,
128-
inscription_fee: 0,
129111
inscription_input_index: input_index,
112+
inscription_output_value: 0,
113+
inscription_fee: 0,
130114
inscription_number: 0,
115+
inscriber_address: None,
131116
ordinal_number: 0,
132117
ordinal_block_height: 0,
133118
ordinal_offset: 0,
134119
transfers_pre_inscription: 0,
135-
satpoint_post_inscription: format!("{}:0:0", tx.txid.clone()),
120+
satpoint_post_inscription: format!(""),
136121
curse_type: inscription.curse.take(),
137122
};
138123

@@ -435,7 +420,11 @@ pub fn update_storage_and_augment_bitcoin_block_with_inscription_reveal_data(
435420
ctx: &Context,
436421
) -> Result<bool, String> {
437422
let mut storage_updated = false;
438-
423+
let network = match block.metadata.network {
424+
BitcoinNetwork::Mainnet => Network::Bitcoin,
425+
BitcoinNetwork::Regtest => Network::Regtest,
426+
BitcoinNetwork::Testnet => Network::Testnet,
427+
};
439428
let mut latest_inscription_number = match find_latest_inscription_number_at_block_height(
440429
&block.block_identifier.index,
441430
&inscriptions_db_conn,
@@ -499,9 +488,24 @@ pub fn update_storage_and_augment_bitcoin_block_with_inscription_reveal_data(
499488
inscription.transfers_pre_inscription = traversal.transfers;
500489
inscription.inscription_fee = new_tx.metadata.fee;
501490
inscription.satpoint_post_inscription = format!(
502-
"{}:{}",
503-
traversal.outpoint_to_watch, traversal.inscription_offset
491+
"{}:{}:{}",
492+
traversal.transaction_identifier.hash,
493+
traversal.output_index,
494+
traversal.inscription_offset_intra_output
504495
);
496+
inscription.inscription_output_value =
497+
new_tx.metadata.outputs[traversal.output_index].value;
498+
inscription.inscriber_address = {
499+
let script_pub_key =
500+
new_tx.metadata.outputs[traversal.output_index].get_script_pubkey_hex();
501+
match Script::from_hex(&script_pub_key) {
502+
Ok(script) => match Address::from_script(&script, network) {
503+
Ok(a) => Some(a.to_string()),
504+
_ => None,
505+
},
506+
_ => None,
507+
}
508+
};
505509

506510
match storage {
507511
Storage::Sqlite(rw_hord_db_conn) => {

components/chainhook-sdk/src/indexer/bitcoin/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,9 @@ pub fn standardize_bitcoin_block(
445445
index: block_height - 1,
446446
},
447447
timestamp: block.time as u32,
448-
metadata: BitcoinBlockMetadata {},
448+
metadata: BitcoinBlockMetadata {
449+
network: network.clone()
450+
},
449451
transactions,
450452
})
451453
}

components/chainhook-types-rs/src/rosetta.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ pub struct BitcoinBlockData {
123123
}
124124

125125
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
126-
pub struct BitcoinBlockMetadata {}
126+
pub struct BitcoinBlockMetadata {
127+
pub network: BitcoinNetwork,
128+
}
127129

128130
/// The timestamp of the block in milliseconds since the Unix Epoch. The
129131
/// timestamp is stored in milliseconds because some blockchains produce blocks

0 commit comments

Comments
 (0)