@@ -494,8 +494,12 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
494494pub ( crate ) enum ChannelMonitorUpdateStep {
495495 LatestHolderCommitmentTXInfo {
496496 commitment_tx : HolderCommitmentTransaction ,
497+ /// Note that LDK after 0.0.115 supports this only containing dust HTLCs (implying the
498+ /// `Signature` field is never filled in). At that point, non-dust HTLCs are implied by the
499+ /// HTLC fields in `commitment_tx` and the sources passed via `nondust_htlc_sources`.
497500 htlc_outputs : Vec < ( HTLCOutputInCommitment , Option < Signature > , Option < HTLCSource > ) > ,
498501 claimed_htlcs : Vec < ( SentHTLCId , PaymentPreimage ) > ,
502+ nondust_htlc_sources : Vec < HTLCSource > ,
499503 } ,
500504 LatestCounterpartyCommitmentTXInfo {
501505 commitment_txid : Txid ,
@@ -540,6 +544,7 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
540544 ( 0 , commitment_tx, required) ,
541545 ( 1 , claimed_htlcs, vec_type) ,
542546 ( 2 , htlc_outputs, vec_type) ,
547+ ( 4 , nondust_htlc_sources, optional_vec) ,
543548 } ,
544549 ( 1 , LatestCounterpartyCommitmentTXInfo ) => {
545550 ( 0 , commitment_txid, required) ,
@@ -1181,7 +1186,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
11811186 & self , holder_commitment_tx : HolderCommitmentTransaction ,
11821187 htlc_outputs : Vec < ( HTLCOutputInCommitment , Option < Signature > , Option < HTLCSource > ) > ,
11831188 ) -> Result < ( ) , ( ) > {
1184- self . inner . lock ( ) . unwrap ( ) . provide_latest_holder_commitment_tx ( holder_commitment_tx, htlc_outputs, & Vec :: new ( ) ) . map_err ( |_| ( ) )
1189+ self . inner . lock ( ) . unwrap ( ) . provide_latest_holder_commitment_tx ( holder_commitment_tx, htlc_outputs, & Vec :: new ( ) , Vec :: new ( ) ) . map_err ( |_| ( ) )
11851190 }
11861191
11871192 /// This is used to provide payment preimage(s) out-of-band during startup without updating the
@@ -2150,7 +2155,53 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
21502155 /// is important that any clones of this channel monitor (including remote clones) by kept
21512156 /// up-to-date as our holder commitment transaction is updated.
21522157 /// Panics if set_on_holder_tx_csv has never been called.
2153- fn provide_latest_holder_commitment_tx ( & mut self , holder_commitment_tx : HolderCommitmentTransaction , htlc_outputs : Vec < ( HTLCOutputInCommitment , Option < Signature > , Option < HTLCSource > ) > , claimed_htlcs : & [ ( SentHTLCId , PaymentPreimage ) ] ) -> Result < ( ) , & ' static str > {
2158+ fn provide_latest_holder_commitment_tx ( & mut self , holder_commitment_tx : HolderCommitmentTransaction , mut htlc_outputs : Vec < ( HTLCOutputInCommitment , Option < Signature > , Option < HTLCSource > ) > , claimed_htlcs : & [ ( SentHTLCId , PaymentPreimage ) ] , nondust_htlc_sources : Vec < HTLCSource > ) -> Result < ( ) , & ' static str > {
2159+ if htlc_outputs. iter ( ) . any ( |( _, s, _) | s. is_some ( ) ) {
2160+ // If we have non-dust HTLCs in htlc_outputs, ensure they match the HTLCs in the
2161+ // `holder_commitment_tx`. In the future, we'll no longer provide the redundant data
2162+ // and just pass in source data via `nondust_htlc_sources`.
2163+ debug_assert_eq ! ( htlc_outputs. iter( ) . filter( |( _, s, _) | s. is_some( ) ) . count( ) , holder_commitment_tx. trust( ) . htlcs( ) . len( ) ) ;
2164+ for ( a, b) in htlc_outputs. iter ( ) . filter ( |( _, s, _) | s. is_some ( ) ) . map ( |( h, _, _) | h) . zip ( holder_commitment_tx. trust ( ) . htlcs ( ) . iter ( ) ) {
2165+ debug_assert_eq ! ( a, b) ;
2166+ }
2167+ debug_assert_eq ! ( htlc_outputs. iter( ) . filter( |( _, s, _) | s. is_some( ) ) . count( ) , holder_commitment_tx. counterparty_htlc_sigs. len( ) ) ;
2168+ for ( a, b) in htlc_outputs. iter ( ) . filter_map ( |( _, s, _) | s. as_ref ( ) ) . zip ( holder_commitment_tx. counterparty_htlc_sigs . iter ( ) ) {
2169+ debug_assert_eq ! ( a, b) ;
2170+ }
2171+ debug_assert ! ( nondust_htlc_sources. is_empty( ) ) ;
2172+ } else {
2173+ // If we don't have any non-dust HTLCs in htlc_outputs, assume they were all passed via
2174+ // `nondust_htlc_sources`, building up the final htlc_outputs by combining
2175+ // `nondust_htlc_sources` and the `holder_commitment_tx`
2176+ #[ cfg( debug_assertions) ] {
2177+ let mut prev = -1 ;
2178+ for htlc in holder_commitment_tx. trust ( ) . htlcs ( ) . iter ( ) {
2179+ assert ! ( htlc. transaction_output_index. unwrap( ) as i32 > prev) ;
2180+ prev = htlc. transaction_output_index . unwrap ( ) as i32 ;
2181+ }
2182+ }
2183+ debug_assert ! ( htlc_outputs. iter( ) . all( |( htlc, _, _) | htlc. transaction_output_index. is_none( ) ) ) ;
2184+ debug_assert ! ( htlc_outputs. iter( ) . all( |( _, sig_opt, _) | sig_opt. is_none( ) ) ) ;
2185+ debug_assert_eq ! ( holder_commitment_tx. trust( ) . htlcs( ) . len( ) , holder_commitment_tx. counterparty_htlc_sigs. len( ) ) ;
2186+
2187+ let mut sources_iter = nondust_htlc_sources. into_iter ( ) ;
2188+
2189+ for ( htlc, counterparty_sig) in holder_commitment_tx. trust ( ) . htlcs ( ) . iter ( )
2190+ . zip ( holder_commitment_tx. counterparty_htlc_sigs . iter ( ) )
2191+ {
2192+ if htlc. offered {
2193+ let source = sources_iter. next ( ) . expect ( "Non-dust HTLC sources didn't match commitment tx" ) ;
2194+ #[ cfg( debug_assertions) ] {
2195+ assert ! ( source. possibly_matches_output( htlc) ) ;
2196+ }
2197+ htlc_outputs. push ( ( htlc. clone ( ) , Some ( counterparty_sig. clone ( ) ) , Some ( source) ) ) ;
2198+ } else {
2199+ htlc_outputs. push ( ( htlc. clone ( ) , Some ( counterparty_sig. clone ( ) ) , None ) ) ;
2200+ }
2201+ }
2202+ debug_assert ! ( sources_iter. next( ) . is_none( ) ) ;
2203+ }
2204+
21542205 let trusted_tx = holder_commitment_tx. trust ( ) ;
21552206 let txid = trusted_tx. txid ( ) ;
21562207 let tx_keys = trusted_tx. keys ( ) ;
@@ -2283,10 +2334,10 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
22832334 let bounded_fee_estimator = LowerBoundedFeeEstimator :: new ( & * fee_estimator) ;
22842335 for update in updates. updates . iter ( ) {
22852336 match update {
2286- ChannelMonitorUpdateStep :: LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, claimed_htlcs } => {
2337+ ChannelMonitorUpdateStep :: LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, claimed_htlcs, nondust_htlc_sources } => {
22872338 log_trace ! ( logger, "Updating ChannelMonitor with latest holder commitment transaction info" ) ;
22882339 if self . lockdown_from_offchain { panic ! ( ) ; }
2289- if let Err ( e) = self . provide_latest_holder_commitment_tx ( commitment_tx. clone ( ) , htlc_outputs. clone ( ) , & claimed_htlcs) {
2340+ if let Err ( e) = self . provide_latest_holder_commitment_tx ( commitment_tx. clone ( ) , htlc_outputs. clone ( ) , & claimed_htlcs, nondust_htlc_sources . clone ( ) ) {
22902341 log_error ! ( logger, "Providing latest holder commitment transaction failed/was refused:" ) ;
22912342 log_error ! ( logger, " {}" , e) ;
22922343 ret = Err ( ( ) ) ;
@@ -4139,7 +4190,7 @@ mod tests {
41394190 }
41404191 }
41414192
4142- macro_rules! preimages_slice_to_htlc_outputs {
4193+ macro_rules! preimages_slice_to_htlcs {
41434194 ( $preimages_slice: expr) => {
41444195 {
41454196 let mut res = Vec :: new( ) ;
@@ -4150,21 +4201,20 @@ mod tests {
41504201 cltv_expiry: 0 ,
41514202 payment_hash: preimage. 1 . clone( ) ,
41524203 transaction_output_index: Some ( idx as u32 ) ,
4153- } , None ) ) ;
4204+ } , ( ) ) ) ;
41544205 }
41554206 res
41564207 }
41574208 }
41584209 }
4159- macro_rules! preimages_to_holder_htlcs {
4210+ macro_rules! preimages_slice_to_htlc_outputs {
41604211 ( $preimages_slice: expr) => {
4161- {
4162- let mut inp = preimages_slice_to_htlc_outputs!( $preimages_slice) ;
4163- let res: Vec <_> = inp. drain( ..) . map( |e| { ( e. 0 , None , e. 1 ) } ) . collect( ) ;
4164- res
4165- }
4212+ preimages_slice_to_htlcs!( $preimages_slice) . into_iter( ) . map( |( htlc, _) | ( htlc, None ) ) . collect( )
41664213 }
41674214 }
4215+ let dummy_sig = crate :: util:: crypto:: sign ( & secp_ctx,
4216+ & bitcoin:: secp256k1:: Message :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ,
4217+ & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
41684218
41694219 macro_rules! test_preimages_exist {
41704220 ( $preimages_slice: expr, $monitor: expr) => {
@@ -4211,13 +4261,15 @@ mod tests {
42114261 let shutdown_pubkey = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
42124262 let best_block = BestBlock :: from_network ( Network :: Testnet ) ;
42134263 let monitor = ChannelMonitor :: new ( Secp256k1 :: new ( ) , keys,
4214- Some ( ShutdownScript :: new_p2wpkh_from_pubkey ( shutdown_pubkey) . into_inner ( ) ) , 0 , & Script :: new ( ) ,
4215- ( OutPoint { txid : Txid :: from_slice ( & [ 43 ; 32 ] ) . unwrap ( ) , index : 0 } , Script :: new ( ) ) ,
4216- & channel_parameters,
4217- Script :: new ( ) , 46 , 0 ,
4218- HolderCommitmentTransaction :: dummy ( ) , best_block, dummy_key) ;
4219-
4220- monitor. provide_latest_holder_commitment_tx ( HolderCommitmentTransaction :: dummy ( ) , preimages_to_holder_htlcs ! ( preimages[ 0 ..10 ] ) ) . unwrap ( ) ;
4264+ Some ( ShutdownScript :: new_p2wpkh_from_pubkey ( shutdown_pubkey) . into_inner ( ) ) , 0 , & Script :: new ( ) ,
4265+ ( OutPoint { txid : Txid :: from_slice ( & [ 43 ; 32 ] ) . unwrap ( ) , index : 0 } , Script :: new ( ) ) ,
4266+ & channel_parameters, Script :: new ( ) , 46 , 0 , HolderCommitmentTransaction :: dummy ( & mut Vec :: new ( ) ) ,
4267+ best_block, dummy_key) ;
4268+
4269+ let mut htlcs = preimages_slice_to_htlcs ! ( preimages[ 0 ..10 ] ) ;
4270+ let dummy_commitment_tx = HolderCommitmentTransaction :: dummy ( & mut htlcs) ;
4271+ monitor. provide_latest_holder_commitment_tx ( dummy_commitment_tx. clone ( ) ,
4272+ htlcs. into_iter ( ) . map ( |( htlc, _) | ( htlc, Some ( dummy_sig) , None ) ) . collect ( ) ) . unwrap ( ) ;
42214273 monitor. provide_latest_counterparty_commitment_tx ( Txid :: from_inner ( Sha256 :: hash ( b"1" ) . into_inner ( ) ) ,
42224274 preimages_slice_to_htlc_outputs ! ( preimages[ 5 ..15 ] ) , 281474976710655 , dummy_key, & logger) ;
42234275 monitor. provide_latest_counterparty_commitment_tx ( Txid :: from_inner ( Sha256 :: hash ( b"2" ) . into_inner ( ) ) ,
@@ -4250,15 +4302,21 @@ mod tests {
42504302
42514303 // Now update holder commitment tx info, pruning only element 18 as we still care about the
42524304 // previous commitment tx's preimages too
4253- monitor. provide_latest_holder_commitment_tx ( HolderCommitmentTransaction :: dummy ( ) , preimages_to_holder_htlcs ! ( preimages[ 0 ..5 ] ) ) . unwrap ( ) ;
4305+ let mut htlcs = preimages_slice_to_htlcs ! ( preimages[ 0 ..5 ] ) ;
4306+ let dummy_commitment_tx = HolderCommitmentTransaction :: dummy ( & mut htlcs) ;
4307+ monitor. provide_latest_holder_commitment_tx ( dummy_commitment_tx. clone ( ) ,
4308+ htlcs. into_iter ( ) . map ( |( htlc, _) | ( htlc, Some ( dummy_sig) , None ) ) . collect ( ) ) . unwrap ( ) ;
42544309 secret[ 0 ..32 ] . clone_from_slice ( & hex:: decode ( "2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8" ) . unwrap ( ) ) ;
42554310 monitor. provide_secret ( 281474976710653 , secret. clone ( ) ) . unwrap ( ) ;
42564311 assert_eq ! ( monitor. inner. lock( ) . unwrap( ) . payment_preimages. len( ) , 12 ) ;
42574312 test_preimages_exist ! ( & preimages[ 0 ..10 ] , monitor) ;
42584313 test_preimages_exist ! ( & preimages[ 18 ..20 ] , monitor) ;
42594314
42604315 // But if we do it again, we'll prune 5-10
4261- monitor. provide_latest_holder_commitment_tx ( HolderCommitmentTransaction :: dummy ( ) , preimages_to_holder_htlcs ! ( preimages[ 0 ..3 ] ) ) . unwrap ( ) ;
4316+ let mut htlcs = preimages_slice_to_htlcs ! ( preimages[ 0 ..3 ] ) ;
4317+ let dummy_commitment_tx = HolderCommitmentTransaction :: dummy ( & mut htlcs) ;
4318+ monitor. provide_latest_holder_commitment_tx ( dummy_commitment_tx,
4319+ htlcs. into_iter ( ) . map ( |( htlc, _) | ( htlc, Some ( dummy_sig) , None ) ) . collect ( ) ) . unwrap ( ) ;
42624320 secret[ 0 ..32 ] . clone_from_slice ( & hex:: decode ( "27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116" ) . unwrap ( ) ) ;
42634321 monitor. provide_secret ( 281474976710652 , secret. clone ( ) ) . unwrap ( ) ;
42644322 assert_eq ! ( monitor. inner. lock( ) . unwrap( ) . payment_preimages. len( ) , 5 ) ;
0 commit comments