@@ -1202,6 +1202,19 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
12021202 funding : FundingScope ,
12031203 pending_funding : Vec < FundingScope > ,
12041204
1205+ /// True if this channel was configured for manual funding broadcasts. Monitors written by
1206+ /// versions prior to LDK 0.2 load with `false` until a new update persists it.
1207+ is_manual_broadcast : bool ,
1208+ /// True once we've observed either funding transaction on-chain. Older monitors prior to LDK 0.2
1209+ /// assume this is `true` when absent during upgrade so holder broadcasts aren't gated unexpectedly.
1210+ /// In manual-broadcast channels we also use this to trigger deferred holder
1211+ /// broadcasts once the funding transaction finally appears on-chain.
1212+ ///
1213+ /// Note: This tracks whether the funding transaction was ever broadcast, not whether it is
1214+ /// currently confirmed. It is never reset, even if the funding transaction is unconfirmed due
1215+ /// to a reorg.
1216+ funding_seen_onchain : bool ,
1217+
12051218 latest_update_id : u64 ,
12061219 commitment_transaction_number_obscure_factor : u64 ,
12071220
@@ -1740,6 +1753,8 @@ pub(crate) fn write_chanmon_internal<Signer: EcdsaChannelSigner, W: Writer>(
17401753 ( 32 , channel_monitor. pending_funding, optional_vec) ,
17411754 ( 33 , channel_monitor. htlcs_resolved_to_user, required) ,
17421755 ( 34 , channel_monitor. alternative_funding_confirmed, option) ,
1756+ ( 35 , channel_monitor. is_manual_broadcast, required) ,
1757+ ( 37 , channel_monitor. funding_seen_onchain, required) ,
17431758 } ) ;
17441759
17451760 Ok ( ( ) )
@@ -1868,6 +1883,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
18681883 commitment_transaction_number_obscure_factor : u64 ,
18691884 initial_holder_commitment_tx : HolderCommitmentTransaction , best_block : BestBlock ,
18701885 counterparty_node_id : PublicKey , channel_id : ChannelId ,
1886+ is_manual_broadcast : bool ,
18711887 ) -> ChannelMonitor < Signer > {
18721888
18731889 assert ! ( commitment_transaction_number_obscure_factor <= ( 1 << 48 ) ) ;
@@ -1914,6 +1930,9 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
19141930 } ,
19151931 pending_funding : vec ! [ ] ,
19161932
1933+ is_manual_broadcast,
1934+ funding_seen_onchain : false ,
1935+
19171936 latest_update_id : 0 ,
19181937 commitment_transaction_number_obscure_factor,
19191938
@@ -2327,19 +2346,33 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
23272346 /// close channel with their commitment transaction after a substantial amount of time. Best
23282347 /// may be to contact the other node operator out-of-band to coordinate other options available
23292348 /// to you.
2330- #[ rustfmt:: skip]
2349+ ///
2350+ /// Note: For channels using manual funding broadcast (see
2351+ /// [`crate::ln::channelmanager::ChannelManager::funding_transaction_generated_manual_broadcast`]),
2352+ /// automatic broadcasts are suppressed until the funding transaction has been observed on-chain.
2353+ /// Calling this method overrides that suppression and queues the latest holder commitment
2354+ /// transaction for broadcast even if the funding has not yet been seen on-chain. This may result
2355+ /// in unconfirmable transactions being broadcast or [`Event::BumpTransaction`] notifications for
2356+ /// transactions that cannot be confirmed until the funding transaction is visible.
2357+ ///
2358+ /// [`Event::BumpTransaction`]: crate::events::Event::BumpTransaction
23312359 pub fn broadcast_latest_holder_commitment_txn < B : Deref , F : Deref , L : Deref > (
2332- & self , broadcaster : & B , fee_estimator : & F , logger : & L
2333- )
2334- where
2360+ & self , broadcaster : & B , fee_estimator : & F , logger : & L ,
2361+ ) where
23352362 B :: Target : BroadcasterInterface ,
23362363 F :: Target : FeeEstimator ,
2337- L :: Target : Logger
2364+ L :: Target : Logger ,
23382365 {
23392366 let mut inner = self . inner . lock ( ) . unwrap ( ) ;
23402367 let fee_estimator = LowerBoundedFeeEstimator :: new ( & * * fee_estimator) ;
23412368 let logger = WithChannelMonitor :: from_impl ( logger, & * inner, None ) ;
2342- inner. queue_latest_holder_commitment_txn_for_broadcast ( broadcaster, & fee_estimator, & logger) ;
2369+
2370+ inner. queue_latest_holder_commitment_txn_for_broadcast (
2371+ broadcaster,
2372+ & fee_estimator,
2373+ & logger,
2374+ false ,
2375+ ) ;
23432376 }
23442377
23452378 /// Unsafe test-only version of `broadcast_latest_holder_commitment_txn` used by our test framework
@@ -3952,12 +3985,26 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
39523985 }
39533986 claimable_outpoints. append ( & mut new_outpoints) ;
39543987 }
3955- ( claimable_outpoints, watch_outputs)
3988+ // In manual-broadcast mode, if we have not yet observed the funding transaction on-chain,
3989+ // return empty vectors.
3990+ if self . is_manual_broadcast && !self . funding_seen_onchain {
3991+ return ( Vec :: new ( ) , Vec :: new ( ) ) ;
3992+ } else {
3993+ ( claimable_outpoints, watch_outputs)
3994+ }
39563995 }
39573996
39583997 #[ rustfmt:: skip]
3998+ /// Note: For channels where the funding transaction is being manually managed (see
3999+ /// [`crate::ln::channelmanager::ChannelManager::funding_transaction_generated_manual_broadcast`]),
4000+ /// this method returns without queuing any transactions until the funding transaction has been
4001+ /// observed on-chain, unless `require_funding_seen` is `false`. This prevents attempting to
4002+ /// broadcast unconfirmable holder commitment transactions before the funding is visible.
4003+ /// See also [`ChannelMonitor::broadcast_latest_holder_commitment_txn`].
4004+ ///
4005+ /// [`ChannelMonitor::broadcast_latest_holder_commitment_txn`]: crate::chain::channelmonitor::ChannelMonitor::broadcast_latest_holder_commitment_txn
39594006 pub ( crate ) fn queue_latest_holder_commitment_txn_for_broadcast < B : Deref , F : Deref , L : Deref > (
3960- & mut self , broadcaster : & B , fee_estimator : & LowerBoundedFeeEstimator < F > , logger : & WithChannelMonitor < L >
4007+ & mut self , broadcaster : & B , fee_estimator : & LowerBoundedFeeEstimator < F > , logger : & WithChannelMonitor < L > , require_funding_seen : bool ,
39614008 )
39624009 where
39634010 B :: Target : BroadcasterInterface ,
@@ -3969,6 +4016,12 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
39694016 message : "ChannelMonitor-initiated commitment transaction broadcast" . to_owned ( ) ,
39704017 } ;
39714018 let ( claimable_outpoints, _) = self . generate_claimable_outpoints_and_watch_outputs ( Some ( reason) ) ;
4019+ // In manual-broadcast mode, if `require_funding_seen` is true and we have not yet observed
4020+ // the funding transaction on-chain, do not queue any transactions.
4021+ if require_funding_seen && self . is_manual_broadcast && !self . funding_seen_onchain {
4022+ log_info ! ( logger, "Not broadcasting holder commitment for manual-broadcast channel before funding appears on-chain" ) ;
4023+ return ;
4024+ }
39724025 let conf_target = self . closure_conf_target ( ) ;
39734026 self . onchain_tx_handler . update_claims_view_from_requests (
39744027 claimable_outpoints, self . best_block . height , self . best_block . height , broadcaster,
@@ -4291,7 +4344,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
42914344 log_trace ! ( logger, "Avoiding commitment broadcast, already detected confirmed spend onchain" ) ;
42924345 continue ;
42934346 }
4294- self . queue_latest_holder_commitment_txn_for_broadcast ( broadcaster, & bounded_fee_estimator, logger) ;
4347+ self . queue_latest_holder_commitment_txn_for_broadcast ( broadcaster, & bounded_fee_estimator, logger, true ) ;
42954348 } else if !self . holder_tx_signed {
42964349 log_error ! ( logger, "WARNING: You have a potentially-unsafe holder commitment transaction available to broadcast" ) ;
42974350 log_error ! ( logger, " in channel monitor for channel {}!" , & self . channel_id( ) ) ;
@@ -5310,7 +5363,21 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
53105363 F :: Target : FeeEstimator ,
53115364 L :: Target : Logger ,
53125365 {
5366+ let funding_seen_before = self . funding_seen_onchain ;
53135367 let txn_matched = self . filter_block ( txdata) ;
5368+
5369+ if !self . funding_seen_onchain {
5370+ for & ( _, tx) in txdata. iter ( ) {
5371+ let txid = tx. compute_txid ( ) ;
5372+ if txid == self . funding . funding_txid ( ) ||
5373+ self . pending_funding . iter ( ) . any ( |f| f. funding_txid ( ) == txid)
5374+ {
5375+ self . funding_seen_onchain = true ;
5376+ break ;
5377+ }
5378+ }
5379+ }
5380+
53145381 for tx in & txn_matched {
53155382 let mut output_val = Amount :: ZERO ;
53165383 for out in tx. output . iter ( ) {
@@ -5331,6 +5398,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
53315398
53325399 let mut watch_outputs = Vec :: new ( ) ;
53335400 let mut claimable_outpoints = Vec :: new ( ) ;
5401+
5402+ if self . is_manual_broadcast && !funding_seen_before && self . funding_seen_onchain && self . holder_tx_signed
5403+ {
5404+ should_broadcast_commitment = true ;
5405+ }
53345406 ' tx_iter: for tx in & txn_matched {
53355407 let txid = tx. compute_txid ( ) ;
53365408 log_trace ! ( logger, "Transaction {} confirmed in block {}" , txid , block_hash) ;
@@ -5582,13 +5654,16 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
55825654 log_trace ! ( logger, "Processing {} matched transactions for block at height {}." , txn_matched. len( ) , conf_height) ;
55835655 debug_assert ! ( self . best_block. height >= conf_height) ;
55845656
5585- let should_broadcast = self . should_broadcast_holder_commitment_txn ( logger) ;
5586- if let Some ( payment_hash) = should_broadcast {
5587- let reason = ClosureReason :: HTLCsTimedOut { payment_hash : Some ( payment_hash) } ;
5588- let ( mut new_outpoints, mut new_outputs) =
5589- self . generate_claimable_outpoints_and_watch_outputs ( Some ( reason) ) ;
5590- claimable_outpoints. append ( & mut new_outpoints) ;
5591- watch_outputs. append ( & mut new_outputs) ;
5657+ // Only generate claims if we haven't already done so (e.g., in transactions_confirmed).
5658+ if claimable_outpoints. is_empty ( ) {
5659+ let should_broadcast = self . should_broadcast_holder_commitment_txn ( logger) ;
5660+ if let Some ( payment_hash) = should_broadcast {
5661+ let reason = ClosureReason :: HTLCsTimedOut { payment_hash : Some ( payment_hash) } ;
5662+ let ( mut new_outpoints, mut new_outputs) =
5663+ self . generate_claimable_outpoints_and_watch_outputs ( Some ( reason) ) ;
5664+ claimable_outpoints. append ( & mut new_outpoints) ;
5665+ watch_outputs. append ( & mut new_outputs) ;
5666+ }
55925667 }
55935668
55945669 // Find which on-chain events have reached their confirmation threshold.
@@ -5826,7 +5901,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
58265901 // Only attempt to broadcast the new commitment after the `block_disconnected` call above so that
58275902 // it doesn't get removed from the set of pending claims.
58285903 if should_broadcast_commitment {
5829- self . queue_latest_holder_commitment_txn_for_broadcast ( & broadcaster, & bounded_fee_estimator, logger) ;
5904+ self . queue_latest_holder_commitment_txn_for_broadcast ( & broadcaster, & bounded_fee_estimator, logger, true ) ;
58305905 }
58315906
58325907 self . best_block = fork_point;
@@ -5887,14 +5962,14 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
58875962 // Only attempt to broadcast the new commitment after the `transaction_unconfirmed` call above so
58885963 // that it doesn't get removed from the set of pending claims.
58895964 if should_broadcast_commitment {
5890- self . queue_latest_holder_commitment_txn_for_broadcast ( & broadcaster, fee_estimator, logger) ;
5965+ self . queue_latest_holder_commitment_txn_for_broadcast ( & broadcaster, fee_estimator, logger, true ) ;
58915966 }
58925967 }
58935968
58945969 /// Filters a block's `txdata` for transactions spending watched outputs or for any child
58955970 /// transactions thereof.
58965971 #[ rustfmt:: skip]
5897- fn filter_block < ' a > ( & self , txdata : & TransactionData < ' a > ) -> Vec < & ' a Transaction > {
5972+ fn filter_block < ' a > ( & mut self , txdata : & TransactionData < ' a > ) -> Vec < & ' a Transaction > {
58985973 let mut matched_txn = new_hash_set ( ) ;
58995974 txdata. iter ( ) . filter ( |& & ( _, tx) | {
59005975 let mut matches = self . spends_watched_output ( tx) ;
@@ -6560,6 +6635,8 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
65606635 let mut channel_parameters = None ;
65616636 let mut pending_funding = None ;
65626637 let mut alternative_funding_confirmed = None ;
6638+ let mut is_manual_broadcast = RequiredWrapper ( None ) ;
6639+ let mut funding_seen_onchain = RequiredWrapper ( None ) ;
65636640 read_tlv_fields ! ( reader, {
65646641 ( 1 , funding_spend_confirmed, option) ,
65656642 ( 3 , htlcs_resolved_on_chain, optional_vec) ,
@@ -6580,6 +6657,8 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
65806657 ( 32 , pending_funding, optional_vec) ,
65816658 ( 33 , htlcs_resolved_to_user, option) ,
65826659 ( 34 , alternative_funding_confirmed, option) ,
6660+ ( 35 , is_manual_broadcast, ( default_value, false ) ) ,
6661+ ( 37 , funding_seen_onchain, ( default_value, true ) ) ,
65836662 } ) ;
65846663 // Note that `payment_preimages_with_info` was added (and is always written) in LDK 0.1, so
65856664 // we can use it to determine if this monitor was last written by LDK 0.1 or later.
@@ -6693,6 +6772,10 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
66936772 prev_holder_commitment_tx,
66946773 } ,
66956774 pending_funding : pending_funding. unwrap_or ( vec ! [ ] ) ,
6775+ is_manual_broadcast : is_manual_broadcast. 0 . unwrap ( ) ,
6776+ // Older monitors prior to LDK 0.2 assume this is `true` when absent
6777+ // during upgrade so holder broadcasts aren't gated unexpectedly.
6778+ funding_seen_onchain : funding_seen_onchain. 0 . unwrap ( ) ,
66966779
66976780 latest_update_id,
66986781 commitment_transaction_number_obscure_factor,
@@ -7029,7 +7112,7 @@ mod tests {
70297112 let monitor = ChannelMonitor :: new (
70307113 Secp256k1 :: new ( ) , keys, Some ( shutdown_script. into_inner ( ) ) , 0 , & ScriptBuf :: new ( ) ,
70317114 & channel_parameters, true , 0 , HolderCommitmentTransaction :: dummy ( 0 , funding_outpoint, Vec :: new ( ) ) ,
7032- best_block, dummy_key, channel_id,
7115+ best_block, dummy_key, channel_id, false ,
70337116 ) ;
70347117
70357118 let nondust_htlcs = preimages_slice_to_htlcs ! ( preimages[ 0 ..10 ] ) ;
@@ -7290,7 +7373,7 @@ mod tests {
72907373 let monitor = ChannelMonitor :: new (
72917374 Secp256k1 :: new ( ) , keys, Some ( shutdown_script. into_inner ( ) ) , 0 , & ScriptBuf :: new ( ) ,
72927375 & channel_parameters, true , 0 , HolderCommitmentTransaction :: dummy ( 0 , funding_outpoint, Vec :: new ( ) ) ,
7293- best_block, dummy_key, channel_id,
7376+ best_block, dummy_key, channel_id, false ,
72947377 ) ;
72957378
72967379 let chan_id = monitor. inner . lock ( ) . unwrap ( ) . channel_id ( ) ;
0 commit comments