Skip to content

Commit 3e15da5

Browse files
author
Ludo Galabru
committed
fix: reopen connect on failures
1 parent ea1ff9a commit 3e15da5

File tree

5 files changed

+105
-55
lines changed

5 files changed

+105
-55
lines changed

components/chainhook-cli/src/cli/mod.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -664,11 +664,12 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
664664
let config =
665665
Config::default(cmd.devnet, cmd.testnet, cmd.mainnet, &cmd.config_path)?;
666666

667-
let hord_db_conn =
668-
open_readonly_hord_db_conn_rocks_db(&config.expected_cache_path(), &ctx)
669-
.unwrap();
670-
671-
let tip_height = find_last_block_inserted(&hord_db_conn) as u64;
667+
let tip_height = {
668+
let hord_db_conn =
669+
open_readonly_hord_db_conn_rocks_db(&config.expected_cache_path(), &ctx)
670+
.unwrap();
671+
find_last_block_inserted(&hord_db_conn) as u64
672+
};
672673
if cmd.block_height > tip_height {
673674
perform_hord_db_update(
674675
tip_height,
@@ -691,7 +692,7 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
691692
let transaction_identifier = TransactionIdentifier { hash: txid.clone() };
692693
let traversals_cache = new_traversals_lazy_cache(1024);
693694
let traversal = retrieve_satoshi_point_using_lazy_storage(
694-
&hord_db_conn,
695+
&config.expected_cache_path(),
695696
&block_identifier,
696697
&transaction_identifier,
697698
0,
@@ -859,7 +860,9 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
859860

860861
let mut missing_blocks = vec![];
861862
for i in 1..=790000 {
862-
if find_lazy_block_at_block_height(i, 3, &blocks_db_rw, &ctx).is_none() {
863+
if find_lazy_block_at_block_height(i, 3, false, &blocks_db_rw, &ctx)
864+
.is_none()
865+
{
863866
println!("Missing block {i}");
864867
missing_blocks.push(i);
865868
}

components/chainhook-cli/src/scan/bitcoin.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ pub async fn scan_bitcoin_chainstate_via_rpc_using_predicate(
8080
let blocks_db_rw =
8181
open_readwrite_hord_db_conn_rocks_db(&config.expected_cache_path(), ctx)?;
8282

83-
if find_lazy_block_at_block_height(end_block as u32, 3, &blocks_db_rw, &ctx).is_none() {
83+
if find_lazy_block_at_block_height(end_block as u32, 3, false, &blocks_db_rw, &ctx)
84+
.is_none()
85+
{
8486
// Count how many entries in the table
8587
// Compute the right interval
8688
// Start the build local storage routine

components/chainhook-cli/src/service/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,10 @@ impl Service {
107107
};
108108

109109
// Download and ingest a Stacks dump
110-
let _ = consolidate_local_stacks_chainstate_using_csv(&mut self.config, &self.ctx).await;
110+
if self.config.rely_on_remote_stacks_tsv() {
111+
let _ =
112+
consolidate_local_stacks_chainstate_using_csv(&mut self.config, &self.ctx).await;
113+
}
111114

112115
// Download and ingest a Ordinal dump, if hord is enabled
113116
if !hord_disabled {

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

+73-22
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,21 @@ pub fn open_readonly_hord_db_conn_rocks_db(
206206
Ok(db)
207207
}
208208

209+
pub fn open_readonly_hord_db_conn_rocks_db_loop(base_dir: &PathBuf, ctx: &Context) -> DB {
210+
let blocks_db = loop {
211+
match open_readonly_hord_db_conn_rocks_db(&base_dir, &ctx) {
212+
Ok(db) => break db,
213+
Err(e) => {
214+
ctx.try_log(|logger| {
215+
slog::warn!(logger, "Unable to open db: {e}",);
216+
});
217+
continue;
218+
}
219+
}
220+
};
221+
blocks_db
222+
}
223+
209224
pub fn open_readwrite_hord_dbs(
210225
base_dir: &PathBuf,
211226
ctx: &Context,
@@ -251,6 +266,7 @@ pub fn find_last_block_inserted(blocks_db: &DB) -> u32 {
251266
pub fn find_lazy_block_at_block_height(
252267
block_height: u32,
253268
retry: u8,
269+
try_iterator: bool,
254270
blocks_db: &DB,
255271
ctx: &Context,
256272
) -> Option<LazyBlock> {
@@ -265,7 +281,7 @@ pub fn find_lazy_block_at_block_height(
265281
match blocks_db.get(block_height.to_be_bytes()) {
266282
Ok(Some(res)) => return Some(LazyBlock::new(res)),
267283
_ => {
268-
if attempt == 1 {
284+
if attempt == 1 && try_iterator {
269285
ctx.try_log(|logger| {
270286
slog::warn!(
271287
logger,
@@ -971,7 +987,7 @@ pub fn parse_outpoint_to_watch(outpoint_to_watch: &str) -> (TransactionIdentifie
971987
}
972988

973989
pub fn retrieve_satoshi_point_using_lazy_storage(
974-
blocks_db: &DB,
990+
blocks_db_dir: &PathBuf,
975991
block_identifier: &BlockIdentifier,
976992
transaction_identifier: &TransactionIdentifier,
977993
input_index: usize,
@@ -987,6 +1003,8 @@ pub fn retrieve_satoshi_point_using_lazy_storage(
9871003
let mut ordinal_block_number = block_identifier.index as u32;
9881004
let txid = transaction_identifier.get_8_hash_bytes();
9891005

1006+
let mut blocks_db = open_readonly_hord_db_conn_rocks_db_loop(&blocks_db_dir, &ctx);
1007+
9901008
let (sats_ranges, inscription_offset_cross_outputs) = match traversals_cache
9911009
.get(&(block_identifier.index as u32, txid.clone()))
9921010
{
@@ -997,21 +1015,38 @@ pub fn retrieve_satoshi_point_using_lazy_storage(
9971015
tx.get_cumulated_sats_in_until_input_index(input_index),
9981016
)
9991017
}
1000-
None => match find_lazy_block_at_block_height(ordinal_block_number, 3, &blocks_db, &ctx) {
1001-
None => {
1002-
return Err(format!("block #{ordinal_block_number} not in database"));
1003-
}
1004-
Some(block) => match block.find_and_serialize_transaction_with_txid(&txid) {
1005-
Some(tx) => {
1006-
let sats_ranges = tx.get_sat_ranges();
1007-
let inscription_offset_cross_outputs =
1008-
tx.get_cumulated_sats_in_until_input_index(input_index);
1009-
traversals_cache.insert((ordinal_block_number, txid.clone()), tx);
1010-
(sats_ranges, inscription_offset_cross_outputs)
1018+
None => {
1019+
let mut attempt = 0;
1020+
loop {
1021+
match find_lazy_block_at_block_height(
1022+
ordinal_block_number,
1023+
3,
1024+
false,
1025+
&blocks_db,
1026+
&ctx,
1027+
) {
1028+
None => {
1029+
if attempt < 3 {
1030+
attempt += 1;
1031+
blocks_db =
1032+
open_readonly_hord_db_conn_rocks_db_loop(&blocks_db_dir, &ctx);
1033+
} else {
1034+
return Err(format!("block #{ordinal_block_number} not in database"));
1035+
}
1036+
}
1037+
Some(block) => match block.find_and_serialize_transaction_with_txid(&txid) {
1038+
Some(tx) => {
1039+
let sats_ranges = tx.get_sat_ranges();
1040+
let inscription_offset_cross_outputs =
1041+
tx.get_cumulated_sats_in_until_input_index(input_index);
1042+
traversals_cache.insert((ordinal_block_number, txid.clone()), tx);
1043+
break (sats_ranges, inscription_offset_cross_outputs);
1044+
}
1045+
None => return Err(format!("txid not in block #{ordinal_block_number}")),
1046+
},
10111047
}
1012-
None => return Err(format!("txid not in block #{ordinal_block_number}")),
1013-
},
1014-
},
1048+
}
1049+
}
10151050
};
10161051

10171052
for (i, (min, max)) in sats_ranges.into_iter().enumerate() {
@@ -1095,13 +1130,29 @@ pub fn retrieve_satoshi_point_using_lazy_storage(
10951130
}
10961131
}
10971132

1098-
let lazy_block =
1099-
match find_lazy_block_at_block_height(ordinal_block_number, 3, &blocks_db, &ctx) {
1100-
Some(block) => block,
1101-
None => {
1102-
return Err(format!("block #{ordinal_block_number} not in database"));
1133+
let lazy_block = {
1134+
let mut attempt = 0;
1135+
loop {
1136+
match find_lazy_block_at_block_height(
1137+
ordinal_block_number,
1138+
3,
1139+
false,
1140+
&blocks_db,
1141+
&ctx,
1142+
) {
1143+
Some(block) => break block,
1144+
None => {
1145+
if attempt < 3 {
1146+
attempt += 1;
1147+
blocks_db =
1148+
open_readonly_hord_db_conn_rocks_db_loop(&blocks_db_dir, &ctx);
1149+
} else {
1150+
return Err(format!("block #{ordinal_block_number} not in database"));
1151+
}
1152+
}
11031153
}
1104-
};
1154+
}
1155+
};
11051156

11061157
let coinbase_txid = lazy_block.get_coinbase_txid();
11071158
let txid = tx_cursor.0;

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

+15-24
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ use crate::{
4141

4242
use self::db::{
4343
find_inscription_with_id, find_latest_cursed_inscription_number_at_block_height,
44-
find_latest_inscription_number_at_block_height, open_readonly_hord_db_conn_rocks_db,
45-
parse_satpoint_to_watch, remove_entry_from_blocks, remove_entry_from_inscriptions, LazyBlock,
46-
LazyBlockTransaction, TraversalResult, WatchedSatpoint,
44+
find_latest_inscription_number_at_block_height,
45+
parse_satpoint_to_watch, remove_entry_from_blocks,
46+
remove_entry_from_inscriptions, LazyBlock, LazyBlockTransaction, TraversalResult,
47+
WatchedSatpoint,
4748
};
4849
use self::inscription::InscriptionParser;
4950
use self::ord::inscription_id::InscriptionId;
@@ -276,27 +277,17 @@ pub fn retrieve_inscribed_satoshi_points_from_block(
276277
let block_identifier = block.block_identifier.clone();
277278
let moved_hord_db_path = hord_config.db_path.clone();
278279
let local_cache = traversals_cache.clone();
279-
traversal_data_pool.execute(move || loop {
280-
match open_readonly_hord_db_conn_rocks_db(&moved_hord_db_path, &moved_ctx) {
281-
Ok(blocks_db) => {
282-
let traversal = retrieve_satoshi_point_using_lazy_storage(
283-
&blocks_db,
284-
&block_identifier,
285-
&transaction_id,
286-
input_index,
287-
0,
288-
local_cache,
289-
&moved_ctx,
290-
);
291-
let _ = moved_traversal_tx.send(traversal);
292-
break;
293-
}
294-
Err(e) => {
295-
moved_ctx.try_log(|logger| {
296-
slog::warn!(logger, "Unable to open db: {e}",);
297-
});
298-
}
299-
}
280+
traversal_data_pool.execute(move || {
281+
let traversal = retrieve_satoshi_point_using_lazy_storage(
282+
&moved_hord_db_path,
283+
&block_identifier,
284+
&transaction_id,
285+
input_index,
286+
0,
287+
local_cache,
288+
&moved_ctx,
289+
);
290+
let _ = moved_traversal_tx.send(traversal);
300291
});
301292
}
302293

0 commit comments

Comments
 (0)