@@ -640,6 +640,11 @@ pub(crate) enum ChannelMonitorUpdateStep {
640640 ShutdownScript {
641641 scriptpubkey : ScriptBuf ,
642642 } ,
643+ RenegotiatedFunding {
644+ channel_parameters : ChannelTransactionParameters ,
645+ holder_commitment_tx : HolderCommitmentTransaction ,
646+ counterparty_commitment_tx : CommitmentTransaction ,
647+ } ,
643648}
644649
645650impl ChannelMonitorUpdateStep {
@@ -653,6 +658,7 @@ impl ChannelMonitorUpdateStep {
653658 ChannelMonitorUpdateStep :: CommitmentSecret { .. } => "CommitmentSecret" ,
654659 ChannelMonitorUpdateStep :: ChannelForceClosed { .. } => "ChannelForceClosed" ,
655660 ChannelMonitorUpdateStep :: ShutdownScript { .. } => "ShutdownScript" ,
661+ ChannelMonitorUpdateStep :: RenegotiatedFunding { .. } => "RenegotiatedFunding" ,
656662 }
657663 }
658664}
@@ -691,6 +697,11 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
691697 ( 0 , htlc_outputs, required_vec) ,
692698 ( 2 , commitment_tx, required) ,
693699 } ,
700+ ( 10 , RenegotiatedFunding ) => {
701+ ( 1 , channel_parameters, ( required: ReadableArgs , None ) ) ,
702+ ( 3 , holder_commitment_tx, required) ,
703+ ( 5 , counterparty_commitment_tx, required) ,
704+ } ,
694705) ;
695706
696707/// Indicates whether the balance is derived from a cooperative close, a force-close
@@ -1024,9 +1035,69 @@ struct FundingScope {
10241035 prev_holder_commitment_tx : Option < HolderCommitmentTransaction > ,
10251036}
10261037
1038+ impl FundingScope {
1039+ fn funding_outpoint ( & self ) -> OutPoint {
1040+ let funding_outpoint = self . channel_parameters . funding_outpoint . as_ref ( ) ;
1041+ * funding_outpoint. expect ( "Funding outpoint must be set for active monitor" )
1042+ }
1043+
1044+ fn funding_txid ( & self ) -> Txid {
1045+ self . funding_outpoint ( ) . txid
1046+ }
1047+ }
1048+
1049+ impl Writeable for FundingScope {
1050+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
1051+ write_tlv_fields ! ( w, {
1052+ ( 1 , self . channel_parameters, ( required: ReadableArgs , None ) ) ,
1053+ ( 3 , self . current_counterparty_commitment_txid, required) ,
1054+ ( 5 , self . prev_counterparty_commitment_txid, option) ,
1055+ ( 7 , self . current_holder_commitment_tx, required) ,
1056+ ( 9 , self . prev_holder_commitment_tx, option) ,
1057+ ( 11 , self . counterparty_claimable_outpoints, required) ,
1058+ } ) ;
1059+ Ok ( ( ) )
1060+ }
1061+ }
1062+
1063+ impl Readable for FundingScope {
1064+ fn read < R : io:: Read > ( r : & mut R ) -> Result < Self , DecodeError > {
1065+ let mut channel_parameters = RequiredWrapper ( None ) ;
1066+ let mut current_counterparty_commitment_txid = RequiredWrapper ( None ) ;
1067+ let mut prev_counterparty_commitment_txid = None ;
1068+ let mut current_holder_commitment_tx = RequiredWrapper ( None ) ;
1069+ let mut prev_holder_commitment_tx = None ;
1070+ let mut counterparty_claimable_outpoints = RequiredWrapper ( None ) ;
1071+
1072+ read_tlv_fields ! ( r, {
1073+ ( 1 , channel_parameters, ( required: ReadableArgs , None ) ) ,
1074+ ( 3 , current_counterparty_commitment_txid, required) ,
1075+ ( 5 , prev_counterparty_commitment_txid, option) ,
1076+ ( 7 , current_holder_commitment_tx, required) ,
1077+ ( 9 , prev_holder_commitment_tx, option) ,
1078+ ( 11 , counterparty_claimable_outpoints, required) ,
1079+ } ) ;
1080+
1081+ let channel_parameters: ChannelTransactionParameters = channel_parameters. 0 . unwrap ( ) ;
1082+ let redeem_script = channel_parameters. make_funding_redeemscript ( ) ;
1083+
1084+ Ok ( Self {
1085+ script_pubkey : redeem_script. to_p2wsh ( ) ,
1086+ redeem_script,
1087+ channel_parameters,
1088+ current_counterparty_commitment_txid : current_counterparty_commitment_txid. 0 . unwrap ( ) ,
1089+ prev_counterparty_commitment_txid,
1090+ current_holder_commitment_tx : current_holder_commitment_tx. 0 . unwrap ( ) ,
1091+ prev_holder_commitment_tx,
1092+ counterparty_claimable_outpoints : counterparty_claimable_outpoints. 0 . unwrap ( ) ,
1093+ } )
1094+ }
1095+ }
1096+
10271097#[ derive( Clone , PartialEq ) ]
10281098pub ( crate ) struct ChannelMonitorImpl < Signer : EcdsaChannelSigner > {
10291099 funding : FundingScope ,
1100+ pending_funding : Vec < FundingScope > ,
10301101
10311102 latest_update_id : u64 ,
10321103 commitment_transaction_number_obscure_factor : u64 ,
@@ -1467,6 +1538,7 @@ impl<Signer: EcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
14671538 ( 27 , self . first_confirmed_funding_txo, required) ,
14681539 ( 29 , self . initial_counterparty_commitment_tx, option) ,
14691540 ( 31 , self . funding. channel_parameters, required) ,
1541+ ( 32 , self . pending_funding, optional_vec) ,
14701542 } ) ;
14711543
14721544 Ok ( ( ) )
@@ -1636,6 +1708,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
16361708 current_holder_commitment_tx : initial_holder_commitment_tx,
16371709 prev_holder_commitment_tx : None ,
16381710 } ,
1711+ pending_funding : vec ! [ ] ,
16391712
16401713 latest_update_id : 0 ,
16411714 commitment_transaction_number_obscure_factor,
@@ -1862,14 +1935,16 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
18621935 {
18631936 let lock = self . inner . lock ( ) . unwrap ( ) ;
18641937 let logger = WithChannelMonitor :: from_impl ( logger, & * lock, None ) ;
1865- log_trace ! ( & logger, "Registering funding outpoint {}" , & lock. get_funding_txo( ) ) ;
1866- let funding_outpoint = lock. get_funding_txo ( ) ;
1867- filter. register_tx ( & funding_outpoint. txid , & lock. funding . script_pubkey ) ;
1938+ for funding in core:: iter:: once ( & lock. funding ) . chain ( & lock. pending_funding ) {
1939+ let funding_outpoint = funding. funding_outpoint ( ) ;
1940+ log_trace ! ( & logger, "Registering funding outpoint {} with the filter to monitor confirmations" , & funding_outpoint) ;
1941+ filter. register_tx ( & funding_outpoint. txid , & funding. script_pubkey ) ;
1942+ }
18681943 for ( txid, outputs) in lock. get_outputs_to_watch ( ) . iter ( ) {
18691944 for ( index, script_pubkey) in outputs. iter ( ) {
18701945 assert ! ( * index <= u16 :: MAX as u32 ) ;
18711946 let outpoint = OutPoint { txid : * txid, index : * index as u16 } ;
1872- log_trace ! ( logger, "Registering outpoint {} with the filter for monitoring spends " , outpoint) ;
1947+ log_trace ! ( logger, "Registering outpoint {} with the filter to monitor spend " , outpoint) ;
18731948 filter. register_output ( WatchedOutput {
18741949 block_hash : None ,
18751950 outpoint,
@@ -3453,6 +3528,109 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34533528 ) ;
34543529 }
34553530
3531+ fn renegotiated_funding < L : Deref > (
3532+ & mut self , logger : & WithChannelMonitor < L > ,
3533+ channel_parameters : & ChannelTransactionParameters ,
3534+ alternative_holder_commitment_tx : & HolderCommitmentTransaction ,
3535+ alternative_counterparty_commitment_tx : & CommitmentTransaction ,
3536+ ) -> Result < ( ) , ( ) >
3537+ where
3538+ L :: Target : Logger ,
3539+ {
3540+ let redeem_script = channel_parameters. make_funding_redeemscript ( ) ;
3541+ let script_pubkey = redeem_script. to_p2wsh ( ) ;
3542+ let alternative_counterparty_commitment_txid =
3543+ alternative_counterparty_commitment_tx. trust ( ) . txid ( ) ;
3544+
3545+ // Both the current counterparty commitment and the alternative one share the same set of
3546+ // non-dust and dust HTLCs in the same order, though the index of each non-dust HTLC may be
3547+ // different.
3548+ //
3549+ // We clone all HTLCs and their sources to use in the alternative funding scope, and update
3550+ // each non-dust HTLC with their corresponding index in the alternative counterparty
3551+ // commitment.
3552+ let current_counterparty_commitment_htlcs =
3553+ if let Some ( txid) = & self . funding . current_counterparty_commitment_txid {
3554+ self . funding . counterparty_claimable_outpoints . get ( txid) . unwrap ( )
3555+ } else {
3556+ debug_assert ! ( false ) ;
3557+ log_error ! (
3558+ logger,
3559+ "Received funding renegotiation while initial funding negotiation is still pending"
3560+ ) ;
3561+ return Err ( ( ) ) ;
3562+ } ;
3563+ let mut htlcs_with_sources = current_counterparty_commitment_htlcs. clone ( ) ;
3564+ let alternative_htlcs = alternative_counterparty_commitment_tx. nondust_htlcs ( ) ;
3565+ // The left side only tracks non-dust, while the right side tracks dust as well.
3566+ debug_assert ! ( alternative_htlcs. len( ) <= current_counterparty_commitment_htlcs. len( ) ) ;
3567+ for ( alternative_htlc, ( htlc, _) ) in
3568+ alternative_htlcs. iter ( ) . zip ( htlcs_with_sources. iter_mut ( ) )
3569+ {
3570+ debug_assert ! ( htlc. transaction_output_index. is_some( ) ) ;
3571+ debug_assert ! ( alternative_htlc. transaction_output_index. is_some( ) ) ;
3572+ debug_assert ! ( alternative_htlc. is_data_equal( htlc) ) ;
3573+ htlc. transaction_output_index = alternative_htlc. transaction_output_index ;
3574+ }
3575+
3576+ let mut counterparty_claimable_outpoints = new_hash_map ( ) ;
3577+ counterparty_claimable_outpoints
3578+ . insert ( alternative_counterparty_commitment_txid, htlcs_with_sources) ;
3579+
3580+ // TODO(splicing): Enforce any necessary RBF validity checks.
3581+ let alternative_funding = FundingScope {
3582+ script_pubkey : script_pubkey. clone ( ) ,
3583+ redeem_script,
3584+ channel_parameters : channel_parameters. clone ( ) ,
3585+ current_counterparty_commitment_txid : Some ( alternative_counterparty_commitment_txid) ,
3586+ prev_counterparty_commitment_txid : None ,
3587+ counterparty_claimable_outpoints,
3588+ current_holder_commitment_tx : alternative_holder_commitment_tx. clone ( ) ,
3589+ prev_holder_commitment_tx : None ,
3590+ } ;
3591+ let alternative_funding_outpoint = alternative_funding. funding_outpoint ( ) ;
3592+
3593+ if self
3594+ . pending_funding
3595+ . iter ( )
3596+ . any ( |funding| funding. funding_txid ( ) == alternative_funding_outpoint. txid )
3597+ {
3598+ log_error ! (
3599+ logger,
3600+ "Renegotiated funding transaction with a duplicate funding txid {}" ,
3601+ alternative_funding_outpoint. txid
3602+ ) ;
3603+ return Err ( ( ) ) ;
3604+ }
3605+
3606+ if let Some ( parent_funding_txid) = channel_parameters. splice_parent_funding_txid . as_ref ( ) {
3607+ // Only one splice can be negotiated at a time after we've exchanged `channel_ready`
3608+ // (implying our funding is confirmed) that spends our currently locked funding.
3609+ if !self . pending_funding . is_empty ( ) {
3610+ log_error ! (
3611+ logger,
3612+ "Negotiated splice while channel is pending channel_ready/splice_locked"
3613+ ) ;
3614+ return Err ( ( ) ) ;
3615+ }
3616+ if * parent_funding_txid != self . funding . funding_txid ( ) {
3617+ log_error ! (
3618+ logger,
3619+ "Negotiated splice that does not spend currently locked funding transaction"
3620+ ) ;
3621+ return Err ( ( ) ) ;
3622+ }
3623+ }
3624+
3625+ self . outputs_to_watch . insert (
3626+ alternative_funding_outpoint. txid ,
3627+ vec ! [ ( alternative_funding_outpoint. index as u32 , script_pubkey) ] ,
3628+ ) ;
3629+ self . pending_funding . push ( alternative_funding) ;
3630+
3631+ Ok ( ( ) )
3632+ }
3633+
34563634 #[ rustfmt:: skip]
34573635 fn update_monitor < B : Deref , F : Deref , L : Deref > (
34583636 & mut self , updates : & ChannelMonitorUpdate , broadcaster : & B , fee_estimator : & F , logger : & WithChannelMonitor < L >
@@ -3532,6 +3710,17 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
35323710 ret = Err ( ( ) ) ;
35333711 }
35343712 } ,
3713+ ChannelMonitorUpdateStep :: RenegotiatedFunding {
3714+ channel_parameters, holder_commitment_tx, counterparty_commitment_tx,
3715+ } => {
3716+ log_trace ! ( logger, "Updating ChannelMonitor with alternative holder and counterparty commitment transactions for funding txid {}" ,
3717+ channel_parameters. funding_outpoint. unwrap( ) . txid) ;
3718+ if let Err ( _) = self . renegotiated_funding (
3719+ logger, channel_parameters, holder_commitment_tx, counterparty_commitment_tx,
3720+ ) {
3721+ ret = Err ( ( ) ) ;
3722+ }
3723+ } ,
35353724 ChannelMonitorUpdateStep :: ChannelForceClosed { should_broadcast } => {
35363725 log_trace ! ( logger, "Updating ChannelMonitor: channel force closed, should broadcast: {}" , should_broadcast) ;
35373726 self . lockdown_from_offchain = true ;
@@ -3583,7 +3772,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
35833772 |ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTXInfo { .. }
35843773 |ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTX { .. }
35853774 |ChannelMonitorUpdateStep :: ShutdownScript { .. }
3586- |ChannelMonitorUpdateStep :: CommitmentSecret { .. } =>
3775+ |ChannelMonitorUpdateStep :: CommitmentSecret { .. }
3776+ |ChannelMonitorUpdateStep :: RenegotiatedFunding { .. } =>
35873777 is_pre_close_update = true ,
35883778 // After a channel is closed, we don't communicate with our peer about it, so the
35893779 // only things we will update is getting a new preimage (from a different channel)
@@ -3765,6 +3955,9 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
37653955 } => {
37663956 Some ( commitment_tx. clone ( ) )
37673957 } ,
3958+ & ChannelMonitorUpdateStep :: RenegotiatedFunding { ref counterparty_commitment_tx, .. } => {
3959+ Some ( counterparty_commitment_tx. clone ( ) )
3960+ } ,
37683961 _ => None ,
37693962 }
37703963 } ) . collect ( )
@@ -5438,6 +5631,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
54385631 let mut payment_preimages_with_info: Option < HashMap < _ , _ > > = None ;
54395632 let mut first_confirmed_funding_txo = RequiredWrapper ( None ) ;
54405633 let mut channel_parameters = None ;
5634+ let mut pending_funding = None ;
54415635 read_tlv_fields ! ( reader, {
54425636 ( 1 , funding_spend_confirmed, option) ,
54435637 ( 3 , htlcs_resolved_on_chain, optional_vec) ,
@@ -5455,6 +5649,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
54555649 ( 27 , first_confirmed_funding_txo, ( default_value, outpoint) ) ,
54565650 ( 29 , initial_counterparty_commitment_tx, option) ,
54575651 ( 31 , channel_parameters, ( option: ReadableArgs , None ) ) ,
5652+ ( 32 , pending_funding, optional_vec) ,
54585653 } ) ;
54595654 if let Some ( payment_preimages_with_info) = payment_preimages_with_info {
54605655 if payment_preimages_with_info. len ( ) != payment_preimages. len ( ) {
@@ -5570,6 +5765,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
55705765 current_holder_commitment_tx,
55715766 prev_holder_commitment_tx,
55725767 } ,
5768+ pending_funding : pending_funding. unwrap_or ( vec ! [ ] ) ,
55735769
55745770 latest_update_id,
55755771 commitment_transaction_number_obscure_factor,
0 commit comments