From 75aedc972d4e9b390a93c5bc78b5d1b6ea8b7cca Mon Sep 17 00:00:00 2001 From: Vincenzo Palazzo Date: Fri, 8 Sep 2023 10:26:07 +0200 Subject: [PATCH] fix: make fetch block more solid Sometimes we make a request for a block that do not exist but we can know before times if this block exist or not. So we try to make a check with the current blockchain height. Link: https://github.com/coffee-tools/folgore/issues/47 Signed-off-by: Vincenzo Palazzo --- folgore-bitcoind/src/lib.rs | 20 +++++++++++++++++-- folgore-esplora/src/lib.rs | 39 ++++++++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/folgore-bitcoind/src/lib.rs b/folgore-bitcoind/src/lib.rs index 54afc31..7bf8267 100644 --- a/folgore-bitcoind/src/lib.rs +++ b/folgore-bitcoind/src/lib.rs @@ -11,13 +11,15 @@ use std::str::FromStr; use bitcoincore_rpc::bitcoin::consensus::{deserialize, serialize}; use bitcoincore_rpc::bitcoin::Transaction; use bitcoincore_rpc::bitcoin::Txid; +use bitcoincore_rpc::bitcoincore_rpc_json::EstimateMode; +use bitcoincore_rpc::jsonrpc::serde_json::json; use bitcoincore_rpc::RpcApi; use bitcoincore_rpc::{Auth, Client}; -use bitcoincore_rpc::bitcoincore_rpc_json::EstimateMode; use folgore_common::client::fee_estimator::FeeEstimator; use folgore_common::client::fee_estimator::{FeePriority, FEE_RATES}; use folgore_common::client::FolgoreBackend; +use folgore_common::cln_plugin::types::LogLevel; use folgore_common::hex; use folgore_common::prelude::cln_plugin::error; use folgore_common::prelude::cln_plugin::errors; @@ -63,9 +65,23 @@ impl FolgoreBackend for BitcoinCore { fn sync_block_by_height( &self, - _: &mut plugin::Plugin, + plugin: &mut plugin::Plugin, height: u64, ) -> Result { + let current_height = self + .client + .get_block_count() + .map_err(|err| error!("{err}"))?; + if current_height < height { + plugin.log( + LogLevel::Debug, + &format!("requesting block out of best chain. Block height wanted: {height}"), + ); + return Ok(json!({ + "blockhash": null, + "block": null, + })); + } let block_header = self .client .get_block_hash(height) diff --git a/folgore-esplora/src/lib.rs b/folgore-esplora/src/lib.rs index 7ae05fd..4a931a2 100644 --- a/folgore-esplora/src/lib.rs +++ b/folgore-esplora/src/lib.rs @@ -10,10 +10,11 @@ use clightningrpc_common::json_utils; use clightningrpc_plugin::error; use clightningrpc_plugin::errors::PluginError; use esplora_client::api::{FromHex, Transaction, TxOut, Txid}; -use esplora_client::{deserialize, serialize}; +use esplora_client::{deserialize, serialize, BlockSummary}; use esplora_client::{BlockingClient, Builder}; use folgore_common::client::FolgoreBackend; +use folgore_common::cln_plugin::types::LogLevel; use folgore_common::stragegy::RecoveryStrategy; use folgore_common::utils::ByteBuf; use folgore_common::utils::{bitcoin_hashes, hex}; @@ -113,9 +114,14 @@ impl FolgoreBackend for Esplora { fn sync_block_by_height( &self, - _: &mut clightningrpc_plugin::plugin::Plugin, + plugin: &mut clightningrpc_plugin::plugin::Plugin, height: u64, ) -> Result { + let fail_resp = json!({ + "blockhash": null, + "block": null, + }); + let chain_tip = self.client.get_height().map_err(|err| error!("{err}"))?; if height > chain_tip.into() { let resp = json!({ @@ -124,10 +130,25 @@ impl FolgoreBackend for Esplora { }); return Ok(resp); } - let block = self - .client - .get_blocks(Some(height.try_into().map_err(|err| error!("{err}"))?)) - .map_err(from)?; + // Check if the blocks that core lightning wants exist. + let current_height = self + .recovery_strategy + .apply(|| self.client.get_height().map_err(|err| error!("{err}"))) + .map_err(|err| error!("{err}"))?; + if current_height < height as u32 { + plugin.log( + LogLevel::Debug, + &format!("requesting block out of best chain. Block height wanted: {height}"), + ); + return Ok(fail_resp); + } + + // Now that we are sure that the block exist we can requesting it + let block: Vec = self.recovery_strategy.apply(|| { + self.client + .get_blocks(Some(height.try_into().expect("height convertion fails"))) + .map_err(|err| error!("{err}")) + })?; let block_hash = block.first().ok_or(error!("block not found"))?; let block_hash = block_hash.id; @@ -144,11 +165,7 @@ impl FolgoreBackend for Esplora { return Ok(response); } debug!("block not found!"); - let resp = json!({ - "blockhash": null, - "block": null, - }); - Ok(resp) + Ok(fail_resp) } fn sync_chain_info(