From: Matt Corallo Date: Sat, 31 Jul 2021 22:19:45 +0000 (+0000) Subject: Limit minimum output size to the dust limit when RBF-bumping X-Git-Tag: v0.0.104~31^2~1 X-Git-Url: http://git.bitcoin.ninja/index.cgi?p=rust-lightning;a=commitdiff_plain;h=9c1c7c496c34d274bfd66f04810676d215d2e904 Limit minimum output size to the dust limit when RBF-bumping --- diff --git a/lightning/src/chain/onchaintx.rs b/lightning/src/chain/onchaintx.rs index d6777cc5..8d70c772 100644 --- a/lightning/src/chain/onchaintx.rs +++ b/lightning/src/chain/onchaintx.rs @@ -380,7 +380,8 @@ impl OnchainTxHandler { let new_timer = Some(cached_request.get_height_timer(cur_height)); if cached_request.is_malleable() { let predicted_weight = cached_request.package_weight(&self.destination_script); - if let Some((output_value, new_feerate)) = cached_request.compute_package_output(predicted_weight, fee_estimator, logger) { + if let Some((output_value, new_feerate)) = + cached_request.compute_package_output(predicted_weight, self.destination_script.dust_value().as_sat(), fee_estimator, logger) { assert!(new_feerate != 0); let transaction = cached_request.finalize_package(self, output_value, self.destination_script.clone(), logger).unwrap(); diff --git a/lightning/src/chain/package.rs b/lightning/src/chain/package.rs index a86add4b..8a17f726 100644 --- a/lightning/src/chain/package.rs +++ b/lightning/src/chain/package.rs @@ -636,26 +636,25 @@ impl PackageTemplate { } current_height + LOW_FREQUENCY_BUMP_INTERVAL } - /// Returns value in satoshis to be included as package outgoing output amount and feerate with which package finalization should be done. - pub(crate) fn compute_package_output(&self, predicted_weight: usize, fee_estimator: &F, logger: &L) -> Option<(u64, u64)> + + /// Returns value in satoshis to be included as package outgoing output amount and feerate + /// which was used to generate the value. Will not return less than `dust_limit_sats` for the + /// value. + pub(crate) fn compute_package_output(&self, predicted_weight: usize, dust_limit_sats: u64, fee_estimator: &F, logger: &L) -> Option<(u64, u64)> where F::Target: FeeEstimator, L::Target: Logger, { debug_assert!(self.malleability == PackageMalleability::Malleable, "The package output is fixed for non-malleable packages"); let input_amounts = self.package_amount(); + assert!(dust_limit_sats as i64 > 0, "Output script must be broadcastable/have a 'real' dust limit."); // If old feerate is 0, first iteration of this claim, use normal fee calculation if self.feerate_previous != 0 { if let Some((new_fee, feerate)) = feerate_bump(predicted_weight, input_amounts, self.feerate_previous, fee_estimator, logger) { - // If new computed fee is superior at the whole claimable amount burn all in fees - if new_fee > input_amounts { - return Some((0, feerate)); - } else { - return Some((input_amounts - new_fee, feerate)); - } + return Some((cmp::max(input_amounts as i64 - new_fee as i64, dust_limit_sats as i64) as u64, feerate)); } } else { if let Some((new_fee, feerate)) = compute_fee_from_spent_amounts(input_amounts, predicted_weight, fee_estimator, logger) { - return Some((input_amounts - new_fee, feerate)); + return Some((cmp::max(input_amounts as i64 - new_fee as i64, dust_limit_sats as i64) as u64, feerate)); } } None