Skip to content

Commit

Permalink
Merge pull request #249 from tnull/2024-02-fix-esplora-fee-estimator
Browse files Browse the repository at this point in the history
Disallow empty fee estimates on Mainnet
  • Loading branch information
tnull authored Feb 12, 2024
2 parents ff38966 + 20742f4 commit 6dcee91
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 8 deletions.
14 changes: 10 additions & 4 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,8 +508,11 @@ fn build_with_store_internal<K: KVStore + Sync + Send + 'static>(
tx_sync.client().clone(),
Arc::clone(&logger),
));
let fee_estimator =
Arc::new(OnchainFeeEstimator::new(tx_sync.client().clone(), Arc::clone(&logger)));
let fee_estimator = Arc::new(OnchainFeeEstimator::new(
tx_sync.client().clone(),
Arc::clone(&config),
Arc::clone(&logger),
));
(blockchain, tx_sync, tx_broadcaster, fee_estimator)
}
None => {
Expand All @@ -523,8 +526,11 @@ fn build_with_store_internal<K: KVStore + Sync + Send + 'static>(
tx_sync.client().clone(),
Arc::clone(&logger),
));
let fee_estimator =
Arc::new(OnchainFeeEstimator::new(tx_sync.client().clone(), Arc::clone(&logger)));
let fee_estimator = Arc::new(OnchainFeeEstimator::new(
tx_sync.client().clone(),
Arc::clone(&config),
Arc::clone(&logger),
));
(blockchain, tx_sync, tx_broadcaster, fee_estimator)
}
};
Expand Down
20 changes: 16 additions & 4 deletions src/fee_estimator.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::logger::{log_error, log_trace, Logger};
use crate::Error;
use crate::{Config, Error};

use lightning::chain::chaininterface::{
ConfirmationTarget, FeeEstimator, FEERATE_FLOOR_SATS_PER_KW,
Expand All @@ -8,28 +8,30 @@ use lightning::chain::chaininterface::{
use bdk::FeeRate;
use esplora_client::AsyncClient as EsploraClient;

use bitcoin::Network;
use bitcoin::blockdata::weight::Weight;

use std::collections::HashMap;
use std::ops::Deref;
use std::sync::RwLock;
use std::sync::{Arc, RwLock};

pub(crate) struct OnchainFeeEstimator<L: Deref>
where
L::Target: Logger,
{
fee_rate_cache: RwLock<HashMap<ConfirmationTarget, FeeRate>>,
esplora_client: EsploraClient,
config: Arc<Config>,
logger: L,
}

impl<L: Deref> OnchainFeeEstimator<L>
where
L::Target: Logger,
{
pub(crate) fn new(esplora_client: EsploraClient, logger: L) -> Self {
pub(crate) fn new(esplora_client: EsploraClient, config: Arc<Config>, logger: L) -> Self {
let fee_rate_cache = RwLock::new(HashMap::new());
Self { fee_rate_cache, esplora_client, logger }
Self { fee_rate_cache, esplora_client, config, logger }
}

pub(crate) async fn update_fee_estimates(&self) -> Result<(), Error> {
Expand Down Expand Up @@ -61,6 +63,16 @@ where
Error::FeerateEstimationUpdateFailed
})?;

if estimates.is_empty() && self.config.network == Network::Bitcoin {
// Ensure we fail if we didn't receive any estimates.
log_error!(
self.logger,
"Failed to retrieve fee rate estimates for {:?}: empty fee estimates are dissallowed on Mainnet.",
target,
);
return Err(Error::FeerateEstimationUpdateFailed);
}

let converted_estimates = esplora_client::convert_fee_rate(num_blocks, estimates)
.map_err(|e| {
log_error!(
Expand Down

0 comments on commit 6dcee91

Please sign in to comment.