From cdfbf487facdf2f04cbed608bec4c2cfaa7a2f27 Mon Sep 17 00:00:00 2001 From: Ludo Galabru Date: Wed, 12 Apr 2023 17:40:35 -0400 Subject: [PATCH] fix: off by one inscriptions number --- components/chainhook-cli/src/scan/bitcoin.rs | 40 +++++++++++++------ .../src/hord/db/mod.rs | 6 +-- .../chainhook-event-observer/src/hord/mod.rs | 3 +- .../src/observer/mod.rs | 4 +- .../chainhook-event-observer/src/utils/mod.rs | 17 +++++--- 5 files changed, 46 insertions(+), 24 deletions(-) diff --git a/components/chainhook-cli/src/scan/bitcoin.rs b/components/chainhook-cli/src/scan/bitcoin.rs index 6939c49..ce9fb89 100644 --- a/components/chainhook-cli/src/scan/bitcoin.rs +++ b/components/chainhook-cli/src/scan/bitcoin.rs @@ -6,8 +6,7 @@ use chainhook_event_observer::chainhooks::bitcoin::{ BitcoinChainhookOccurrence, BitcoinTriggerChainhook, }; use chainhook_event_observer::chainhooks::types::{ - BitcoinChainhookSpecification, BitcoinPredicateType, - Protocols, + BitcoinChainhookSpecification, BitcoinPredicateType, Protocols, }; use chainhook_event_observer::hord::db::{ fetch_and_cache_blocks_in_hord_db, find_all_inscriptions, find_block_at_block_height, @@ -27,7 +26,7 @@ use chainhook_event_observer::utils::{file_append, send_request, Context}; use chainhook_types::{BitcoinChainEvent, BitcoinChainUpdatedWithBlocksData}; use std::collections::{BTreeMap, HashMap}; -pub async fn scan_bitcoin_chain_with_predicate_via_http( +pub async fn scan_bitcoin_chainstate_via_http_using_predicate( predicate_spec: BitcoinChainhookSpecification, config: &Config, ctx: &Context, @@ -137,6 +136,7 @@ pub async fn scan_bitcoin_chain_with_predicate_via_http( let mut blocks_scanned = 0; let mut actions_triggered = 0; + let mut err_count = 0; let event_observer_config = config.get_event_observer_config(); let bitcoin_config = event_observer_config.get_bitcoin_config(); @@ -199,8 +199,14 @@ pub async fn scan_bitcoin_chain_with_predicate_via_http( ctx, ); - actions_triggered += - execute_predicates_action(hits, &event_observer_config, &ctx).await; + match execute_predicates_action(hits, &event_observer_config, &ctx).await { + Ok(actions) => actions_triggered += actions, + Err(_) => err_count += 1, + } + + if err_count >= 3 { + return Err(format!("Scan aborted (consecutive action errors >= 3)")); + } } } else { let use_scan_to_seed_hord_db = true; @@ -242,8 +248,14 @@ pub async fn scan_bitcoin_chain_with_predicate_via_http( ctx, ); - actions_triggered += - execute_predicates_action(hits, &event_observer_config, &ctx).await; + match execute_predicates_action(hits, &event_observer_config, &ctx).await { + Ok(actions) => actions_triggered += actions, + Err(_) => err_count += 1, + } + + if err_count >= 3 { + return Err(format!("Scan aborted (consecutive action errors >= 3)")); + } } } info!( @@ -258,7 +270,7 @@ pub async fn execute_predicates_action<'a>( hits: Vec>, config: &EventObserverConfig, ctx: &Context, -) -> u32 { +) -> Result { let mut actions_triggered = 0; let proofs = gather_proofs(&hits, &config, &ctx); for hit in hits.into_iter() { @@ -269,13 +281,17 @@ pub async fn execute_predicates_action<'a>( Ok(action) => { actions_triggered += 1; match action { - BitcoinChainhookOccurrence::Http(request) => send_request(request, &ctx).await, - BitcoinChainhookOccurrence::File(path, bytes) => file_append(path, bytes, &ctx), + BitcoinChainhookOccurrence::Http(request) => { + send_request(request, &ctx).await? + } + BitcoinChainhookOccurrence::File(path, bytes) => { + file_append(path, bytes, &ctx)? + } BitcoinChainhookOccurrence::Data(_payload) => unreachable!(), - } + }; } } } - actions_triggered + Ok(actions_triggered) } diff --git a/components/chainhook-event-observer/src/hord/db/mod.rs b/components/chainhook-event-observer/src/hord/db/mod.rs index 14dbd7d..28a3d17 100644 --- a/components/chainhook-event-observer/src/hord/db/mod.rs +++ b/components/chainhook-event-observer/src/hord/db/mod.rs @@ -517,7 +517,7 @@ pub fn find_latest_inscription_block_height( pub fn find_latest_inscription_number( inscriptions_db_conn: &Connection, _ctx: &Context, -) -> Result { +) -> Result, String> { let args: &[&dyn ToSql] = &[]; let mut stmt = inscriptions_db_conn .prepare( @@ -527,9 +527,9 @@ pub fn find_latest_inscription_number( let mut rows = stmt.query(args).unwrap(); while let Ok(Some(row)) = rows.next() { let inscription_number: u64 = row.get(0).unwrap(); - return Ok(inscription_number); + return Ok(Some(inscription_number)); } - Ok(0) + Ok(None) } pub fn find_inscription_with_ordinal_number( diff --git a/components/chainhook-event-observer/src/hord/mod.rs b/components/chainhook-event-observer/src/hord/mod.rs index 24495dd..4e87967 100644 --- a/components/chainhook-event-observer/src/hord/mod.rs +++ b/components/chainhook-event-observer/src/hord/mod.rs @@ -229,7 +229,8 @@ pub fn update_storage_and_augment_bitcoin_block_with_inscription_reveal_data( } else { inscription.inscription_number = match find_latest_inscription_number(&inscription_db_conn, &ctx) { - Ok(inscription_number) => inscription_number + 1, + Ok(None) => 0, + Ok(Some(inscription_number)) => inscription_number + 1, Err(e) => { ctx.try_log(|logger| { slog::error!( diff --git a/components/chainhook-event-observer/src/observer/mod.rs b/components/chainhook-event-observer/src/observer/mod.rs index b561292..6f27d02 100644 --- a/components/chainhook-event-observer/src/observer/mod.rs +++ b/components/chainhook-event-observer/src/observer/mod.rs @@ -1028,7 +1028,7 @@ pub async fn start_observer_commands_handler( request ) }); - send_request(request, &ctx).await; + let _ = send_request(request, &ctx).await; } if let Some(ref tx) = observer_events_tx { @@ -1160,7 +1160,7 @@ pub async fn start_observer_commands_handler( request ) }); - send_request(request, &ctx).await; + let _ = send_request(request, &ctx).await; } if let Some(ref tx) = observer_events_tx { diff --git a/components/chainhook-event-observer/src/utils/mod.rs b/components/chainhook-event-observer/src/utils/mod.rs index 9ea5e04..8ec7bd7 100644 --- a/components/chainhook-event-observer/src/utils/mod.rs +++ b/components/chainhook-event-observer/src/utils/mod.rs @@ -139,11 +139,12 @@ impl AbstractBlock for BitcoinBlockData { } } -pub async fn send_request(request: RequestBuilder, ctx: &Context) { +pub async fn send_request(request: RequestBuilder, ctx: &Context) -> Result<(), ()> { match request.send().await { Ok(res) => { if res.status().is_success() { ctx.try_log(|logger| slog::info!(logger, "Trigger {} successful", res.url())); + return Ok(()); } else { ctx.try_log(|logger| { slog::warn!( @@ -161,15 +162,16 @@ pub async fn send_request(request: RequestBuilder, ctx: &Context) { }); } } + Err(()) } -pub fn file_append(path: String, bytes: Vec, ctx: &Context) { +pub fn file_append(path: String, bytes: Vec, ctx: &Context) -> Result<(), ()> { let mut file_path = match std::env::current_dir() { Err(e) => { ctx.try_log(|logger| { slog::warn!(logger, "unable to retrieve current_dir {}", e.to_string()) }); - return; + return Err(()); } Ok(p) => p, }; @@ -188,7 +190,7 @@ pub fn file_append(path: String, bytes: Vec, ctx: &Context) { e.to_string() ) }); - return; + return Err(()); } } } @@ -201,7 +203,7 @@ pub fn file_append(path: String, bytes: Vec, ctx: &Context) { { Err(e) => { ctx.try_log(|logger| slog::warn!(logger, "unable to open file {}", e.to_string())); - return; + return Err(()); } Ok(p) => p, }; @@ -216,12 +218,15 @@ pub fn file_append(path: String, bytes: Vec, ctx: &Context) { e.to_string() ) }); - return; + return Err(()); } }; if let Err(e) = writeln!(file, "{}", utf8) { ctx.try_log(|logger| slog::warn!(logger, "unable to open file {}", e.to_string())); eprintln!("Couldn't write to file: {}", e); + return Err(()); } + + Ok(()) }