@@ -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,30 @@ 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 new_funding = self
3699
+ . pending_funding
3700
+ . iter_mut ( )
3701
+ . find ( |funding| funding. funding_txid ( ) == new_funding_txid) ;
3702
+ if new_funding. is_none ( ) {
3703
+ return Err ( ( ) ) ;
3704
+ }
3705
+ let mut new_funding = new_funding. unwrap ( ) ;
3706
+
3707
+ mem:: swap ( & mut self . funding , & mut new_funding) ;
3708
+ self . onchain_tx_handler . update_after_renegotiated_funding_locked (
3709
+ self . funding . current_holder_commitment_tx . clone ( ) ,
3710
+ self . funding . prev_holder_commitment_tx . clone ( ) ,
3711
+ ) ;
3712
+
3713
+ // The swap above places the previous `FundingScope` into `pending_funding`.
3714
+ for funding in self . pending_funding . drain ( ..) {
3715
+ self . outputs_to_watch . remove ( & funding. funding_txid ( ) ) ;
3716
+ }
3717
+
3718
+ Ok ( ( ) )
3719
+ }
3720
+
3684
3721
#[ rustfmt:: skip]
3685
3722
fn update_monitor < B : Deref , F : Deref , L : Deref > (
3686
3723
& mut self , updates : & ChannelMonitorUpdate , broadcaster : & B , fee_estimator : & F , logger : & WithChannelMonitor < L >
@@ -3771,6 +3808,13 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3771
3808
ret = Err ( ( ) ) ;
3772
3809
}
3773
3810
} ,
3811
+ ChannelMonitorUpdateStep :: RenegotiatedFundingLocked { funding_txid } => {
3812
+ log_trace ! ( logger, "Updating ChannelMonitor with locked renegotiated funding txid {}" , funding_txid) ;
3813
+ if let Err ( _) = self . promote_funding ( * funding_txid) {
3814
+ log_error ! ( logger, "Unknown funding with txid {} became locked" , funding_txid) ;
3815
+ ret = Err ( ( ) ) ;
3816
+ }
3817
+ } ,
3774
3818
ChannelMonitorUpdateStep :: ChannelForceClosed { should_broadcast } => {
3775
3819
log_trace ! ( logger, "Updating ChannelMonitor: channel force closed, should broadcast: {}" , should_broadcast) ;
3776
3820
self . lockdown_from_offchain = true ;
@@ -3823,7 +3867,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3823
3867
|ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTX { .. }
3824
3868
|ChannelMonitorUpdateStep :: ShutdownScript { .. }
3825
3869
|ChannelMonitorUpdateStep :: CommitmentSecret { .. }
3826
- |ChannelMonitorUpdateStep :: RenegotiatedFunding { .. } =>
3870
+ |ChannelMonitorUpdateStep :: RenegotiatedFunding { .. }
3871
+ |ChannelMonitorUpdateStep :: RenegotiatedFundingLocked { .. } =>
3827
3872
is_pre_close_update = true ,
3828
3873
// After a channel is closed, we don't communicate with our peer about it, so the
3829
3874
// only things we will update is getting a new preimage (from a different channel)
0 commit comments