@@ -676,6 +676,9 @@ pub(crate) enum ChannelMonitorUpdateStep {
676
676
holder_commitment_tx : HolderCommitmentTransaction ,
677
677
counterparty_commitment_tx : CommitmentTransaction ,
678
678
} ,
679
+ RenegotiatedFundingLocked {
680
+ funding_txid : Txid ,
681
+ } ,
679
682
}
680
683
681
684
impl ChannelMonitorUpdateStep {
@@ -690,6 +693,7 @@ impl ChannelMonitorUpdateStep {
690
693
ChannelMonitorUpdateStep :: ChannelForceClosed { .. } => "ChannelForceClosed" ,
691
694
ChannelMonitorUpdateStep :: ShutdownScript { .. } => "ShutdownScript" ,
692
695
ChannelMonitorUpdateStep :: RenegotiatedFunding { .. } => "RenegotiatedFunding" ,
696
+ ChannelMonitorUpdateStep :: RenegotiatedFundingLocked { .. } => "RenegotiatedFundingLocked" ,
693
697
}
694
698
}
695
699
}
@@ -733,6 +737,9 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
733
737
( 3 , holder_commitment_tx, required) ,
734
738
( 5 , counterparty_commitment_tx, required) ,
735
739
} ,
740
+ ( 12 , RenegotiatedFundingLocked ) => {
741
+ ( 1 , funding_txid, required) ,
742
+ } ,
736
743
) ;
737
744
738
745
/// Indicates whether the balance is derived from a cooperative close, a force-close
@@ -1075,6 +1082,10 @@ impl FundingScope {
1075
1082
fn funding_txid ( & self ) -> Txid {
1076
1083
self . funding_outpoint ( ) . txid
1077
1084
}
1085
+
1086
+ fn is_splice ( & self ) -> bool {
1087
+ self . channel_parameters . splice_parent_funding_txid . is_some ( )
1088
+ }
1078
1089
}
1079
1090
1080
1091
impl Writeable for FundingScope {
@@ -1209,8 +1220,6 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
1209
1220
// interface knows about the TXOs that we want to be notified of spends of. We could probably
1210
1221
// be smart and derive them from the above storage fields, but its much simpler and more
1211
1222
// Obviously Correct (tm) if we just keep track of them explicitly.
1212
- //
1213
- // TODO: Remove entries for stale funding transactions on `splice_locked`.
1214
1223
outputs_to_watch : HashMap < Txid , Vec < ( u32 , ScriptBuf ) > > ,
1215
1224
1216
1225
#[ cfg( any( test, feature = "_test_utils" ) ) ]
@@ -3670,6 +3679,10 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3670
3679
) ;
3671
3680
return Err ( ( ) ) ;
3672
3681
}
3682
+ } else if self . funding . is_splice ( ) {
3683
+ // If we've already spliced at least once, we're no longer able to RBF the original
3684
+ // funding transaction.
3685
+ return Err ( ( ) ) ;
3673
3686
}
3674
3687
3675
3688
self . outputs_to_watch . insert (
@@ -3681,6 +3694,39 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3681
3694
Ok ( ( ) )
3682
3695
}
3683
3696
3697
+ fn promote_funding ( & mut self , new_funding_txid : Txid ) -> Result < ( ) , ( ) > {
3698
+ let is_pending_splice = self . pending_funding . iter ( ) . any ( |funding| funding. is_splice ( ) ) ;
3699
+
3700
+ let new_funding = self
3701
+ . pending_funding
3702
+ . iter_mut ( )
3703
+ . find ( |funding| funding. funding_txid ( ) == new_funding_txid) ;
3704
+ if new_funding. is_none ( ) {
3705
+ return Err ( ( ) ) ;
3706
+ }
3707
+ let mut new_funding = new_funding. unwrap ( ) ;
3708
+
3709
+ // `first_confirmed_funding_txo` is set to the first outpoint for the channel upon init.
3710
+ // If an RBF happens and it confirms, this will no longer be accurate, so update it now
3711
+ // if we know the RBF doesn't belong to a splice.
3712
+ if !is_pending_splice && self . first_confirmed_funding_txo == self . funding . funding_outpoint ( )
3713
+ {
3714
+ self . first_confirmed_funding_txo = new_funding. funding_outpoint ( ) ;
3715
+ }
3716
+
3717
+ mem:: swap ( & mut self . funding , & mut new_funding) ;
3718
+ self . onchain_tx_handler . update_after_renegotiated_funding_locked (
3719
+ self . funding . current_holder_commitment_tx . clone ( ) ,
3720
+ self . funding . prev_holder_commitment_tx . clone ( ) ,
3721
+ ) ;
3722
+
3723
+ for funding in self . pending_funding . drain ( ..) {
3724
+ self . outputs_to_watch . remove ( & funding. funding_txid ( ) ) ;
3725
+ }
3726
+
3727
+ Ok ( ( ) )
3728
+ }
3729
+
3684
3730
#[ rustfmt:: skip]
3685
3731
fn update_monitor < B : Deref , F : Deref , L : Deref > (
3686
3732
& mut self , updates : & ChannelMonitorUpdate , broadcaster : & B , fee_estimator : & F , logger : & WithChannelMonitor < L >
@@ -3771,6 +3817,13 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3771
3817
ret = Err ( ( ) ) ;
3772
3818
}
3773
3819
} ,
3820
+ ChannelMonitorUpdateStep :: RenegotiatedFundingLocked { funding_txid } => {
3821
+ log_trace ! ( logger, "Updating ChannelMonitor with locked renegotiated funding txid {}" , funding_txid) ;
3822
+ if let Err ( _) = self . promote_funding ( * funding_txid) {
3823
+ log_error ! ( logger, "Unknown funding with txid {} became locked" , funding_txid) ;
3824
+ ret = Err ( ( ) ) ;
3825
+ }
3826
+ } ,
3774
3827
ChannelMonitorUpdateStep :: ChannelForceClosed { should_broadcast } => {
3775
3828
log_trace ! ( logger, "Updating ChannelMonitor: channel force closed, should broadcast: {}" , should_broadcast) ;
3776
3829
self . lockdown_from_offchain = true ;
@@ -3823,7 +3876,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3823
3876
|ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTX { .. }
3824
3877
|ChannelMonitorUpdateStep :: ShutdownScript { .. }
3825
3878
|ChannelMonitorUpdateStep :: CommitmentSecret { .. }
3826
- |ChannelMonitorUpdateStep :: RenegotiatedFunding { .. } =>
3879
+ |ChannelMonitorUpdateStep :: RenegotiatedFunding { .. }
3880
+ |ChannelMonitorUpdateStep :: RenegotiatedFundingLocked { .. } =>
3827
3881
is_pre_close_update = true ,
3828
3882
// After a channel is closed, we don't communicate with our peer about it, so the
3829
3883
// only things we will update is getting a new preimage (from a different channel)
0 commit comments