@@ -1193,6 +1193,8 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
1193
1193
/// True once we've observed either funding transaction on-chain. Older monitors assume this is
1194
1194
/// `true` when absent during upgrade so holder broadcasts aren't gated unexpectedly.
1195
1195
funding_seen_onchain : bool ,
1196
+ /// Tracks whether manual-broadcasting was requested before the funding transaction appeared on-chain.
1197
+ manual_broadcast_pending : bool ,
1196
1198
1197
1199
latest_update_id : u64 ,
1198
1200
commitment_transaction_number_obscure_factor : u64 ,
@@ -1734,6 +1736,7 @@ pub(crate) fn write_chanmon_internal<Signer: EcdsaChannelSigner, W: Writer>(
1734
1736
( 34 , channel_monitor. alternative_funding_confirmed, option) ,
1735
1737
( 35 , channel_monitor. is_manual_broadcast, required) ,
1736
1738
( 37 , channel_monitor. funding_seen_onchain, required) ,
1739
+ ( 39 , channel_monitor. manual_broadcast_pending, required) ,
1737
1740
} ) ;
1738
1741
1739
1742
Ok ( ( ) )
@@ -1911,6 +1914,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
1911
1914
1912
1915
is_manual_broadcast,
1913
1916
funding_seen_onchain : false ,
1917
+ manual_broadcast_pending : false ,
1914
1918
1915
1919
latest_update_id : 0 ,
1916
1920
commitment_transaction_number_obscure_factor,
@@ -3983,6 +3987,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3983
3987
// the funding transaction on-chain, do not queue any transactions.
3984
3988
if require_funding_seen && self . is_manual_broadcast && !self . funding_seen_onchain {
3985
3989
log_info ! ( logger, "Not broadcasting holder commitment for manual-broadcast channel before funding appears on-chain" ) ;
3990
+ self . manual_broadcast_pending = true ;
3986
3991
return ;
3987
3992
}
3988
3993
let reason = ClosureReason :: HolderForceClosed {
@@ -3995,6 +4000,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3995
4000
claimable_outpoints, self . best_block . height , self . best_block . height , broadcaster,
3996
4001
conf_target, & self . destination_script , fee_estimator, logger,
3997
4002
) ;
4003
+ self . manual_broadcast_pending = false ;
3998
4004
}
3999
4005
4000
4006
fn renegotiated_funding < L : Deref > (
@@ -5275,6 +5281,15 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
5275
5281
5276
5282
let mut watch_outputs = Vec :: new ( ) ;
5277
5283
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
+ }
5278
5293
' tx_iter: for tx in & txn_matched {
5279
5294
let txid = tx. compute_txid ( ) ;
5280
5295
log_trace ! ( logger, "Transaction {} confirmed in block {}" , txid , block_hash) ;
@@ -5489,12 +5504,16 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
5489
5504
}
5490
5505
5491
5506
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 {
5496
5514
claimable_outpoints. append ( & mut claimables) ;
5497
5515
watch_outputs. append ( & mut outputs) ;
5516
+ self . manual_broadcast_pending = false ;
5498
5517
}
5499
5518
}
5500
5519
@@ -5532,13 +5551,14 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
5532
5551
let should_broadcast = self . should_broadcast_holder_commitment_txn ( logger) ;
5533
5552
if let Some ( payment_hash) = should_broadcast {
5534
5553
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) ) ;
5535
5556
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 ;
5537
5558
} else {
5538
- let ( mut new_outpoints, mut new_outputs) =
5539
- self . generate_claimable_outpoints_and_watch_outputs ( Some ( reason) ) ;
5540
5559
claimable_outpoints. append ( & mut new_outpoints) ;
5541
5560
watch_outputs. append ( & mut new_outputs) ;
5561
+ self . manual_broadcast_pending = false ;
5542
5562
}
5543
5563
}
5544
5564
@@ -6495,6 +6515,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
6495
6515
let mut alternative_funding_confirmed = None ;
6496
6516
let mut is_manual_broadcast = None ;
6497
6517
let mut funding_seen_onchain = None ;
6518
+ let mut manual_broadcast_pending = None ;
6498
6519
read_tlv_fields ! ( reader, {
6499
6520
( 1 , funding_spend_confirmed, option) ,
6500
6521
( 3 , htlcs_resolved_on_chain, optional_vec) ,
@@ -6517,6 +6538,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
6517
6538
( 34 , alternative_funding_confirmed, option) ,
6518
6539
( 35 , is_manual_broadcast, option) ,
6519
6540
( 37 , funding_seen_onchain, option) ,
6541
+ ( 39 , manual_broadcast_pending, option) ,
6520
6542
} ) ;
6521
6543
// Note that `payment_preimages_with_info` was added (and is always written) in LDK 0.1, so
6522
6544
// we can use it to determine if this monitor was last written by LDK 0.1 or later.
@@ -6551,6 +6573,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
6551
6573
let channel_parameters = channel_parameters. unwrap_or_else ( || {
6552
6574
onchain_tx_handler. channel_parameters ( ) . clone ( )
6553
6575
} ) ;
6576
+ let manual_broadcast_pending = manual_broadcast_pending. unwrap_or ( false ) ;
6554
6577
6555
6578
// Monitors for anchor outputs channels opened in v0.0.116 suffered from a bug in which the
6556
6579
// wrong `counterparty_payment_script` was being tracked. Fix it now on deserialization to
@@ -6637,6 +6660,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
6637
6660
is_manual_broadcast : is_manual_broadcast. unwrap_or ( false ) ,
6638
6661
// Assume "seen" when absent to prevent gating holder broadcasts after upgrade.
6639
6662
funding_seen_onchain : funding_seen_onchain. unwrap_or ( true ) ,
6663
+ manual_broadcast_pending,
6640
6664
6641
6665
latest_update_id,
6642
6666
commitment_transaction_number_obscure_factor,
@@ -7126,6 +7150,11 @@ mod tests {
7126
7150
let header = create_dummy_header ( prev_hash, 0 ) ;
7127
7151
monitor. best_block_updated ( & header, 10 , & * broadcaster, & fee_estimator, & logger) ;
7128
7152
assert ! ( broadcaster. txn_broadcast( ) . is_empty( ) ) ;
7153
+ {
7154
+ let inner = monitor. inner . lock ( ) . unwrap ( ) ;
7155
+ assert ! ( !inner. funding_seen_onchain) ;
7156
+ assert ! ( inner. manual_broadcast_pending) ;
7157
+ }
7129
7158
7130
7159
// Now confirm the funding transaction via transactions_confirmed.
7131
7160
let fund_block = create_dummy_block ( header. block_hash ( ) , 1 , vec ! [ funding_tx. clone( ) ] ) ;
@@ -7139,6 +7168,10 @@ mod tests {
7139
7168
& fee_estimator,
7140
7169
& logger,
7141
7170
) ;
7171
+ {
7172
+ let inner = monitor. inner . lock ( ) . unwrap ( ) ;
7173
+ assert ! ( !inner. manual_broadcast_pending) ;
7174
+ }
7142
7175
7143
7176
// Next height update should allow broadcast.
7144
7177
{
0 commit comments