@@ -2666,18 +2666,59 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
2666
2666
}
2667
2667
}
2668
2668
2669
- fn broadcast_latest_holder_commitment_txn < B : Deref , L : Deref > ( & mut self , broadcaster : & B , logger : & WithChannelMonitor < L > )
2670
- where B :: Target : BroadcasterInterface ,
2671
- L :: Target : Logger ,
2672
- {
2673
- let commit_txs = self . get_latest_holder_commitment_txn ( logger) ;
2674
- let mut txs = vec ! [ ] ;
2675
- for tx in commit_txs. iter ( ) {
2676
- log_info ! ( logger, "Broadcasting local {}" , log_tx!( tx) ) ;
2677
- txs. push ( tx) ;
2678
- }
2679
- broadcaster. broadcast_transactions ( & txs) ;
2669
+ fn generate_claimable_outpoints_and_watch_outputs ( & mut self ) -> ( Vec < PackageTemplate > , Vec < TransactionOutputs > ) {
2670
+ let funding_outp = HolderFundingOutput :: build (
2671
+ self . funding_redeemscript . clone ( ) ,
2672
+ self . channel_value_satoshis ,
2673
+ self . onchain_tx_handler . channel_type_features ( ) . clone ( )
2674
+ ) ;
2675
+ let commitment_package = PackageTemplate :: build_package (
2676
+ self . funding_info . 0 . txid . clone ( ) , self . funding_info . 0 . index as u32 ,
2677
+ PackageSolvingData :: HolderFundingOutput ( funding_outp) ,
2678
+ self . best_block . height ( ) , self . best_block . height ( )
2679
+ ) ;
2680
+ let mut claimable_outpoints = vec ! [ commitment_package] ;
2680
2681
self . pending_monitor_events . push ( MonitorEvent :: HolderForceClosed ( self . funding_info . 0 ) ) ;
2682
+ // Although we aren't signing the transaction directly here, the transaction will be signed
2683
+ // in the claim that is queued to OnchainTxHandler. We set holder_tx_signed here to reject
2684
+ // new channel updates.
2685
+ self . holder_tx_signed = true ;
2686
+ let mut watch_outputs = Vec :: new ( ) ;
2687
+ // We can't broadcast our HTLC transactions while the commitment transaction is
2688
+ // unconfirmed. We'll delay doing so until we detect the confirmed commitment in
2689
+ // `transactions_confirmed`.
2690
+ if !self . onchain_tx_handler . channel_type_features ( ) . supports_anchors_zero_fee_htlc_tx ( ) {
2691
+ // Because we're broadcasting a commitment transaction, we should construct the package
2692
+ // assuming it gets confirmed in the next block. Sadly, we have code which considers
2693
+ // "not yet confirmed" things as discardable, so we cannot do that here.
2694
+ let ( mut new_outpoints, _) = self . get_broadcasted_holder_claims (
2695
+ & self . current_holder_commitment_tx , self . best_block . height ( )
2696
+ ) ;
2697
+ let unsigned_commitment_tx = self . onchain_tx_handler . get_unsigned_holder_commitment_tx ( ) ;
2698
+ let new_outputs = self . get_broadcasted_holder_watch_outputs (
2699
+ & self . current_holder_commitment_tx , & unsigned_commitment_tx
2700
+ ) ;
2701
+ if !new_outputs. is_empty ( ) {
2702
+ watch_outputs. push ( ( self . current_holder_commitment_tx . txid . clone ( ) , new_outputs) ) ;
2703
+ }
2704
+ claimable_outpoints. append ( & mut new_outpoints) ;
2705
+ }
2706
+ ( claimable_outpoints, watch_outputs)
2707
+ }
2708
+
2709
+ pub ( crate ) fn queue_latest_holder_commitment_txn_for_broadcast < B : Deref , F : Deref , L : Deref > (
2710
+ & mut self , broadcaster : & B , fee_estimator : & LowerBoundedFeeEstimator < F > , logger : & WithChannelMonitor < L >
2711
+ )
2712
+ where
2713
+ B :: Target : BroadcasterInterface ,
2714
+ F :: Target : FeeEstimator ,
2715
+ L :: Target : Logger ,
2716
+ {
2717
+ let ( claimable_outpoints, _) = self . generate_claimable_outpoints_and_watch_outputs ( ) ;
2718
+ self . onchain_tx_handler . update_claims_view_from_requests (
2719
+ claimable_outpoints, self . best_block . height ( ) , self . best_block . height ( ) , broadcaster,
2720
+ fee_estimator, logger
2721
+ ) ;
2681
2722
}
2682
2723
2683
2724
fn update_monitor < B : Deref , F : Deref , L : Deref > (
@@ -2767,26 +2808,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
2767
2808
log_trace ! ( logger, "Avoiding commitment broadcast, already detected confirmed spend onchain" ) ;
2768
2809
continue ;
2769
2810
}
2770
- self . broadcast_latest_holder_commitment_txn ( broadcaster, logger) ;
2771
- // If the channel supports anchor outputs, we'll need to emit an external
2772
- // event to be consumed such that a child transaction is broadcast with a
2773
- // high enough feerate for the parent commitment transaction to confirm.
2774
- if self . onchain_tx_handler . channel_type_features ( ) . supports_anchors_zero_fee_htlc_tx ( ) {
2775
- let funding_output = HolderFundingOutput :: build (
2776
- self . funding_redeemscript . clone ( ) , self . channel_value_satoshis ,
2777
- self . onchain_tx_handler . channel_type_features ( ) . clone ( ) ,
2778
- ) ;
2779
- let best_block_height = self . best_block . height ( ) ;
2780
- let commitment_package = PackageTemplate :: build_package (
2781
- self . funding_info . 0 . txid . clone ( ) , self . funding_info . 0 . index as u32 ,
2782
- PackageSolvingData :: HolderFundingOutput ( funding_output) ,
2783
- best_block_height, best_block_height
2784
- ) ;
2785
- self . onchain_tx_handler . update_claims_view_from_requests (
2786
- vec ! [ commitment_package] , best_block_height, best_block_height,
2787
- broadcaster, & bounded_fee_estimator, logger,
2788
- ) ;
2789
- }
2811
+ self . queue_latest_holder_commitment_txn_for_broadcast ( broadcaster, & bounded_fee_estimator, logger) ;
2790
2812
} else if !self . holder_tx_signed {
2791
2813
log_error ! ( logger, "WARNING: You have a potentially-unsafe holder commitment transaction available to broadcast" ) ;
2792
2814
log_error ! ( logger, " in channel monitor for channel {}!" , & self . funding_info. 0 . to_channel_id( ) ) ;
@@ -3363,6 +3385,58 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3363
3385
}
3364
3386
}
3365
3387
3388
+ /// Cancels any existing pending claims for a commitment that previously confirmed and has now
3389
+ /// been replaced by another.
3390
+ pub fn cancel_prev_commitment_claims < L : Deref > (
3391
+ & mut self , logger : & L , confirmed_commitment_txid : & Txid
3392
+ ) where L :: Target : Logger {
3393
+ for ( counterparty_commitment_txid, _) in & self . counterparty_commitment_txn_on_chain {
3394
+ // Cancel any pending claims for counterparty commitments we've seen confirm.
3395
+ if counterparty_commitment_txid == confirmed_commitment_txid {
3396
+ continue ;
3397
+ }
3398
+ for ( htlc, _) in self . counterparty_claimable_outpoints . get ( counterparty_commitment_txid) . unwrap_or ( & vec ! [ ] ) {
3399
+ log_trace ! ( logger, "Canceling claims for previously confirmed counterparty commitment {}" ,
3400
+ counterparty_commitment_txid) ;
3401
+ let mut outpoint = BitcoinOutPoint { txid : * counterparty_commitment_txid, vout : 0 } ;
3402
+ if let Some ( vout) = htlc. transaction_output_index {
3403
+ outpoint. vout = vout;
3404
+ self . onchain_tx_handler . abandon_claim ( & outpoint) ;
3405
+ }
3406
+ }
3407
+ }
3408
+ if self . holder_tx_signed {
3409
+ // If we've signed, we may have broadcast either commitment (prev or current), and
3410
+ // attempted to claim from it immediately without waiting for a confirmation.
3411
+ if self . current_holder_commitment_tx . txid != * confirmed_commitment_txid {
3412
+ log_trace ! ( logger, "Canceling claims for previously broadcast holder commitment {}" ,
3413
+ self . current_holder_commitment_tx. txid) ;
3414
+ let mut outpoint = BitcoinOutPoint { txid : self . current_holder_commitment_tx . txid , vout : 0 } ;
3415
+ for ( htlc, _, _) in & self . current_holder_commitment_tx . htlc_outputs {
3416
+ if let Some ( vout) = htlc. transaction_output_index {
3417
+ outpoint. vout = vout;
3418
+ self . onchain_tx_handler . abandon_claim ( & outpoint) ;
3419
+ }
3420
+ }
3421
+ }
3422
+ if let Some ( prev_holder_commitment_tx) = & self . prev_holder_signed_commitment_tx {
3423
+ if prev_holder_commitment_tx. txid != * confirmed_commitment_txid {
3424
+ log_trace ! ( logger, "Canceling claims for previously broadcast holder commitment {}" ,
3425
+ prev_holder_commitment_tx. txid) ;
3426
+ let mut outpoint = BitcoinOutPoint { txid : prev_holder_commitment_tx. txid , vout : 0 } ;
3427
+ for ( htlc, _, _) in & prev_holder_commitment_tx. htlc_outputs {
3428
+ if let Some ( vout) = htlc. transaction_output_index {
3429
+ outpoint. vout = vout;
3430
+ self . onchain_tx_handler . abandon_claim ( & outpoint) ;
3431
+ }
3432
+ }
3433
+ }
3434
+ }
3435
+ } else {
3436
+ // No previous claim.
3437
+ }
3438
+ }
3439
+
3366
3440
fn get_latest_holder_commitment_txn < L : Deref > (
3367
3441
& mut self , logger : & WithChannelMonitor < L > ,
3368
3442
) -> Vec < Transaction > where L :: Target : Logger {
@@ -3578,6 +3652,10 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3578
3652
commitment_tx_to_counterparty_output,
3579
3653
} ,
3580
3654
} ) ;
3655
+ // Now that we've detected a confirmed commitment transaction, attempt to cancel
3656
+ // pending claims for any commitments that were previously confirmed such that
3657
+ // we don't continue claiming inputs that no longer exist.
3658
+ self . cancel_prev_commitment_claims ( & logger, & txid) ;
3581
3659
}
3582
3660
}
3583
3661
if tx. input . len ( ) >= 1 {
@@ -3643,29 +3721,9 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3643
3721
3644
3722
let should_broadcast = self . should_broadcast_holder_commitment_txn ( logger) ;
3645
3723
if should_broadcast {
3646
- let funding_outp = HolderFundingOutput :: build ( self . funding_redeemscript . clone ( ) , self . channel_value_satoshis , self . onchain_tx_handler . channel_type_features ( ) . clone ( ) ) ;
3647
- let commitment_package = PackageTemplate :: build_package ( self . funding_info . 0 . txid . clone ( ) , self . funding_info . 0 . index as u32 , PackageSolvingData :: HolderFundingOutput ( funding_outp) , self . best_block . height ( ) , self . best_block . height ( ) ) ;
3648
- claimable_outpoints. push ( commitment_package) ;
3649
- self . pending_monitor_events . push ( MonitorEvent :: HolderForceClosed ( self . funding_info . 0 ) ) ;
3650
- // Although we aren't signing the transaction directly here, the transaction will be signed
3651
- // in the claim that is queued to OnchainTxHandler. We set holder_tx_signed here to reject
3652
- // new channel updates.
3653
- self . holder_tx_signed = true ;
3654
- // We can't broadcast our HTLC transactions while the commitment transaction is
3655
- // unconfirmed. We'll delay doing so until we detect the confirmed commitment in
3656
- // `transactions_confirmed`.
3657
- if !self . onchain_tx_handler . channel_type_features ( ) . supports_anchors_zero_fee_htlc_tx ( ) {
3658
- // Because we're broadcasting a commitment transaction, we should construct the package
3659
- // assuming it gets confirmed in the next block. Sadly, we have code which considers
3660
- // "not yet confirmed" things as discardable, so we cannot do that here.
3661
- let ( mut new_outpoints, _) = self . get_broadcasted_holder_claims ( & self . current_holder_commitment_tx , self . best_block . height ( ) ) ;
3662
- let unsigned_commitment_tx = self . onchain_tx_handler . get_unsigned_holder_commitment_tx ( ) ;
3663
- let new_outputs = self . get_broadcasted_holder_watch_outputs ( & self . current_holder_commitment_tx , & unsigned_commitment_tx) ;
3664
- if !new_outputs. is_empty ( ) {
3665
- watch_outputs. push ( ( self . current_holder_commitment_tx . txid . clone ( ) , new_outputs) ) ;
3666
- }
3667
- claimable_outpoints. append ( & mut new_outpoints) ;
3668
- }
3724
+ let ( mut new_outpoints, mut new_outputs) = self . generate_claimable_outpoints_and_watch_outputs ( ) ;
3725
+ claimable_outpoints. append ( & mut new_outpoints) ;
3726
+ watch_outputs. append ( & mut new_outputs) ;
3669
3727
}
3670
3728
3671
3729
// Find which on-chain events have reached their confirmation threshold.
0 commit comments