Skip to content

Commit d161031

Browse files
fixup: replay spends when commitment broadcast was previously skipped because of funding_seen_onchain=false
1 parent b4eb396 commit d161031

File tree

1 file changed

+40
-7
lines changed

1 file changed

+40
-7
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,8 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
11931193
/// True once we've observed either funding transaction on-chain. Older monitors assume this is
11941194
/// `true` when absent during upgrade so holder broadcasts aren't gated unexpectedly.
11951195
funding_seen_onchain: bool,
1196+
/// Tracks whether manual-broadcasting was requested before the funding transaction appeared on-chain.
1197+
manual_broadcast_pending: bool,
11961198

11971199
latest_update_id: u64,
11981200
commitment_transaction_number_obscure_factor: u64,
@@ -1734,6 +1736,7 @@ pub(crate) fn write_chanmon_internal<Signer: EcdsaChannelSigner, W: Writer>(
17341736
(34, channel_monitor.alternative_funding_confirmed, option),
17351737
(35, channel_monitor.is_manual_broadcast, required),
17361738
(37, channel_monitor.funding_seen_onchain, required),
1739+
(39, channel_monitor.manual_broadcast_pending, required),
17371740
});
17381741

17391742
Ok(())
@@ -1911,6 +1914,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
19111914

19121915
is_manual_broadcast,
19131916
funding_seen_onchain: false,
1917+
manual_broadcast_pending: false,
19141918

19151919
latest_update_id: 0,
19161920
commitment_transaction_number_obscure_factor,
@@ -3983,6 +3987,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
39833987
// the funding transaction on-chain, do not queue any transactions.
39843988
if require_funding_seen && self.is_manual_broadcast && !self.funding_seen_onchain {
39853989
log_info!(logger, "Not broadcasting holder commitment for manual-broadcast channel before funding appears on-chain");
3990+
self.manual_broadcast_pending = true;
39863991
return;
39873992
}
39883993
let reason = ClosureReason::HolderForceClosed {
@@ -3995,6 +4000,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
39954000
claimable_outpoints, self.best_block.height, self.best_block.height, broadcaster,
39964001
conf_target, &self.destination_script, fee_estimator, logger,
39974002
);
4003+
self.manual_broadcast_pending = false;
39984004
}
39994005

40004006
fn renegotiated_funding<L: Deref>(
@@ -5275,6 +5281,15 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
52755281

52765282
let mut watch_outputs = Vec::new();
52775283
let mut claimable_outpoints = Vec::new();
5284+
5285+
if self.is_manual_broadcast && self.funding_seen_onchain && self.manual_broadcast_pending {
5286+
self.queue_latest_holder_commitment_txn_for_broadcast(
5287+
&broadcaster,
5288+
fee_estimator,
5289+
logger,
5290+
true,
5291+
);
5292+
}
52785293
'tx_iter: for tx in &txn_matched {
52795294
let txid = tx.compute_txid();
52805295
log_trace!(logger, "Transaction {} confirmed in block {}", txid , block_hash);
@@ -5489,12 +5504,16 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
54895504
}
54905505

