@@ -1166,6 +1166,14 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
1166
1166
/// The node_id of our counterparty
1167
1167
counterparty_node_id : PublicKey ,
1168
1168
1169
+ /// Controls whether the monitor is allowed to automatically broadcast the latest holder commitment transaction.
1170
+ ///
1171
+ /// This flag is set to `false` when a channel is force-closed with `should_broadcast: false`,
1172
+ /// indicating that broadcasting the latest holder commitment transaction would be unsafe.
1173
+ ///
1174
+ /// Default: `true`.
1175
+ allow_automated_broadcast : bool ,
1176
+
1169
1177
/// Initial counterparty commmitment data needed to recreate the commitment tx
1170
1178
/// in the persistence pipeline for third-party watchtowers. This will only be present on
1171
1179
/// monitors created after 0.0.117.
@@ -1467,6 +1475,7 @@ impl<Signer: EcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
1467
1475
( 27 , self . first_confirmed_funding_txo, required) ,
1468
1476
( 29 , self . initial_counterparty_commitment_tx, option) ,
1469
1477
( 31 , self . funding. channel_parameters, required) ,
1478
+ ( 33 , self . allow_automated_broadcast, required) ,
1470
1479
} ) ;
1471
1480
1472
1481
Ok ( ( ) )
@@ -1684,6 +1693,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
1684
1693
1685
1694
best_block,
1686
1695
counterparty_node_id : counterparty_node_id,
1696
+ allow_automated_broadcast : true ,
1687
1697
initial_counterparty_commitment_info : None ,
1688
1698
initial_counterparty_commitment_tx : None ,
1689
1699
balances_empty_height : None ,
@@ -2038,7 +2048,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
2038
2048
/// may be to contact the other node operator out-of-band to coordinate other options available
2039
2049
/// to you.
2040
2050
#[ rustfmt:: skip]
2041
- pub fn broadcast_latest_holder_commitment_txn < B : Deref , F : Deref , L : Deref > (
2051
+ pub fn force_broadcast_latest_holder_commitment_txn_unsafe < B : Deref , F : Deref , L : Deref > (
2042
2052
& self , broadcaster : & B , fee_estimator : & F , logger : & L
2043
2053
)
2044
2054
where
@@ -3453,6 +3463,32 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3453
3463
) ;
3454
3464
}
3455
3465
3466
+ fn maybe_broadcast_latest_holder_commitment_txn < B : Deref , F : Deref , L : Deref > (
3467
+ & mut self , broadcaster : & B , fee_estimator : & LowerBoundedFeeEstimator < F > ,
3468
+ logger : & WithChannelMonitor < L > ,
3469
+ ) where
3470
+ B :: Target : BroadcasterInterface ,
3471
+ F :: Target : FeeEstimator ,
3472
+ L :: Target : Logger ,
3473
+ {
3474
+ if !self . allow_automated_broadcast {
3475
+ return ;
3476
+ }
3477
+ let detected_funding_spend = self . funding_spend_confirmed . is_some ( )
3478
+ || self
3479
+ . onchain_events_awaiting_threshold_conf
3480
+ . iter ( )
3481
+ . any ( |event| matches ! ( event. event, OnchainEvent :: FundingSpendConfirmation { .. } ) ) ;
3482
+ if detected_funding_spend {
3483
+ log_trace ! (
3484
+ logger,
3485
+ "Avoiding commitment broadcast, already detected confirmed spend onchain"
3486
+ ) ;
3487
+ return ;
3488
+ }
3489
+ self . queue_latest_holder_commitment_txn_for_broadcast ( broadcaster, fee_estimator, logger) ;
3490
+ }
3491
+
3456
3492
#[ rustfmt:: skip]
3457
3493
fn update_monitor < B : Deref , F : Deref , L : Deref > (
3458
3494
& mut self , updates : & ChannelMonitorUpdate , broadcaster : & B , fee_estimator : & F , logger : & WithChannelMonitor < L >
@@ -3535,28 +3571,16 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3535
3571
ChannelMonitorUpdateStep :: ChannelForceClosed { should_broadcast } => {
3536
3572
log_trace ! ( logger, "Updating ChannelMonitor: channel force closed, should broadcast: {}" , should_broadcast) ;
3537
3573
self . lockdown_from_offchain = true ;
3538
- if * should_broadcast {
3539
- // There's no need to broadcast our commitment transaction if we've seen one
3540
- // confirmed (even with 1 confirmation) as it'll be rejected as
3541
- // duplicate/conflicting.
3542
- let detected_funding_spend = self . funding_spend_confirmed . is_some ( ) ||
3543
- self . onchain_events_awaiting_threshold_conf . iter ( ) . any (
3544
- |event| matches ! ( event. event, OnchainEvent :: FundingSpendConfirmation { .. } ) ) ;
3545
- if detected_funding_spend {
3546
- log_trace ! ( logger, "Avoiding commitment broadcast, already detected confirmed spend onchain" ) ;
3547
- continue ;
3548
- }
3549
- self . queue_latest_holder_commitment_txn_for_broadcast ( broadcaster, & bounded_fee_estimator, logger) ;
3550
- } else if !self . holder_tx_signed {
3551
- log_error ! ( logger, "WARNING: You have a potentially-unsafe holder commitment transaction available to broadcast" ) ;
3552
- log_error ! ( logger, " in channel monitor for channel {}!" , & self . channel_id( ) ) ;
3553
- log_error ! ( logger, " Read the docs for ChannelMonitor::broadcast_latest_holder_commitment_txn to take manual action!" ) ;
3554
- } else {
3574
+ if self . allow_automated_broadcast {
3575
+ self . allow_automated_broadcast = * should_broadcast;
3576
+ }
3577
+ if !* should_broadcast && self . holder_tx_signed {
3555
3578
// If we generated a MonitorEvent::HolderForceClosed, the ChannelManager
3556
3579
// will still give us a ChannelForceClosed event with !should_broadcast, but we
3557
3580
// shouldn't print the scary warning above.
3558
3581
log_info ! ( logger, "Channel off-chain state closed after we broadcasted our latest commitment transaction." ) ;
3559
3582
}
3583
+ self . maybe_broadcast_latest_holder_commitment_txn ( broadcaster, & bounded_fee_estimator, logger) ;
3560
3584
} ,
3561
3585
ChannelMonitorUpdateStep :: ShutdownScript { scriptpubkey } => {
3562
3586
log_trace ! ( logger, "Updating ChannelMonitor with shutdown script" ) ;
@@ -5438,6 +5462,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
5438
5462
let mut payment_preimages_with_info: Option < HashMap < _ , _ > > = None ;
5439
5463
let mut first_confirmed_funding_txo = RequiredWrapper ( None ) ;
5440
5464
let mut channel_parameters = None ;
5465
+ let mut allow_automated_broadcast = None ;
5441
5466
read_tlv_fields ! ( reader, {
5442
5467
( 1 , funding_spend_confirmed, option) ,
5443
5468
( 3 , htlcs_resolved_on_chain, optional_vec) ,
@@ -5455,6 +5480,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
5455
5480
( 27 , first_confirmed_funding_txo, ( default_value, outpoint) ) ,
5456
5481
( 29 , initial_counterparty_commitment_tx, option) ,
5457
5482
( 31 , channel_parameters, ( option: ReadableArgs , None ) ) ,
5483
+ ( 33 , allow_automated_broadcast, option) ,
5458
5484
} ) ;
5459
5485
if let Some ( payment_preimages_with_info) = payment_preimages_with_info {
5460
5486
if payment_preimages_with_info. len ( ) != payment_preimages. len ( ) {
@@ -5618,6 +5644,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
5618
5644
5619
5645
best_block,
5620
5646
counterparty_node_id : counterparty_node_id. unwrap ( ) ,
5647
+ allow_automated_broadcast : allow_automated_broadcast. unwrap_or ( true ) ,
5621
5648
initial_counterparty_commitment_info,
5622
5649
initial_counterparty_commitment_tx,
5623
5650
balances_empty_height,
0 commit comments