Skip to content

Commit 7340531

Browse files
committed
Rework get_latest_holder_commitment_txn to broadcast for users
This method is meant to be used as a last resort when a user is forced to broadcast the current state, even if it is stale, in an attempt to claim their funds in the channel. Previously, we'd return the commitment and HTLC transactions such that they broadcast them themselves. Doing so required a different code path, one which was not tested, to obtain these transactions than our usual path when force closing. It's not worth maintaining both, and it's much simpler for us to broadcast instead.
1 parent 242b20d commit 7340531

File tree

2 files changed

+15
-51
lines changed

2 files changed

+15
-51
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 11 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,11 +1551,18 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
15511551
/// close channel with their commitment transaction after a substantial amount of time. Best
15521552
/// may be to contact the other node operator out-of-band to coordinate other options available
15531553
/// to you.
1554-
pub fn get_latest_holder_commitment_txn<L: Deref>(&self, logger: &L) -> Result<Vec<Transaction>, ()>
1555-
where L::Target: Logger {
1554+
pub fn broadcast_latest_holder_commitment_txn<B: Deref, F: Deref, L: Deref>(
1555+
&self, broadcaster: &B, fee_estimator: &F, logger: &L
1556+
)
1557+
where
1558+
B::Target: BroadcasterInterface,
1559+
F::Target: FeeEstimator,
1560+
L::Target: Logger
1561+
{
15561562
let mut inner = self.inner.lock().unwrap();
1563+
let fee_estimator = LowerBoundedFeeEstimator::new(&**fee_estimator);
15571564
let logger = WithChannelMonitor::from_impl(logger, &*inner);
1558-
inner.get_latest_holder_commitment_txn(&logger)
1565+
inner.queue_latest_holder_commitment_txn_for_broadcast(broadcaster, &fee_estimator, &logger);
15591566
}
15601567

15611568
/// Unsafe test-only version of get_latest_holder_commitment_txn used by our test framework
@@ -2836,7 +2843,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
28362843
} else if !self.holder_tx_signed {
28372844
log_error!(logger, "WARNING: You have a potentially-unsafe holder commitment transaction available to broadcast");
28382845
log_error!(logger, " in channel monitor for channel {}!", &self.funding_info.0.to_channel_id());
2839-
log_error!(logger, " Read the docs for ChannelMonitor::get_latest_holder_commitment_txn and take manual action!");
2846+
log_error!(logger, " Read the docs for ChannelMonitor::broadcast_latest_holder_commitment_txn and take manual action!");
28402847
} else {
28412848
// If we generated a MonitorEvent::HolderForceClosed, the ChannelManager
28422849
// will still give us a ChannelForceClosed event with !should_broadcast, but we
@@ -3461,51 +3468,6 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34613468
}
34623469
}
34633470

3464-
fn get_latest_holder_commitment_txn<L: Deref>(
3465-
&mut self, logger: &WithChannelMonitor<L>,
3466-
) -> Result<Vec<Transaction>, ()> where L::Target: Logger {
3467-
log_debug!(logger, "Getting signed latest holder commitment transaction!");
3468-
self.holder_tx_signed = true;
3469-
let commitment_tx = self.onchain_tx_handler.get_maybe_signed_holder_tx(&self.funding_redeemscript);
3470-
if commitment_tx.input.iter().any(|input| input.witness.is_empty()) {
3471-
return Err(());
3472-
}
3473-
let txid = commitment_tx.txid();
3474-
let mut holder_transactions = vec![commitment_tx];
3475-
// When anchor outputs are present, the HTLC transactions are only valid once the commitment
3476-
// transaction confirms.
3477-
if self.onchain_tx_handler.channel_type_features().supports_anchors_zero_fee_htlc_tx() {
3478-
return Ok(holder_transactions);
3479-
}
3480-
for htlc in self.current_holder_commitment_tx.htlc_outputs.iter() {
3481-
if let Some(vout) = htlc.0.transaction_output_index {
3482-
let preimage = if !htlc.0.offered {
3483-
if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(preimage.clone()) } else {
3484-
// We can't build an HTLC-Success transaction without the preimage
3485-
continue;
3486-
}
3487-
} else if htlc.0.cltv_expiry > self.best_block.height() + 1 {
3488-
// Don't broadcast HTLC-Timeout transactions immediately as they don't meet the
3489-
// current locktime requirements on-chain. We will broadcast them in
3490-
// `block_confirmed` when `should_broadcast_holder_commitment_txn` returns true.
3491-
// Note that we add + 1 as transactions are broadcastable when they can be
3492-
// confirmed in the next block.
3493-
continue;
3494-
} else { None };
3495-
if let Some(htlc_tx) = self.onchain_tx_handler.get_maybe_signed_htlc_tx(
3496-
&::bitcoin::OutPoint { txid, vout }, &preimage
3497-
) {
3498-
if !htlc_tx.input.iter().any(|input| input.witness.is_empty()) {
3499-
holder_transactions.push(htlc_tx);
3500-
}
3501-
}
3502-
}
3503-
}
3504-
// 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.
3505-
// The data will be re-generated and tracked in check_spend_holder_transaction if we get a confirmation.
3506-
Ok(holder_transactions)
3507-
}
3508-
35093471
#[cfg(any(test,feature = "unsafe_revoked_tx_signing"))]
35103472
/// Note that this includes possibly-locktimed-in-the-future transactions!
35113473
fn unsafe_get_latest_holder_commitment_txn<L: Deref>(

lightning/src/ln/monitor_tests.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2755,7 +2755,9 @@ fn do_test_monitor_claims_with_random_signatures(anchors: bool, confirm_counterp
27552755
(&nodes[0], &nodes[1])
27562756
};
27572757

2758-
closing_node.node.force_close_broadcasting_latest_txn(&chan_id, &other_node.node.get_our_node_id()).unwrap();
2758+
get_monitor!(closing_node, chan_id).broadcast_latest_holder_commitment_txn(
2759+
&closing_node.tx_broadcaster, &closing_node.fee_estimator, &closing_node.logger
2760+
);
27592761

27602762
// The commitment transaction comes first.
27612763
let commitment_tx = {
@@ -2768,7 +2770,7 @@ fn do_test_monitor_claims_with_random_signatures(anchors: bool, confirm_counterp
27682770
mine_transaction(closing_node, &commitment_tx);
27692771
check_added_monitors!(closing_node, 1);
27702772
check_closed_broadcast!(closing_node, true);
2771-
check_closed_event!(closing_node, 1, ClosureReason::HolderForceClosed, [other_node.node.get_our_node_id()], 1_000_000);
2773+
check_closed_event!(closing_node, 1, ClosureReason::CommitmentTxConfirmed, [other_node.node.get_our_node_id()], 1_000_000);
27722774

27732775
mine_transaction(other_node, &commitment_tx);
27742776
check_added_monitors!(other_node, 1);

0 commit comments

Comments
 (0)