X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fchain%2Fpackage.rs;h=1b938d98137ef76cf4a4d2db82019027f504a8bf;hb=649129ddab4b24664f40190463a0b622413ab163;hp=382ffac3e8e886c303207798fafe528c78406b0d;hpb=4f4e84ef4d39a0fc81b3fd3c6c54611616860844;p=rust-lightning diff --git a/lightning/src/chain/package.rs b/lightning/src/chain/package.rs index 382ffac3..1b938d98 100644 --- a/lightning/src/chain/package.rs +++ b/lightning/src/chain/package.rs @@ -24,7 +24,7 @@ use crate::ln::PaymentPreimage; use crate::ln::chan_utils::{TxCreationKeys, HTLCOutputInCommitment}; use crate::ln::chan_utils; use crate::ln::msgs::DecodeError; -use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, MIN_RELAY_FEE_SAT_PER_1000_WEIGHT}; +use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, MIN_RELAY_FEE_SAT_PER_1000_WEIGHT, compute_feerate_sat_per_1000_weight, FEERATE_FLOOR_SATS_PER_KW}; use crate::sign::WriteableEcdsaChannelSigner; use crate::chain::onchaintx::{ExternalHTLCClaim, OnchainTxHandler}; use crate::util::logger::Logger; @@ -551,6 +551,32 @@ impl PackageSolvingData { _ => { mem::discriminant(self) == mem::discriminant(&input) } } } + fn as_tx_input(&self, previous_output: BitcoinOutPoint) -> TxIn { + let sequence = match self { + PackageSolvingData::RevokedOutput(_) => Sequence::ENABLE_RBF_NO_LOCKTIME, + PackageSolvingData::RevokedHTLCOutput(_) => Sequence::ENABLE_RBF_NO_LOCKTIME, + PackageSolvingData::CounterpartyOfferedHTLCOutput(outp) => if outp.channel_type_features.supports_anchors_zero_fee_htlc_tx() { + Sequence::from_consensus(1) + } else { + Sequence::ENABLE_RBF_NO_LOCKTIME + }, + PackageSolvingData::CounterpartyReceivedHTLCOutput(outp) => if outp.channel_type_features.supports_anchors_zero_fee_htlc_tx() { + Sequence::from_consensus(1) + } else { + Sequence::ENABLE_RBF_NO_LOCKTIME + }, + _ => { + debug_assert!(false, "This should not be reachable by 'untractable' or 'malleable with external funding' packages"); + Sequence::ENABLE_RBF_NO_LOCKTIME + }, + }; + TxIn { + previous_output, + script_sig: Script::new(), + sequence, + witness: Witness::new(), + } + } fn finalize_input(&self, bumped_tx: &mut Transaction, i: usize, onchain_handler: &mut OnchainTxHandler) -> bool { match self { PackageSolvingData::RevokedOutput(ref outp) => { @@ -895,13 +921,8 @@ impl PackageTemplate { value, }], }; - for (outpoint, _) in self.inputs.iter() { - bumped_tx.input.push(TxIn { - previous_output: *outpoint, - script_sig: Script::new(), - sequence: Sequence::ENABLE_RBF_NO_LOCKTIME, - witness: Witness::new(), - }); + for (outpoint, outp) in self.inputs.iter() { + bumped_tx.input.push(outp.as_tx_input(*outpoint)); } for (i, (outpoint, out)) in self.inputs.iter().enumerate() { log_debug!(logger, "Adding claiming input for outpoint {}:{}", outpoint.txid, outpoint.vout); @@ -1080,40 +1101,30 @@ impl Readable for PackageTemplate { } /// Attempt to propose a bumping fee for a transaction from its spent output's values and predicted -/// weight. We start with the highest priority feerate returned by the node's fee estimator then -/// fall-back to lower priorities until we have enough value available to suck from. +/// weight. We first try our [`OnChainSweep`] feerate, if it's not enough we try to sweep half of +/// the input amounts. /// /// If the proposed fee is less than the available spent output's values, we return the proposed -/// fee and the corresponding updated feerate. If the proposed fee is equal or more than the -/// available spent output's values, we return nothing +/// fee and the corresponding updated feerate. If fee is under [`FEERATE_FLOOR_SATS_PER_KW`], we +/// return nothing. +/// +/// [`OnChainSweep`]: crate::chain::chaininterface::ConfirmationTarget::OnChainSweep +/// [`FEERATE_FLOOR_SATS_PER_KW`]: crate::chain::chaininterface::MIN_RELAY_FEE_SAT_PER_1000_WEIGHT fn compute_fee_from_spent_amounts(input_amounts: u64, predicted_weight: usize, fee_estimator: &LowerBoundedFeeEstimator, logger: &L) -> Option<(u64, u64)> where F::Target: FeeEstimator, L::Target: Logger, { - let mut updated_feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::HighPriority) as u64; - let mut fee = updated_feerate * (predicted_weight as u64) / 1000; - if input_amounts <= fee { - updated_feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Normal) as u64; - fee = updated_feerate * (predicted_weight as u64) / 1000; - if input_amounts <= fee { - updated_feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Background) as u64; - fee = updated_feerate * (predicted_weight as u64) / 1000; - if input_amounts <= fee { - log_error!(logger, "Failed to generate an on-chain punishment tx as even low priority fee ({} sat) was more than the entire claim balance ({} sat)", - fee, input_amounts); - None - } else { - log_warn!(logger, "Used low priority fee for on-chain punishment tx as high priority fee was more than the entire claim balance ({} sat)", - input_amounts); - Some((fee, updated_feerate)) - } - } else { - log_warn!(logger, "Used medium priority fee for on-chain punishment tx as high priority fee was more than the entire claim balance ({} sat)", - input_amounts); - Some((fee, updated_feerate)) - } + let sweep_feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::OnChainSweep); + let fee_rate = cmp::min(sweep_feerate, compute_feerate_sat_per_1000_weight(input_amounts / 2, predicted_weight as u64)) as u64; + let fee = fee_rate * (predicted_weight as u64) / 1000; + + // if the fee rate is below the floor, we don't sweep + if fee_rate < FEERATE_FLOOR_SATS_PER_KW as u64 { + log_error!(logger, "Failed to generate an on-chain tx with fee ({} sat/kw) was less than the floor ({} sat/kw)", + fee_rate, FEERATE_FLOOR_SATS_PER_KW); + None } else { - Some((fee, updated_feerate)) + Some((fee, fee_rate)) } }