@@ -113,6 +113,23 @@ pub struct ChannelMonitorUpdate {
113
113
pub channel_id : Option < ChannelId > ,
114
114
}
115
115
116
+ impl ChannelMonitorUpdate {
117
+ /// Returns an iterator of new (funding outpoint, funding script) to monitor the chain for as
118
+ /// a result of a renegotiated funding transaction.
119
+ pub fn renegotiated_funding_data ( & self ) -> impl Iterator < Item = ( OutPoint , ScriptBuf ) > + ' _ {
120
+ self . updates . iter ( ) . filter_map ( |update| match update {
121
+ ChannelMonitorUpdateStep :: RenegotiatedFunding { channel_parameters, .. } => {
122
+ let funding_outpoint = channel_parameters
123
+ . funding_outpoint
124
+ . expect ( "Renegotiated funding must always have known outpoint" ) ;
125
+ let funding_script = channel_parameters. make_funding_redeemscript ( ) . to_p2wsh ( ) ;
126
+ Some ( ( funding_outpoint, funding_script) )
127
+ } ,
128
+ _ => None ,
129
+ } )
130
+ }
131
+ }
132
+
116
133
/// LDK prior to 0.1 used this constant as the [`ChannelMonitorUpdate::update_id`] for any
117
134
/// [`ChannelMonitorUpdate`]s which were generated after the channel was closed.
118
135
const LEGACY_CLOSED_CHANNEL_UPDATE_ID : u64 = u64:: MAX ;
@@ -640,6 +657,11 @@ pub(crate) enum ChannelMonitorUpdateStep {
640
657
ShutdownScript {
641
658
scriptpubkey : ScriptBuf ,
642
659
} ,
660
+ RenegotiatedFunding {
661
+ channel_parameters : ChannelTransactionParameters ,
662
+ holder_commitment_tx : HolderCommitmentTransaction ,
663
+ counterparty_commitment_tx : CommitmentTransaction ,
664
+ } ,
643
665
}
644
666
645
667
impl ChannelMonitorUpdateStep {
@@ -653,6 +675,7 @@ impl ChannelMonitorUpdateStep {
653
675
ChannelMonitorUpdateStep :: CommitmentSecret { .. } => "CommitmentSecret" ,
654
676
ChannelMonitorUpdateStep :: ChannelForceClosed { .. } => "ChannelForceClosed" ,
655
677
ChannelMonitorUpdateStep :: ShutdownScript { .. } => "ShutdownScript" ,
678
+ ChannelMonitorUpdateStep :: RenegotiatedFunding { .. } => "RenegotiatedFunding" ,
656
679
}
657
680
}
658
681
}
@@ -691,6 +714,11 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
691
714
( 0 , htlc_outputs, required_vec) ,
692
715
( 2 , commitment_tx, required) ,
693
716
} ,
717
+ ( 10 , RenegotiatedFunding ) => {
718
+ ( 1 , channel_parameters, ( required: ReadableArgs , None ) ) ,
719
+ ( 3 , holder_commitment_tx, required) ,
720
+ ( 5 , counterparty_commitment_tx, required) ,
721
+ } ,
694
722
) ;
695
723
696
724
/// Indicates whether the balance is derived from a cooperative close, a force-close
@@ -1024,9 +1052,69 @@ struct FundingScope {
1024
1052
prev_holder_commitment_tx : Option < HolderCommitmentTransaction > ,
1025
1053
}
1026
1054
1055
+ impl FundingScope {
1056
+ fn funding_outpoint ( & self ) -> OutPoint {
1057
+ let funding_outpoint = self . channel_parameters . funding_outpoint . as_ref ( ) ;
1058
+ * funding_outpoint. expect ( "Funding outpoint must be set for active monitor" )
1059
+ }
1060
+
1061
+ fn funding_txid ( & self ) -> Txid {
1062
+ self . funding_outpoint ( ) . txid
1063
+ }
1064
+ }
1065
+
1066
+ impl Writeable for FundingScope {
1067
+ fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
1068
+ write_tlv_fields ! ( w, {
1069
+ ( 1 , self . channel_parameters, ( required: ReadableArgs , None ) ) ,
1070
+ ( 3 , self . current_counterparty_commitment_txid, required) ,
1071
+ ( 5 , self . prev_counterparty_commitment_txid, option) ,
1072
+ ( 7 , self . current_holder_commitment_tx, required) ,
1073
+ ( 9 , self . prev_holder_commitment_tx, option) ,
1074
+ ( 11 , self . counterparty_claimable_outpoints, required) ,
1075
+ } ) ;
1076
+ Ok ( ( ) )
1077
+ }
1078
+ }
1079
+
1080
+ impl Readable for FundingScope {
1081
+ fn read < R : io:: Read > ( r : & mut R ) -> Result < Self , DecodeError > {
1082
+ let mut channel_parameters = RequiredWrapper ( None ) ;
1083
+ let mut current_counterparty_commitment_txid = RequiredWrapper ( None ) ;
1084
+ let mut prev_counterparty_commitment_txid = None ;
1085
+ let mut current_holder_commitment_tx = RequiredWrapper ( None ) ;
1086
+ let mut prev_holder_commitment_tx = None ;
1087
+ let mut counterparty_claimable_outpoints = RequiredWrapper ( None ) ;
1088
+
1089
+ read_tlv_fields ! ( r, {
1090
+ ( 1 , channel_parameters, ( required: ReadableArgs , None ) ) ,
1091
+ ( 3 , current_counterparty_commitment_txid, required) ,
1092
+ ( 5 , prev_counterparty_commitment_txid, option) ,
1093
+ ( 7 , current_holder_commitment_tx, required) ,
1094
+ ( 9 , prev_holder_commitment_tx, option) ,
1095
+ ( 11 , counterparty_claimable_outpoints, required) ,
1096
+ } ) ;
1097
+
1098
+ let channel_parameters: ChannelTransactionParameters = channel_parameters. 0 . unwrap ( ) ;
1099
+ let redeem_script = channel_parameters. make_funding_redeemscript ( ) ;
1100
+
1101
+ Ok ( Self {
1102
+ script_pubkey : redeem_script. to_p2wsh ( ) ,
1103
+ redeem_script,
1104
+ channel_parameters,
1105
+ current_counterparty_commitment_txid : current_counterparty_commitment_txid. 0 . unwrap ( ) ,
1106
+ prev_counterparty_commitment_txid,
1107
+ current_holder_commitment_tx : current_holder_commitment_tx. 0 . unwrap ( ) ,
1108
+ prev_holder_commitment_tx,
1109
+ counterparty_claimable_outpoints : counterparty_claimable_outpoints. 0 . unwrap ( ) ,
1110
+ } )
1111
+ }
1112
+ }
1113
+
1027
1114
#[ derive( Clone , PartialEq ) ]
1028
1115
pub ( crate ) struct ChannelMonitorImpl < Signer : EcdsaChannelSigner > {
1029
1116
funding : FundingScope ,
1117
+ pending_funding : Vec < FundingScope > ,
1030
1118
1031
1119
latest_update_id : u64 ,
1032
1120
commitment_transaction_number_obscure_factor : u64 ,
@@ -1467,6 +1555,7 @@ impl<Signer: EcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signer> {
1467
1555
( 27 , self . first_confirmed_funding_txo, required) ,
1468
1556
( 29 , self . initial_counterparty_commitment_tx, option) ,
1469
1557
( 31 , self . funding. channel_parameters, required) ,
1558
+ ( 32 , self . pending_funding, optional_vec) ,
1470
1559
} ) ;
1471
1560
1472
1561
Ok ( ( ) )
@@ -1636,6 +1725,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
1636
1725
current_holder_commitment_tx : initial_holder_commitment_tx,
1637
1726
prev_holder_commitment_tx : None ,
1638
1727
} ,
1728
+ pending_funding : vec ! [ ] ,
1639
1729
1640
1730
latest_update_id : 0 ,
1641
1731
commitment_transaction_number_obscure_factor,
@@ -1862,14 +1952,16 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
1862
1952
{
1863
1953
let lock = self . inner . lock ( ) . unwrap ( ) ;
1864
1954
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 ) ;
1955
+ for funding in core:: iter:: once ( & lock. funding ) . chain ( & lock. pending_funding ) {
1956
+ let funding_outpoint = funding. funding_outpoint ( ) ;
1957
+ log_trace ! ( & logger, "Registering funding outpoint {} with the filter to monitor confirmations" , & funding_outpoint) ;
1958
+ filter. register_tx ( & funding_outpoint. txid , & funding. script_pubkey ) ;
1959
+ }
1868
1960
for ( txid, outputs) in lock. get_outputs_to_watch ( ) . iter ( ) {
1869
1961
for ( index, script_pubkey) in outputs. iter ( ) {
1870
1962
assert ! ( * index <= u16 :: MAX as u32 ) ;
1871
1963
let outpoint = OutPoint { txid : * txid, index : * index as u16 } ;
1872
- log_trace ! ( logger, "Registering outpoint {} with the filter for monitoring spends " , outpoint) ;
1964
+ log_trace ! ( logger, "Registering outpoint {} with the filter to monitor spend " , outpoint) ;
1873
1965
filter. register_output ( WatchedOutput {
1874
1966
block_hash : None ,
1875
1967
outpoint,
@@ -3453,6 +3545,126 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3453
3545
) ;
3454
3546
}
3455
3547
3548
+ fn renegotiated_funding < L : Deref > (
3549
+ & mut self , logger : & WithChannelMonitor < L > ,
3550
+ channel_parameters : & ChannelTransactionParameters ,
3551
+ alternative_holder_commitment_tx : & HolderCommitmentTransaction ,
3552
+ alternative_counterparty_commitment_tx : & CommitmentTransaction ,
3553
+ ) -> Result < ( ) , ( ) >
3554
+ where
3555
+ L :: Target : Logger ,
3556
+ {
3557
+ let redeem_script = channel_parameters. make_funding_redeemscript ( ) ;
3558
+ let script_pubkey = redeem_script. to_p2wsh ( ) ;
3559
+ let alternative_counterparty_commitment_txid =
3560
+ alternative_counterparty_commitment_tx. trust ( ) . txid ( ) ;
3561
+
3562
+ // Both the current counterparty commitment and the alternative one share the same set of
3563
+ // non-dust and dust HTLCs in the same order, though the index of each non-dust HTLC may be
3564
+ // different.
3565
+ //
3566
+ // We clone all HTLCs and their sources to use in the alternative funding scope, and update
3567
+ // each non-dust HTLC with their corresponding index in the alternative counterparty
3568
+ // commitment.
3569
+ let current_counterparty_commitment_htlcs =
3570
+ if let Some ( txid) = & self . funding . current_counterparty_commitment_txid {
3571
+ self . funding . counterparty_claimable_outpoints . get ( txid) . unwrap ( )
3572
+ } else {
3573
+ debug_assert ! ( false ) ;
3574
+ log_error ! (
3575
+ logger,
3576
+ "Received funding renegotiation while initial funding negotiation is still pending"
3577
+ ) ;
3578
+ return Err ( ( ) ) ;
3579
+ } ;
3580
+ let mut htlcs_with_sources = current_counterparty_commitment_htlcs. clone ( ) ;
3581
+ let alternative_htlcs = alternative_counterparty_commitment_tx. nondust_htlcs ( ) ;
3582
+
3583
+ let expected_non_dust_htlc_count = htlcs_with_sources
3584
+ . iter ( )
3585
+ . filter ( |( htlc, _) | htlc. transaction_output_index . is_some ( ) )
3586
+ . count ( ) ;
3587
+ if alternative_htlcs. len ( ) != expected_non_dust_htlc_count {
3588
+ log_error ! (
3589
+ logger,
3590
+ "Received alternative counterparty commitment with HTLC count mismatch"
3591
+ ) ;
3592
+ return Err ( ( ) ) ;
3593
+ }
3594
+
3595
+ for ( alternative_htlc, ( htlc, _) ) in
3596
+ alternative_htlcs. iter ( ) . zip ( htlcs_with_sources. iter_mut ( ) )
3597
+ {
3598
+ debug_assert ! ( htlc. transaction_output_index. is_some( ) ) ;
3599
+ debug_assert ! ( alternative_htlc. transaction_output_index. is_some( ) ) ;
3600
+ if !alternative_htlc. is_data_equal ( htlc) {
3601
+ log_error ! (
3602
+ logger,
3603
+ "Received alternative counterparty commitment with non-dust HTLC mismatch"
3604
+ ) ;
3605
+ return Err ( ( ) ) ;
3606
+ }
3607
+ htlc. transaction_output_index = alternative_htlc. transaction_output_index ;
3608
+ }
3609
+
3610
+ let mut counterparty_claimable_outpoints = new_hash_map ( ) ;
3611
+ counterparty_claimable_outpoints
3612
+ . insert ( alternative_counterparty_commitment_txid, htlcs_with_sources) ;
3613
+
3614
+ // TODO(splicing): Enforce any necessary RBF validity checks.
3615
+ let alternative_funding = FundingScope {
3616
+ script_pubkey : script_pubkey. clone ( ) ,
3617
+ redeem_script,
3618
+ channel_parameters : channel_parameters. clone ( ) ,
3619
+ current_counterparty_commitment_txid : Some ( alternative_counterparty_commitment_txid) ,
3620
+ prev_counterparty_commitment_txid : None ,
3621
+ counterparty_claimable_outpoints,
3622
+ current_holder_commitment_tx : alternative_holder_commitment_tx. clone ( ) ,
3623
+ prev_holder_commitment_tx : None ,
3624
+ } ;
3625
+ let alternative_funding_outpoint = alternative_funding. funding_outpoint ( ) ;
3626
+
3627
+ if self
3628
+ . pending_funding
3629
+ . iter ( )
3630
+ . any ( |funding| funding. funding_txid ( ) == alternative_funding_outpoint. txid )
3631
+ {
3632
+ log_error ! (
3633
+ logger,
3634
+ "Renegotiated funding transaction with a duplicate funding txid {}" ,
3635
+ alternative_funding_outpoint. txid
3636
+ ) ;
3637
+ return Err ( ( ) ) ;
3638
+ }
3639
+
3640
+ if let Some ( parent_funding_txid) = channel_parameters. splice_parent_funding_txid . as_ref ( ) {
3641
+ // Only one splice can be negotiated at a time after we've exchanged `channel_ready`
3642
+ // (implying our funding is confirmed) that spends our currently locked funding.
3643
+ if !self . pending_funding . is_empty ( ) {
3644
+ log_error ! (
3645
+ logger,
3646
+ "Negotiated splice while channel is pending channel_ready/splice_locked"
3647
+ ) ;
3648
+ return Err ( ( ) ) ;
3649
+ }
3650
+ if * parent_funding_txid != self . funding . funding_txid ( ) {
3651
+ log_error ! (
3652
+ logger,
3653
+ "Negotiated splice that does not spend currently locked funding transaction"
3654
+ ) ;
3655
+ return Err ( ( ) ) ;
3656
+ }
3657
+ }
3658
+
3659
+ self . outputs_to_watch . insert (
3660
+ alternative_funding_outpoint. txid ,
3661
+ vec ! [ ( alternative_funding_outpoint. index as u32 , script_pubkey) ] ,
3662
+ ) ;
3663
+ self . pending_funding . push ( alternative_funding) ;
3664
+
3665
+ Ok ( ( ) )
3666
+ }
3667
+
3456
3668
#[ rustfmt:: skip]
3457
3669
fn update_monitor < B : Deref , F : Deref , L : Deref > (
3458
3670
& mut self , updates : & ChannelMonitorUpdate , broadcaster : & B , fee_estimator : & F , logger : & WithChannelMonitor < L >
@@ -3532,6 +3744,17 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3532
3744
ret = Err ( ( ) ) ;
3533
3745
}
3534
3746
} ,
3747
+ ChannelMonitorUpdateStep :: RenegotiatedFunding {
3748
+ channel_parameters, holder_commitment_tx, counterparty_commitment_tx,
3749
+ } => {
3750
+ log_trace ! ( logger, "Updating ChannelMonitor with alternative holder and counterparty commitment transactions for funding txid {}" ,
3751
+ channel_parameters. funding_outpoint. unwrap( ) . txid) ;
3752
+ if let Err ( _) = self . renegotiated_funding (
3753
+ logger, channel_parameters, holder_commitment_tx, counterparty_commitment_tx,
3754
+ ) {
3755
+ ret = Err ( ( ) ) ;
3756
+ }
3757
+ } ,
3535
3758
ChannelMonitorUpdateStep :: ChannelForceClosed { should_broadcast } => {
3536
3759
log_trace ! ( logger, "Updating ChannelMonitor: channel force closed, should broadcast: {}" , should_broadcast) ;
3537
3760
self . lockdown_from_offchain = true ;
@@ -3583,7 +3806,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3583
3806
|ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTXInfo { .. }
3584
3807
|ChannelMonitorUpdateStep :: LatestCounterpartyCommitmentTX { .. }
3585
3808
|ChannelMonitorUpdateStep :: ShutdownScript { .. }
3586
- |ChannelMonitorUpdateStep :: CommitmentSecret { .. } =>
3809
+ |ChannelMonitorUpdateStep :: CommitmentSecret { .. }
3810
+ |ChannelMonitorUpdateStep :: RenegotiatedFunding { .. } =>
3587
3811
is_pre_close_update = true ,
3588
3812
// After a channel is closed, we don't communicate with our peer about it, so the
3589
3813
// only things we will update is getting a new preimage (from a different channel)
@@ -3765,6 +3989,9 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3765
3989
} => {
3766
3990
Some ( commitment_tx. clone ( ) )
3767
3991
} ,
3992
+ & ChannelMonitorUpdateStep :: RenegotiatedFunding { ref counterparty_commitment_tx, .. } => {
3993
+ Some ( counterparty_commitment_tx. clone ( ) )
3994
+ } ,
3768
3995
_ => None ,
3769
3996
}
3770
3997
} ) . collect ( )
@@ -5438,6 +5665,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
5438
5665
let mut payment_preimages_with_info: Option < HashMap < _ , _ > > = None ;
5439
5666
let mut first_confirmed_funding_txo = RequiredWrapper ( None ) ;
5440
5667
let mut channel_parameters = None ;
5668
+ let mut pending_funding = None ;
5441
5669
read_tlv_fields ! ( reader, {
5442
5670
( 1 , funding_spend_confirmed, option) ,
5443
5671
( 3 , htlcs_resolved_on_chain, optional_vec) ,
@@ -5455,6 +5683,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
5455
5683
( 27 , first_confirmed_funding_txo, ( default_value, outpoint) ) ,
5456
5684
( 29 , initial_counterparty_commitment_tx, option) ,
5457
5685
( 31 , channel_parameters, ( option: ReadableArgs , None ) ) ,
5686
+ ( 32 , pending_funding, optional_vec) ,
5458
5687
} ) ;
5459
5688
if let Some ( payment_preimages_with_info) = payment_preimages_with_info {
5460
5689
if payment_preimages_with_info. len ( ) != payment_preimages. len ( ) {
@@ -5570,6 +5799,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
5570
5799
current_holder_commitment_tx,
5571
5800
prev_holder_commitment_tx,
5572
5801
} ,
5802
+ pending_funding : pending_funding. unwrap_or ( vec ! [ ] ) ,
5573
5803
5574
5804
latest_update_id,
5575
5805
commitment_transaction_number_obscure_factor,
0 commit comments