@@ -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,39 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
36813694 Ok ( ( ) )
36823695 }
36833696
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+
36843730 #[ rustfmt:: skip]
36853731 fn update_monitor < B : Deref , F : Deref , L : Deref > (
36863732 & mut self , updates : & ChannelMonitorUpdate , broadcaster : & B , fee_estimator : & F , logger : & WithChannelMonitor < L >
@@ -3771,6 +3817,13 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
37713817 ret = Err ( ( ) ) ;
37723818 }
37733819 } ,
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+ } ,
37743827 ChannelMonitorUpdateStep :: ChannelForceClosed { should_broadcast } => {
37753828 log_trace ! ( logger, "Updating ChannelMonitor: channel force closed, should broadcast: {}" , should_broadcast) ;
37763829 self . lockdown_from_offchain = true ;
@@ -3823,7 +3876,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
38233876 |ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTX { .. }
38243877 |ChannelMonitorUpdateStep :: ShutdownScript { .. }
38253878 |ChannelMonitorUpdateStep :: CommitmentSecret { .. }
3826- |ChannelMonitorUpdateStep :: RenegotiatedFunding { .. } =>
3879+ |ChannelMonitorUpdateStep :: RenegotiatedFunding { .. }
3880+ |ChannelMonitorUpdateStep :: RenegotiatedFundingLocked { .. } =>
38273881 is_pre_close_update = true ,
38283882 // After a channel is closed, we don't communicate with our peer about it, so the
38293883 // only things we will update is getting a new preimage (from a different channel)
0 commit comments