@@ -676,6 +676,9 @@ pub(crate) enum ChannelMonitorUpdateStep {
676676 holder_commitment_tx : HolderCommitmentTransaction ,
677677 counterparty_commitment_tx : CommitmentTransaction ,
678678 } ,
679+ RenegotiatedFundingLocked {
680+ funding_txid : Txid ,
681+ } ,
679682}
680683
681684impl ChannelMonitorUpdateStep {
@@ -690,6 +693,7 @@ impl ChannelMonitorUpdateStep {
690693 ChannelMonitorUpdateStep :: ChannelForceClosed { .. } => "ChannelForceClosed" ,
691694 ChannelMonitorUpdateStep :: ShutdownScript { .. } => "ShutdownScript" ,
692695 ChannelMonitorUpdateStep :: RenegotiatedFunding { .. } => "RenegotiatedFunding" ,
696+ ChannelMonitorUpdateStep :: RenegotiatedFundingLocked { .. } => "RenegotiatedFundingLocked" ,
693697 }
694698 }
695699}
@@ -733,6 +737,9 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
733737 ( 3 , holder_commitment_tx, required) ,
734738 ( 5 , counterparty_commitment_tx, required) ,
735739 } ,
740+ ( 12 , RenegotiatedFundingLocked ) => {
741+ ( 1 , funding_txid, required) ,
742+ } ,
736743) ;
737744
738745/// Indicates whether the balance is derived from a cooperative close, a force-close
@@ -1075,6 +1082,10 @@ impl FundingScope {
10751082 fn funding_txid ( & self ) -> Txid {
10761083 self . funding_outpoint ( ) . txid
10771084 }
1085+
1086+ fn is_splice ( & self ) -> bool {
1087+ self . channel_parameters . splice_parent_funding_txid . is_some ( )
1088+ }
10781089}
10791090
10801091impl Writeable for FundingScope {
@@ -1209,8 +1220,6 @@ pub(crate) struct ChannelMonitorImpl<Signer: EcdsaChannelSigner> {
12091220 // interface knows about the TXOs that we want to be notified of spends of. We could probably
12101221 // be smart and derive them from the above storage fields, but its much simpler and more
12111222 // Obviously Correct (tm) if we just keep track of them explicitly.
1212- //
1213- // TODO: Remove entries for stale funding transactions on `splice_locked`.
12141223 outputs_to_watch : HashMap < Txid , Vec < ( u32 , ScriptBuf ) > > ,
12151224
12161225 #[ cfg( any( test, feature = "_test_utils" ) ) ]
@@ -3670,6 +3679,10 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
36703679 ) ;
36713680 return Err ( ( ) ) ;
36723681 }
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 ( ( ) ) ;
36733686 }
36743687
36753688 self . outputs_to_watch . insert (
@@ -3681,6 +3694,30 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
36813694 Ok ( ( ) )
36823695 }
36833696
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+
36843721 #[ rustfmt:: skip]
36853722 fn update_monitor < B : Deref , F : Deref , L : Deref > (
36863723 & mut self , updates : & ChannelMonitorUpdate , broadcaster : & B , fee_estimator : & F , logger : & WithChannelMonitor < L >
@@ -3771,6 +3808,13 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
37713808 ret = Err ( ( ) ) ;
37723809 }
37733810 } ,
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+ } ,
37743818 ChannelMonitorUpdateStep :: ChannelForceClosed { should_broadcast } => {
37753819 log_trace ! ( logger, "Updating ChannelMonitor: channel force closed, should broadcast: {}" , should_broadcast) ;
37763820 self . lockdown_from_offchain = true ;
@@ -3823,7 +3867,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
38233867 |ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTX { .. }
38243868 |ChannelMonitorUpdateStep :: ShutdownScript { .. }
38253869 |ChannelMonitorUpdateStep :: CommitmentSecret { .. }
3826- |ChannelMonitorUpdateStep :: RenegotiatedFunding { .. } =>
3870+ |ChannelMonitorUpdateStep :: RenegotiatedFunding { .. }
3871+ |ChannelMonitorUpdateStep :: RenegotiatedFundingLocked { .. } =>
38273872 is_pre_close_update = true ,
38283873 // After a channel is closed, we don't communicate with our peer about it, so the
38293874 // only things we will update is getting a new preimage (from a different channel)
0 commit comments