54915506
if should_broadcast_commitment {
5492-
// Avoid broadcasting in manual-broadcast mode until funding is seen on-chain.
5493-
if !self.is_manual_broadcast || self.funding_seen_onchain {
5494-
let (mut claimables, mut outputs) =
5495-
self.generate_claimable_outpoints_and_watch_outputs(None);
5507+
// Always update holder state, but only enqueue broadcast data once funding is seen in
5508+
// manual-broadcast mode.
5509+
let (mut claimables, mut outputs) =
5510+
self.generate_claimable_outpoints_and_watch_outputs(None);
5511+
if self.is_manual_broadcast && !self.funding_seen_onchain {
5512+
self.manual_broadcast_pending = true;
5513+
} else {
54965514
claimable_outpoints.append(&mut claimables);
54975515
watch_outputs.append(&mut outputs);
5516+
self.manual_broadcast_pending = false;
54985517
}
54995518
}
55005519

@@ -5532,13 +5551,14 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
55325551
let should_broadcast = self.should_broadcast_holder_commitment_txn(logger);
55335552
if let Some(payment_hash) = should_broadcast {
55345553
let reason = ClosureReason::HTLCsTimedOut { payment_hash: Some(payment_hash) };
5554+
let (mut new_outpoints, mut new_outputs) =
5555+
self.generate_claimable_outpoints_and_watch_outputs(Some(reason));
55355556
if self.is_manual_broadcast && !self.funding_seen_onchain {
5536-
let _ = self.generate_claimable_outpoints_and_watch_outputs(Some(reason));
5557+
self.manual_broadcast_pending = true;
55375558
} else {
5538-
let (mut new_outpoints, mut new_outputs) =
5539-
self.generate_claimable_outpoints_and_watch_outputs(Some(reason));
55405559
claimable_outpoints.append(&mut new_outpoints);
55415560
watch_outputs.append(&mut new_outputs);
5561+
self.manual_broadcast_pending = false;
55425562
}
55435563
}
55445564

@@ -6506,6 +6526,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
65066526
let mut alternative_funding_confirmed = None;
65076527
let mut is_manual_broadcast = None;
65086528
let mut funding_seen_onchain = None;
6529+
let mut manual_broadcast_pending = None;
65096530
read_tlv_fields!(reader, {
65106531
(1, funding_spend_confirmed, option),
65116532
(3, htlcs_resolved_on_chain, optional_vec),
@@ -6528,6 +6549,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
65286549
(34, alternative_funding_confirmed, option),
65296550
(35, is_manual_broadcast, option),
65306551
(37, funding_seen_onchain, option),
6552+
(39, manual_broadcast_pending, option),
65316553
});
65326554
// Note that `payment_preimages_with_info` was added (and is always written) in LDK 0.1, so
65336555
// we can use it to determine if this monitor was last written by LDK 0.1 or later.
@@ -6562,6 +6584,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
65626584
let channel_parameters = channel_parameters.unwrap_or_else(|| {
65636585
onchain_tx_handler.channel_parameters().clone()
65646586
});
6587+
let manual_broadcast_pending = manual_broadcast_pending.unwrap_or(false);
65656588

65666589
// Monitors for anchor outputs channels opened in v0.0.116 suffered from a bug in which the
65676590
// wrong `counterparty_payment_script` was being tracked. Fix it now on deserialization to
@@ -6648,6 +6671,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
66486671
is_manual_broadcast: is_manual_broadcast.unwrap_or(false),
66496672
// Assume "seen" when absent to prevent gating holder broadcasts after upgrade.
66506673
funding_seen_onchain: funding_seen_onchain.unwrap_or(true),
6674+
manual_broadcast_pending,
66516675

66526676
latest_update_id,
66536677
commitment_transaction_number_obscure_factor,
@@ -7137,6 +7161,11 @@ mod tests {
71377161
let header = create_dummy_header(prev_hash, 0);
71387162
monitor.best_block_updated(&header, 10, &*broadcaster, &fee_estimator, &logger);
71397163
assert!(broadcaster.txn_broadcast().is_empty());
7164+
{
7165+
let inner = monitor.inner.lock().unwrap();
7166+
assert!(!inner.funding_seen_onchain);
7167+
assert!(inner.manual_broadcast_pending);
7168+
}
71407169

71417170
// Now confirm the funding transaction via transactions_confirmed.
71427171
let fund_block = create_dummy_block(header.block_hash(), 1, vec![funding_tx.clone()]);
@@ -7150,6 +7179,10 @@ mod tests {
71507179
&fee_estimator,
71517180
&logger,
71527181
);
7182+
{
7183+
let inner = monitor.inner.lock().unwrap();
7184+
assert!(!inner.manual_broadcast_pending);
7185+
}
71537186

71547187
// Next height update should allow broadcast.
71557188
{

0 commit comments

Comments
 (0)