@@ -1175,6 +1175,8 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
1175
1175
/// True once we've observed either funding transaction on-chain. Older monitors assume this is
1176
1176
/// `true` when absent during upgrade so holder broadcasts aren't gated unexpectedly.
1177
1177
funding_seen_onchain : bool ,
1178
+ /// Tracks whether manual-broadcasting was requested before the funding transaction appeared on-chain.
1179
+ manual_broadcast_pending : bool ,
1178
1180
1179
1181
latest_update_id : u64 ,
1180
1182
commitment_transaction_number_obscure_factor : u64 ,
@@ -1707,6 +1709,7 @@ pub(crate) fn write_chanmon_internal<Signer: EcdsaChannelSigner, W: Writer>(
1707
1709
( 34 , channel_monitor. alternative_funding_confirmed, option) ,
1708
1710
( 35 , channel_monitor. is_manual_broadcast, required) ,
1709
1711
( 37 , channel_monitor. funding_seen_onchain, required) ,
1712
+ ( 39 , channel_monitor. manual_broadcast_pending, required) ,
1710
1713
} ) ;
1711
1714
1712
1715
Ok ( ( ) )
@@ -1884,6 +1887,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
1884
1887
1885
1888
is_manual_broadcast,
1886
1889
funding_seen_onchain : false ,
1890
+ manual_broadcast_pending : false ,
1887
1891
1888
1892
latest_update_id : 0 ,
1889
1893
commitment_transaction_number_obscure_factor,
@@ -4011,6 +4015,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
4011
4015
// the funding transaction on-chain, do not queue any transactions.
4012
4016
if require_funding_seen && self . is_manual_broadcast && !self . funding_seen_onchain {
4013
4017
log_info ! ( logger, "Not broadcasting holder commitment for manual-broadcast channel before funding appears on-chain" ) ;
4018
+ self . manual_broadcast_pending = true ;
4014
4019
return ;
4015
4020
}
4016
4021
let reason = ClosureReason :: HolderForceClosed {
@@ -4023,6 +4028,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
4023
4028
claimable_outpoints, self . best_block . height , self . best_block . height , broadcaster,
4024
4029
conf_target, & self . destination_script , fee_estimator, logger,
4025
4030
) ;
4031
+ self . manual_broadcast_pending = false ;
4026
4032
}
4027
4033
4028
4034
fn renegotiated_funding < L : Deref > (
@@ -5274,6 +5280,15 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
5274
5280
5275
5281
let mut watch_outputs = Vec :: new ( ) ;
5276
5282
let mut claimable_outpoints = Vec :: new ( ) ;
5283
+
5284
+ if self . is_manual_broadcast && self . funding_seen_onchain && self . manual_broadcast_pending {
5285
+ self . queue_latest_holder_commitment_txn_for_broadcast (
5286
+ & broadcaster,
5287
+ fee_estimator,
5288
+ logger,
5289
+ true ,
5290
+ ) ;
5291
+ }
5277
5292
' tx_iter: for tx in & txn_matched {
5278
5293
let txid = tx. compute_txid ( ) ;
5279
5294
log_trace ! ( logger, "Transaction {} confirmed in block {}" , txid , block_hash) ;
@@ -5488,12 +5503,16 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
5488
5503
}
5489
5504
5490
5505
if should_broadcast_commitment {
5491
- // Avoid broadcasting in manual-broadcast mode until funding is seen on-chain.
5492
- if !self . is_manual_broadcast || self . funding_seen_onchain {
5493
- let ( mut claimables, mut outputs) =
5494
- self . generate_claimable_outpoints_and_watch_outputs ( None ) ;
5506
+ // Always update holder state, but only enqueue broadcast data once funding is seen in
5507
+ // manual-broadcast mode.
5508
+ let ( mut claimables, mut outputs) =
5509
+ self . generate_claimable_outpoints_and_watch_outputs ( None ) ;
5510
+ if self . is_manual_broadcast && !self . funding_seen_onchain {
5511
+ self . manual_broadcast_pending = true ;
5512
+ } else {
5495
5513
claimable_outpoints. append ( & mut claimables) ;
5496
5514
watch_outputs. append ( & mut outputs) ;
5515
+ self . manual_broadcast_pending = false ;
5497
5516
}
5498
5517
}
5499
5518
@@ -5531,13 +5550,14 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
5531
5550
let should_broadcast = self . should_broadcast_holder_commitment_txn ( logger) ;
5532
5551
if let Some ( payment_hash) = should_broadcast {
5533
5552
let reason = ClosureReason :: HTLCsTimedOut { payment_hash : Some ( payment_hash) } ;
5553
+ let ( mut new_outpoints, mut new_outputs) =
5554
+ self . generate_claimable_outpoints_and_watch_outputs ( Some ( reason) ) ;
5534
5555
if self . is_manual_broadcast && !self . funding_seen_onchain {
5535
- let _ = self . generate_claimable_outpoints_and_watch_outputs ( Some ( reason ) ) ;
5556
+ self . manual_broadcast_pending = true ;
5536
5557
} else {
5537
- let ( mut new_outpoints, mut new_outputs) =
5538
- self . generate_claimable_outpoints_and_watch_outputs ( Some ( reason) ) ;
5539
5558
claimable_outpoints. append ( & mut new_outpoints) ;
5540
5559
watch_outputs. append ( & mut new_outputs) ;
5560
+ self . manual_broadcast_pending = false ;
5541
5561
}
5542
5562
}
5543
5563
@@ -6493,6 +6513,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
6493
6513
let mut alternative_funding_confirmed = None ;
6494
6514
let mut is_manual_broadcast = None ;
6495
6515
let mut funding_seen_onchain = None ;
6516
+ let mut manual_broadcast_pending = None ;
6496
6517
read_tlv_fields ! ( reader, {
6497
6518
( 1 , funding_spend_confirmed, option) ,
6498
6519
( 3 , htlcs_resolved_on_chain, optional_vec) ,
@@ -6514,6 +6535,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
6514
6535
( 34 , alternative_funding_confirmed, option) ,
6515
6536
( 35 , is_manual_broadcast, option) ,
6516
6537
( 37 , funding_seen_onchain, option) ,
6538
+ ( 39 , manual_broadcast_pending, option) ,
6517
6539
} ) ;
6518
6540
// Note that `payment_preimages_with_info` was added (and is always written) in LDK 0.1, so
6519
6541
// we can use it to determine if this monitor was last written by LDK 0.1 or later.
@@ -6548,6 +6570,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
6548
6570
let channel_parameters = channel_parameters. unwrap_or_else ( || {
6549
6571
onchain_tx_handler. channel_parameters ( ) . clone ( )
6550
6572
} ) ;
6573
+ let manual_broadcast_pending = manual_broadcast_pending. unwrap_or ( false ) ;
6551
6574
6552
6575
// Monitors for anchor outputs channels opened in v0.0.116 suffered from a bug in which the
6553
6576
// wrong `counterparty_payment_script` was being tracked. Fix it now on deserialization to
@@ -6634,6 +6657,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
6634
6657
is_manual_broadcast : is_manual_broadcast. unwrap_or ( false ) ,
6635
6658
// Assume "seen" when absent to prevent gating holder broadcasts after upgrade.
6636
6659
funding_seen_onchain : funding_seen_onchain. unwrap_or ( true ) ,
6660
+ manual_broadcast_pending,
6637
6661
6638
6662
latest_update_id,
6639
6663
commitment_transaction_number_obscure_factor,
@@ -7122,6 +7146,11 @@ mod tests {
7122
7146
let header = create_dummy_header ( prev_hash, 0 ) ;
7123
7147
monitor. best_block_updated ( & header, 10 , & * broadcaster, & fee_estimator, & logger) ;
7124
7148
assert ! ( broadcaster. txn_broadcast( ) . is_empty( ) ) ;
7149
+ {
7150
+ let inner = monitor. inner . lock ( ) . unwrap ( ) ;
7151
+ assert ! ( !inner. funding_seen_onchain) ;
7152
+ assert ! ( inner. manual_broadcast_pending) ;
7153
+ }
7125
7154
7126
7155
// Now confirm the funding transaction via transactions_confirmed.
7127
7156
let fund_block = create_dummy_block ( header. block_hash ( ) , 1 , vec ! [ funding_tx. clone( ) ] ) ;
@@ -7135,6 +7164,10 @@ mod tests {
7135
7164
& fee_estimator,
7136
7165
& logger,
7137
7166
) ;
7167
+ {
7168
+ let inner = monitor. inner . lock ( ) . unwrap ( ) ;
7169
+ assert ! ( !inner. manual_broadcast_pending) ;
7170
+ }
7138
7171
7139
7172
// Next height update should allow broadcast.
7140
7173
{
0 commit comments