use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
use crate::chain::transaction::{OutPoint, TransactionData};
use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, ecdsa::WriteableEcdsaChannelSigner, SignerProvider, EntropySource};
-use crate::chain::onchaintx::{ClaimEvent, OnchainTxHandler};
+use crate::chain::onchaintx::{ClaimEvent, FeerateStrategy, OnchainTxHandler};
use crate::chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderFundingOutput, HolderHTLCOutput, PackageSolvingData, PackageTemplate, RevokedOutput, RevokedHTLCOutput};
use crate::chain::Filter;
use crate::util::logger::{Logger, Record};
/// Loads the funding txo and outputs to watch into the given `chain::Filter` by repeatedly
/// calling `chain::Filter::register_output` and `chain::Filter::register_tx` until all outputs
/// have been registered.
- pub fn load_outputs_to_watch<F: Deref, L: Deref>(&self, filter: &F, logger: &L)
- where
+ pub fn load_outputs_to_watch<F: Deref, L: Deref>(&self, filter: &F, logger: &L)
+ where
F::Target: chain::Filter, L::Target: Logger,
{
let lock = self.inner.lock().unwrap();
self.inner.lock().unwrap().counterparty_node_id
}
- /// Used by [`ChannelManager`] deserialization to broadcast the latest holder state if its copy
- /// of the channel state was out-of-date.
- ///
- /// You may also use this to broadcast the latest local commitment transaction, either because
+ /// You may use this to broadcast the latest local commitment transaction, either because
/// a monitor update failed or because we've fallen behind (i.e. we've received proof that our
/// counterparty side knows a revocation secret we gave them that they shouldn't know).
///
- /// Broadcasting these transactions in the second case is UNSAFE, as they allow counterparty
+ /// Broadcasting these transactions in this manner is UNSAFE, as they allow counterparty
/// side to punish you. Nevertheless you may want to broadcast them if counterparty doesn't
/// close channel with their commitment transaction after a substantial amount of time. Best
/// may be to contact the other node operator out-of-band to coordinate other options available
/// to you.
- ///
- /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
- pub fn get_latest_holder_commitment_txn<L: Deref>(&self, logger: &L) -> Vec<Transaction>
- where L::Target: Logger {
+ pub fn broadcast_latest_holder_commitment_txn<B: Deref, F: Deref, L: Deref>(
+ &self, broadcaster: &B, fee_estimator: &F, logger: &L
+ )
+ where
+ B::Target: BroadcasterInterface,
+ F::Target: FeeEstimator,
+ L::Target: Logger
+ {
let mut inner = self.inner.lock().unwrap();
+ let fee_estimator = LowerBoundedFeeEstimator::new(&**fee_estimator);
let logger = WithChannelMonitor::from_impl(logger, &*inner);
- inner.get_latest_holder_commitment_txn(&logger)
+ inner.queue_latest_holder_commitment_txn_for_broadcast(broadcaster, &fee_estimator, &logger);
}
- /// Unsafe test-only version of get_latest_holder_commitment_txn used by our test framework
+ /// Unsafe test-only version of `broadcast_latest_holder_commitment_txn` used by our test framework
/// to bypass HolderCommitmentTransaction state update lockdown after signature and generate
/// revoked commitment transaction.
#[cfg(any(test, feature = "unsafe_revoked_tx_signing"))]
let logger = WithChannelMonitor::from_impl(logger, &*inner);
let current_height = inner.best_block.height;
inner.onchain_tx_handler.rebroadcast_pending_claims(
- current_height, &broadcaster, &fee_estimator, &logger,
+ current_height, FeerateStrategy::HighestOfPreviousOrNew, &broadcaster, &fee_estimator, &logger,
);
}
} else if !self.holder_tx_signed {
log_error!(logger, "WARNING: You have a potentially-unsafe holder commitment transaction available to broadcast");
log_error!(logger, " in channel monitor for channel {}!", &self.channel_id());
- log_error!(logger, " Read the docs for ChannelMonitor::get_latest_holder_commitment_txn and take manual action!");
+ log_error!(logger, " Read the docs for ChannelMonitor::broadcast_latest_holder_commitment_txn to take manual action!");
} else {
// If we generated a MonitorEvent::HolderForceClosed, the ChannelManager
// will still give us a ChannelForceClosed event with !should_broadcast, but we
ClaimEvent::BumpCommitment {
package_target_feerate_sat_per_1000_weight, commitment_tx, anchor_output_idx,
} => {
+ let channel_id = self.channel_id;
+ // unwrap safety: `ClaimEvent`s are only available for Anchor channels,
+ // introduced with v0.0.116. counterparty_node_id is guaranteed to be `Some`
+ // since v0.0.110.
+ let counterparty_node_id = self.counterparty_node_id.unwrap();
let commitment_txid = commitment_tx.txid();
debug_assert_eq!(self.current_holder_commitment_tx.txid, commitment_txid);
let pending_htlcs = self.current_holder_commitment_tx.non_dust_htlcs();
let commitment_tx_fee_satoshis = self.channel_value_satoshis -
commitment_tx.output.iter().fold(0u64, |sum, output| sum + output.value);
ret.push(Event::BumpTransaction(BumpTransactionEvent::ChannelClose {
+ channel_id,
+ counterparty_node_id,
claim_id,
package_target_feerate_sat_per_1000_weight,
commitment_tx,
ClaimEvent::BumpHTLC {
target_feerate_sat_per_1000_weight, htlcs, tx_lock_time,
} => {
+ let channel_id = self.channel_id;
+ // unwrap safety: `ClaimEvent`s are only available for Anchor channels,
+ // introduced with v0.0.116. counterparty_node_id is guaranteed to be `Some`
+ // since v0.0.110.
+ let counterparty_node_id = self.counterparty_node_id.unwrap();
let mut htlc_descriptors = Vec::with_capacity(htlcs.len());
for htlc in htlcs {
htlc_descriptors.push(HTLCDescriptor {
});
}
ret.push(Event::BumpTransaction(BumpTransactionEvent::HTLCResolution {
+ channel_id,
+ counterparty_node_id,
claim_id,
target_feerate_sat_per_1000_weight,
htlc_descriptors,
(htlc, htlc_source.as_ref().map(|htlc_source| htlc_source.as_ref()))
), logger);
} else {
- // Our fuzzers aren't contrained by pesky things like valid signatures, so can
+ // Our fuzzers aren't constrained by pesky things like valid signatures, so can
// spend our funding output with a transaction which doesn't match our past
// commitment transactions. Thus, we can only debug-assert here when not
// fuzzing.
}
}
- fn get_latest_holder_commitment_txn<L: Deref>(
- &mut self, logger: &WithChannelMonitor<L>,
- ) -> Vec<Transaction> where L::Target: Logger {
- log_debug!(logger, "Getting signed latest holder commitment transaction!");
- self.holder_tx_signed = true;
- let commitment_tx = self.onchain_tx_handler.get_fully_signed_holder_tx(&self.funding_redeemscript);
- let txid = commitment_tx.txid();
- let mut holder_transactions = vec![commitment_tx];
- // When anchor outputs are present, the HTLC transactions are only valid once the commitment
- // transaction confirms.
- if self.onchain_tx_handler.channel_type_features().supports_anchors_zero_fee_htlc_tx() {
- return holder_transactions;
- }
- for htlc in self.current_holder_commitment_tx.htlc_outputs.iter() {
- if let Some(vout) = htlc.0.transaction_output_index {
- let preimage = if !htlc.0.offered {
- if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(preimage.clone()) } else {
- // We can't build an HTLC-Success transaction without the preimage
- continue;
- }
- } else if htlc.0.cltv_expiry > self.best_block.height() + 1 {
- // Don't broadcast HTLC-Timeout transactions immediately as they don't meet the
- // current locktime requirements on-chain. We will broadcast them in
- // `block_confirmed` when `should_broadcast_holder_commitment_txn` returns true.
- // Note that we add + 1 as transactions are broadcastable when they can be
- // confirmed in the next block.
- continue;
- } else { None };
- if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx(
- &::bitcoin::OutPoint { txid, vout }, &preimage) {
- holder_transactions.push(htlc_tx);
- }
- }
- }
- // We throw away the generated waiting_first_conf data as we aren't (yet) confirmed and we don't actually know what the caller wants to do.
- // The data will be re-generated and tracked in check_spend_holder_transaction if we get a confirmation.
- holder_transactions
- }
-
#[cfg(any(test,feature = "unsafe_revoked_tx_signing"))]
/// Note that this includes possibly-locktimed-in-the-future transactions!
fn unsafe_get_latest_holder_commitment_txn<L: Deref>(