@@ -496,6 +496,9 @@ impl OnchainEventEntry {
496
496
// it's broadcastable when we see the previous block.
497
497
conf_threshold = cmp:: max ( conf_threshold, self . height + csv as u32 - 1 ) ;
498
498
} ,
499
+ OnchainEvent :: AlternativeFundingConfirmation { confirmation_depth } => {
500
+ conf_threshold = cmp:: max ( conf_threshold, self . height + confirmation_depth - 1 ) ;
501
+ } ,
499
502
_ => { } ,
500
503
}
501
504
conf_threshold
@@ -565,6 +568,16 @@ enum OnchainEvent {
565
568
/// output (and generate a SpendableOutput event).
566
569
on_to_local_output_csv : Option < u16 > ,
567
570
} ,
571
+ /// An alternative funding transaction (due to a splice/RBF) has confirmed but is not yet
572
+ /// locked, invalidating the previous funding transaction. Note that we wait to promote the
573
+ /// corresponding `FundingScope` until we see a
574
+ /// [`ChannelMonitorUpdateStep::RenegotiatedFundingLocked`] or if the alternative funding
575
+ /// transaction is irrevocably confirmed.
576
+ AlternativeFundingConfirmation {
577
+ // The confirmation depth negotiated and required for the funding transaction to be
578
+ // considered locked.
579
+ confirmation_depth : u32 ,
580
+ } ,
568
581
}
569
582
570
583
impl Writeable for OnchainEventEntry {
@@ -609,6 +622,9 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
609
622
( 1 , MaturingOutput ) => {
610
623
( 0 , descriptor, required) ,
611
624
} ,
625
+ ( 2 , AlternativeFundingConfirmation ) => {
626
+ ( 1 , confirmation_depth, required) ,
627
+ } ,
612
628
( 3 , FundingSpendConfirmation ) => {
613
629
( 0 , on_local_output_csv, option) ,
614
630
( 1 , commitment_tx_to_counterparty_output, option) ,
@@ -618,7 +634,6 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
618
634
( 2 , preimage, option) ,
619
635
( 4 , on_to_local_output_csv, option) ,
620
636
} ,
621
-
622
637
) ;
623
638
624
639
#[ derive( Clone , Debug , PartialEq , Eq ) ]
@@ -677,6 +692,7 @@ pub(crate) enum ChannelMonitorUpdateStep {
677
692
channel_parameters : ChannelTransactionParameters ,
678
693
holder_commitment_tx : HolderCommitmentTransaction ,
679
694
counterparty_commitment_tx : CommitmentTransaction ,
695
+ confirmation_depth : u32 ,
680
696
} ,
681
697
RenegotiatedFundingLocked {
682
698
funding_txid : Txid ,
@@ -744,6 +760,7 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
744
760
( 1 , channel_parameters, ( required: ReadableArgs , None ) ) ,
745
761
( 3 , holder_commitment_tx, required) ,
746
762
( 5 , counterparty_commitment_tx, required) ,
763
+ ( 7 , confirmation_depth, required) ,
747
764
} ,
748
765
( 12 , RenegotiatedFundingLocked ) => {
749
766
( 1 , funding_txid, required) ,
@@ -1111,7 +1128,7 @@ impl_writeable_tlv_based!(FundingScope, {
1111
1128
#[ derive( Clone , PartialEq ) ]
1112
1129
pub ( crate ) struct ChannelMonitorImpl < Signer : EcdsaChannelSigner > {
1113
1130
funding : FundingScope ,
1114
- pending_funding : Vec < FundingScope > ,
1131
+ pending_funding : Vec < ( FundingScope , u32 ) > ,
1115
1132
1116
1133
latest_update_id : u64 ,
1117
1134
commitment_transaction_number_obscure_factor : u64 ,
@@ -1944,7 +1961,9 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
1944
1961
{
1945
1962
let lock = self . inner . lock ( ) . unwrap ( ) ;
1946
1963
let logger = WithChannelMonitor :: from_impl ( logger, & * lock, None ) ;
1947
- for funding in core:: iter:: once ( & lock. funding ) . chain ( & lock. pending_funding ) {
1964
+ for funding in core:: iter:: once ( & lock. funding )
1965
+ . chain ( lock. pending_funding . iter ( ) . map ( |pending_funding| & pending_funding. 0 ) )
1966
+ {
1948
1967
let funding_outpoint = funding. funding_outpoint ( ) ;
1949
1968
log_trace ! ( & logger, "Registering funding outpoint {} with the filter to monitor confirmations" , & funding_outpoint) ;
1950
1969
let script_pubkey = funding. channel_parameters . make_funding_redeemscript ( ) . to_p2wsh ( ) ;
@@ -3313,8 +3332,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3313
3332
current_funding_commitment_tx. per_commitment_point ( ) ,
3314
3333
) ;
3315
3334
3316
- for ( pending_funding, commitment_tx) in
3317
- self . pending_funding . iter_mut ( ) . zip ( commitment_txs. iter ( ) . skip ( 1 ) )
3335
+ for ( pending_funding, commitment_tx) in self
3336
+ . pending_funding
3337
+ . iter_mut ( )
3338
+ . map ( |pending_funding| & mut pending_funding. 0 )
3339
+ . zip ( commitment_txs. iter ( ) . skip ( 1 ) )
3318
3340
{
3319
3341
let commitment_txid = commitment_tx. trust ( ) . txid ( ) ;
3320
3342
pending_funding. prev_counterparty_commitment_txid =
@@ -3410,8 +3432,9 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3410
3432
}
3411
3433
3412
3434
let mut other_commitment_tx = None :: < & CommitmentTransaction > ;
3413
- for ( funding, commitment_tx) in
3414
- core:: iter:: once ( & self . funding ) . chain ( self . pending_funding . iter ( ) ) . zip ( commitment_txs)
3435
+ for ( funding, commitment_tx) in core:: iter:: once ( & self . funding )
3436
+ . chain ( self . pending_funding . iter ( ) . map ( |pending_funding| & pending_funding. 0 ) )
3437
+ . zip ( commitment_txs)
3415
3438
{
3416
3439
let trusted_tx = & commitment_tx. trust ( ) . built_transaction ( ) . transaction ;
3417
3440
if trusted_tx. input . len ( ) != 1 {
@@ -3466,7 +3489,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3466
3489
self . current_holder_commitment_number = current_funding_commitment_tx. commitment_number ( ) ;
3467
3490
self . onchain_tx_handler . provide_latest_holder_tx ( current_funding_commitment_tx. clone ( ) ) ;
3468
3491
for ( funding, mut commitment_tx) in core:: iter:: once ( & mut self . funding )
3469
- . chain ( self . pending_funding . iter_mut ( ) )
3492
+ . chain ( self . pending_funding . iter_mut ( ) . map ( |pending_funding| & mut pending_funding . 0 ) )
3470
3493
. zip ( commitment_txs. into_iter ( ) )
3471
3494
{
3472
3495
mem:: swap ( & mut commitment_tx, & mut funding. current_holder_commitment_tx ) ;
@@ -3674,7 +3697,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3674
3697
& mut self , logger : & WithChannelMonitor < L > ,
3675
3698
channel_parameters : & ChannelTransactionParameters ,
3676
3699
alternative_holder_commitment_tx : & HolderCommitmentTransaction ,
3677
- alternative_counterparty_commitment_tx : & CommitmentTransaction ,
3700
+ alternative_counterparty_commitment_tx : & CommitmentTransaction , confirmation_depth : u32 ,
3678
3701
) -> Result < ( ) , ( ) >
3679
3702
where
3680
3703
L :: Target : Logger ,
@@ -3750,7 +3773,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3750
3773
if self
3751
3774
. pending_funding
3752
3775
. iter ( )
3753
- . any ( |funding| funding. funding_txid ( ) == alternative_funding_outpoint. txid )
3776
+ . any ( |funding| funding. 0 . funding_txid ( ) == alternative_funding_outpoint. txid )
3754
3777
{
3755
3778
log_error ! (
3756
3779
logger,
@@ -3788,7 +3811,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3788
3811
alternative_funding_outpoint. txid ,
3789
3812
vec ! [ ( alternative_funding_outpoint. index as u32 , script_pubkey) ] ,
3790
3813
) ;
3791
- self . pending_funding . push ( alternative_funding) ;
3814
+ self . pending_funding . push ( ( alternative_funding, confirmation_depth ) ) ;
3792
3815
3793
3816
Ok ( ( ) )
3794
3817
}
@@ -3797,6 +3820,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3797
3820
let new_funding = self
3798
3821
. pending_funding
3799
3822
. iter_mut ( )
3823
+ . map ( |pending_funding| & mut pending_funding. 0 )
3800
3824
. find ( |funding| funding. funding_txid ( ) == new_funding_txid) ;
3801
3825
if new_funding. is_none ( ) {
3802
3826
return Err ( ( ) ) ;
@@ -3810,7 +3834,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3810
3834
) ;
3811
3835
3812
3836
// The swap above places the previous `FundingScope` into `pending_funding`.
3813
- for funding in self . pending_funding . drain ( ..) {
3837
+ for ( funding, _ ) in self . pending_funding . drain ( ..) {
3814
3838
self . outputs_to_watch . remove ( & funding. funding_txid ( ) ) ;
3815
3839
}
3816
3840
@@ -3926,11 +3950,13 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3926
3950
} ,
3927
3951
ChannelMonitorUpdateStep :: RenegotiatedFunding {
3928
3952
channel_parameters, holder_commitment_tx, counterparty_commitment_tx,
3953
+ confirmation_depth,
3929
3954
} => {
3930
3955
log_trace ! ( logger, "Updating ChannelMonitor with alternative holder and counterparty commitment transactions for funding txid {}" ,
3931
3956
channel_parameters. funding_outpoint. unwrap( ) . txid) ;
3932
3957
if let Err ( _) = self . renegotiated_funding (
3933
3958
logger, channel_parameters, holder_commitment_tx, counterparty_commitment_tx,
3959
+ * confirmation_depth,
3934
3960
) {
3935
3961
ret = Err ( ( ) ) ;
3936
3962
}
@@ -4871,6 +4897,51 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
4871
4897
}
4872
4898
}
4873
4899
4900
+ // A splice transaction has confirmed. We can't promote the splice's scope until we see
4901
+ // the corresponding monitor update for it, but we track the txid so we know which
4902
+ // holder commitment transaction we may need to broadcast.
4903
+ if let Some ( ( alternative_funding, confirmation_depth) ) = self . pending_funding . iter ( )
4904
+ . find ( |funding| funding. 0 . funding_txid ( ) == txid)
4905
+ {
4906
+ debug_assert ! ( self . funding_spend_confirmed. is_none( ) ) ;
4907
+ debug_assert ! (
4908
+ !self . onchain_events_awaiting_threshold_conf. iter( )
4909
+ . any( |e| matches!( e. event, OnchainEvent :: FundingSpendConfirmation { .. } ) )
4910
+ ) ;
4911
+
4912
+ let ( desc, msg) = if alternative_funding. channel_parameters . splice_parent_funding_txid . is_some ( ) {
4913
+ debug_assert ! ( tx. input. iter( ) . any( |input| {
4914
+ let funding_outpoint = self . funding. funding_outpoint( ) . into_bitcoin_outpoint( ) ;
4915
+ input. previous_output == funding_outpoint
4916
+ } ) ) ;
4917
+ ( "Splice" , "splice_locked" )
4918
+ } else {
4919
+ ( "RBF" , "channel_ready" )
4920
+ } ;
4921
+ let action = if self . no_further_updates_allowed ( ) {
4922
+ if self . holder_tx_signed {
4923
+ ", broadcasting post-splice holder commitment transaction" . to_string ( )
4924
+ } else {
4925
+ "" . to_string ( )
4926
+ }
4927
+ } else {
4928
+ format ! ( ", waiting for `{}` exchange" , msg)
4929
+ } ;
4930
+ log_info ! ( logger, "{desc} for channel {} confirmed with txid {txid}{action}" , self . channel_id( ) ) ;
4931
+
4932
+ self . onchain_events_awaiting_threshold_conf . push ( OnchainEventEntry {
4933
+ txid,
4934
+ transaction : Some ( ( * tx) . clone ( ) ) ,
4935
+ height,
4936
+ block_hash : Some ( block_hash) ,
4937
+ event : OnchainEvent :: AlternativeFundingConfirmation {
4938
+ confirmation_depth : * confirmation_depth,
4939
+ } ,
4940
+ } ) ;
4941
+
4942
+ continue ' tx_iter;
4943
+ }
4944
+
4874
4945
if tx. input . len ( ) == 1 {
4875
4946
// Assuming our keys were not leaked (in which case we're screwed no matter what),
4876
4947
// commitment transactions and HTLC transactions will all only ever have one input
@@ -5002,7 +5073,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
5002
5073
let unmatured_htlcs: Vec < _ > = self . onchain_events_awaiting_threshold_conf
5003
5074
. iter ( )
5004
5075
. filter_map ( |entry| match & entry. event {
5005
- OnchainEvent :: HTLCUpdate { source, .. } => Some ( source) ,
5076
+ OnchainEvent :: HTLCUpdate { source, .. } => Some ( source. clone ( ) ) ,
5006
5077
_ => None ,
5007
5078
} )
5008
5079
. collect ( ) ;
@@ -5017,7 +5088,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
5017
5088
#[ cfg( debug_assertions) ]
5018
5089
{
5019
5090
debug_assert ! (
5020
- !unmatured_htlcs. contains( && source) ,
5091
+ !unmatured_htlcs. contains( & source) ,
5021
5092
"An unmature HTLC transaction conflicts with a maturing one; failed to \
5022
5093
call either transaction_unconfirmed for the conflicting transaction \
5023
5094
or block_disconnected for a block containing it.") ;
@@ -5064,6 +5135,21 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
5064
5135
self . funding_spend_confirmed = Some ( entry. txid ) ;
5065
5136
self . confirmed_commitment_tx_counterparty_output = commitment_tx_to_counterparty_output;
5066
5137
} ,
5138
+ OnchainEvent :: AlternativeFundingConfirmation { .. } => {
5139
+ // An alternative funding transaction has irrevocably confirmed. Locate the
5140
+ // corresponding scope and promote it if the monitor is no longer allowing
5141
+ // updates. Otherwise, we expect it to be promoted via
5142
+ // [`ChannelMonitorUpdateStep::RenegotiatedFundingLocked`].
5143
+ if self . no_further_updates_allowed ( ) {
5144
+ let funding_txid = entry. transaction
5145
+ . expect ( "Transactions are always present for AlternativeFundingConfirmation entries" )
5146
+ . compute_txid ( ) ;
5147
+ debug_assert_ne ! ( self . funding. funding_txid( ) , funding_txid) ;
5148
+ if let Err ( _) = self . promote_funding ( funding_txid) {
5149
+ log_error ! ( logger, "Missing scope for alternative funding confirmation with txid {}" , entry. txid) ;
5150
+ }
5151
+ }
5152
+ } ,
5067
5153
}
5068
5154
}
5069
5155
0 commit comments