@@ -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