@@ -678,6 +678,9 @@ pub(crate) enum ChannelMonitorUpdateStep {
678
678
holder_commitment_tx : HolderCommitmentTransaction ,
679
679
counterparty_commitment_tx : CommitmentTransaction ,
680
680
} ,
681
+ RenegotiatedFundingLocked {
682
+ funding_txid : Txid ,
683
+ } ,
681
684
}
682
685
683
686
impl ChannelMonitorUpdateStep {
@@ -693,6 +696,7 @@ impl ChannelMonitorUpdateStep {
693
696
ChannelMonitorUpdateStep :: ChannelForceClosed { .. } => "ChannelForceClosed" ,
694
697
ChannelMonitorUpdateStep :: ShutdownScript { .. } => "ShutdownScript" ,
695
698
ChannelMonitorUpdateStep :: RenegotiatedFunding { .. } => "RenegotiatedFunding" ,
699
+ ChannelMonitorUpdateStep :: RenegotiatedFundingLocked { .. } => "RenegotiatedFundingLocked" ,
696
700
}
697
701
}
698
702
}
@@ -741,6 +745,9 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
741
745
( 3 , holder_commitment_tx, required) ,
742
746
( 5 , counterparty_commitment_tx, required) ,
743
747
} ,
748
+ ( 12 , RenegotiatedFundingLocked ) => {
749
+ ( 1 , funding_txid, required) ,
750
+ } ,
744
751
) ;
745
752
746
753
/// Indicates whether the balance is derived from a cooperative close, a force-close
@@ -1086,6 +1093,10 @@ impl FundingScope {
1086
1093
fn funding_txid ( & self ) -> Txid {
1087
1094
self . funding_outpoint ( ) . txid
1088
1095
}
1096
+
1097
+ fn is_splice ( & self ) -> bool {
1098
+ self . channel_parameters . splice_parent_funding_txid . is_some ( )
1099
+ }
1089
1100
}
1090
1101
1091
1102
impl_writeable_tlv_based ! ( FundingScope , {
@@ -1181,8 +1192,6 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
1181
1192
// interface knows about the TXOs that we want to be notified of spends of. We could probably
1182
1193
// be smart and derive them from the above storage fields, but its much simpler and more
1183
1194
// Obviously Correct (tm) if we just keep track of them explicitly.
1184
- //
1185
- // TODO: Remove entries for stale funding transactions on `splice_locked`.
1186
1195
outputs_to_watch : HashMap < Txid , Vec < ( u32 , ScriptBuf ) > > ,
1187
1196
1188
1197
#[ cfg( any( test, feature = "_test_utils" ) ) ]
@@ -3768,6 +3777,10 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3768
3777
) ;
3769
3778
return Err ( ( ) ) ;
3770
3779
}
3780
+ } else if self . funding . is_splice ( ) {
3781
+ // If we've already spliced at least once, we're no longer able to RBF the original
3782
+ // funding transaction.
3783
+ return Err ( ( ) ) ;
3771
3784
}
3772
3785
3773
3786
let script_pubkey = channel_parameters. make_funding_redeemscript ( ) . to_p2wsh ( ) ;
@@ -3780,6 +3793,30 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3780
3793
Ok ( ( ) )
3781
3794
}
3782
3795
3796
+ fn promote_funding ( & mut self , new_funding_txid : Txid ) -> Result < ( ) , ( ) > {
3797
+ let new_funding = self
3798
+ . pending_funding
3799
+ . iter_mut ( )
3800
+ . find ( |funding| funding. funding_txid ( ) == new_funding_txid) ;
3801
+ if new_funding. is_none ( ) {
3802
+ return Err ( ( ) ) ;
3803
+ }
3804
+ let mut new_funding = new_funding. unwrap ( ) ;
3805
+
3806
+ mem:: swap ( & mut self . funding , & mut new_funding) ;
3807
+ self . onchain_tx_handler . update_after_renegotiated_funding_locked (
3808
+ self . funding . current_holder_commitment_tx . clone ( ) ,
3809
+ self . funding . prev_holder_commitment_tx . clone ( ) ,
3810
+ ) ;
3811
+
3812
+ // The swap above places the previous `FundingScope` into `pending_funding`.
3813
+ for funding in self . pending_funding . drain ( ..) {
3814
+ self . outputs_to_watch . remove ( & funding. funding_txid ( ) ) ;
3815
+ }
3816
+
3817
+ Ok ( ( ) )
3818
+ }
3819
+
3783
3820
#[ rustfmt:: skip]
3784
3821
fn update_monitor < B : Deref , F : Deref , L : Deref > (
3785
3822
& mut self , updates : & ChannelMonitorUpdate , broadcaster : & B , fee_estimator : & F , logger : & WithChannelMonitor < L >
@@ -3898,6 +3935,13 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3898
3935
ret = Err ( ( ) ) ;
3899
3936
}
3900
3937
} ,
3938
+ ChannelMonitorUpdateStep :: RenegotiatedFundingLocked { funding_txid } => {
3939
+ log_trace ! ( logger, "Updating ChannelMonitor with locked renegotiated funding txid {}" , funding_txid) ;
3940
+ if let Err ( _) = self . promote_funding ( * funding_txid) {
3941
+ log_error ! ( logger, "Unknown funding with txid {} became locked" , funding_txid) ;
3942
+ ret = Err ( ( ) ) ;
3943
+ }
3944
+ } ,
3901
3945
ChannelMonitorUpdateStep :: ChannelForceClosed { should_broadcast } => {
3902
3946
log_trace ! ( logger, "Updating ChannelMonitor: channel force closed, should broadcast: {}" , should_broadcast) ;
3903
3947
self . lockdown_from_offchain = true ;
@@ -3951,7 +3995,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3951
3995
|ChannelMonitorUpdateStep :: LatestCounterpartyCommitment { .. }
3952
3996
|ChannelMonitorUpdateStep :: ShutdownScript { .. }
3953
3997
|ChannelMonitorUpdateStep :: CommitmentSecret { .. }
3954
- |ChannelMonitorUpdateStep :: RenegotiatedFunding { .. } =>
3998
+ |ChannelMonitorUpdateStep :: RenegotiatedFunding { .. }
3999
+ |ChannelMonitorUpdateStep :: RenegotiatedFundingLocked { .. } =>
3955
4000
is_pre_close_update = true ,
3956
4001
// After a channel is closed, we don't communicate with our peer about it, so the
3957
4002
// only things we will update is getting a new preimage (from a different channel)
0 commit comments