@@ -493,8 +493,12 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
493493pub ( crate ) enum ChannelMonitorUpdateStep {
494494 LatestHolderCommitmentTXInfo {
495495 commitment_tx : HolderCommitmentTransaction ,
496+ /// Note that LDK after 0.0.115 supports this only containing dust HTLCs (implying the
497+ /// `Signature` field is never filled in). At that point, non-dust HTLCs are implied by the
498+ /// HTLC fields in `commitment_tx` and the sources passed via `nondust_htlc_sources`.
496499 htlc_outputs : Vec < ( HTLCOutputInCommitment , Option < Signature > , Option < HTLCSource > ) > ,
497500 claimed_htlcs : Vec < ( SentHTLCId , PaymentPreimage ) > ,
501+ nondust_htlc_sources : Vec < HTLCSource > ,
498502 } ,
499503 LatestCounterpartyCommitmentTXInfo {
500504 commitment_txid : Txid ,
@@ -539,6 +543,7 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
539543 ( 0 , commitment_tx, required) ,
540544 ( 1 , claimed_htlcs, vec_type) ,
541545 ( 2 , htlc_outputs, vec_type) ,
546+ ( 4 , nondust_htlc_sources, optional_vec) ,
542547 } ,
543548 ( 1 , LatestCounterpartyCommitmentTXInfo ) => {
544549 ( 0 , commitment_txid, required) ,
@@ -1180,7 +1185,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
11801185 & self , holder_commitment_tx : HolderCommitmentTransaction ,
11811186 htlc_outputs : Vec < ( HTLCOutputInCommitment , Option < Signature > , Option < HTLCSource > ) > ,
11821187 ) -> Result < ( ) , ( ) > {
1183- self . inner . lock ( ) . unwrap ( ) . provide_latest_holder_commitment_tx ( holder_commitment_tx, htlc_outputs, & Vec :: new ( ) ) . map_err ( |_| ( ) )
1188+ self . inner . lock ( ) . unwrap ( ) . provide_latest_holder_commitment_tx ( holder_commitment_tx, htlc_outputs, & Vec :: new ( ) , Vec :: new ( ) ) . map_err ( |_| ( ) )
11841189 }
11851190
11861191 /// This is used to provide payment preimage(s) out-of-band during startup without updating the
@@ -2160,7 +2165,53 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
21602165 /// is important that any clones of this channel monitor (including remote clones) by kept
21612166 /// up-to-date as our holder commitment transaction is updated.
21622167 /// Panics if set_on_holder_tx_csv has never been called.
2163- 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 > {
2168+ 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 > {
2169+ if htlc_outputs. iter ( ) . any ( |( _, s, _) | s. is_some ( ) ) {
2170+ // If we have non-dust HTLCs in htlc_outputs, ensure they match the HTLCs in the
2171+ // `holder_commitment_tx`. In the future, we'll no longer provide the redundant data
2172+ // and just pass in source data via `nondust_htlc_sources`.
2173+ debug_assert_eq ! ( htlc_outputs. iter( ) . filter( |( _, s, _) | s. is_some( ) ) . count( ) , holder_commitment_tx. trust( ) . htlcs( ) . len( ) ) ;
2174+ for ( a, b) in htlc_outputs. iter ( ) . filter ( |( _, s, _) | s. is_some ( ) ) . map ( |( h, _, _) | h) . zip ( holder_commitment_tx. trust ( ) . htlcs ( ) . iter ( ) ) {
2175+ debug_assert_eq ! ( a, b) ;
2176+ }
2177+ debug_assert_eq ! ( htlc_outputs. iter( ) . filter( |( _, s, _) | s. is_some( ) ) . count( ) , holder_commitment_tx. counterparty_htlc_sigs. len( ) ) ;
2178+ for ( a, b) in htlc_outputs. iter ( ) . filter_map ( |( _, s, _) | s. as_ref ( ) ) . zip ( holder_commitment_tx. counterparty_htlc_sigs . iter ( ) ) {
2179+ debug_assert_eq ! ( a, b) ;
2180+ }
2181+ debug_assert ! ( nondust_htlc_sources. is_empty( ) ) ;
2182+ } else {
2183+ // If we don't have any non-dust HTLCs in htlc_outputs, assume they were all passed via
2184+ // `nondust_htlc_sources`, building up the final htlc_outputs by combining
2185+ // `nondust_htlc_sources` and the `holder_commitment_tx`
2186+ #[ cfg( debug_assertions) ] {
2187+ let mut prev = -1 ;
2188+ for htlc in holder_commitment_tx. trust ( ) . htlcs ( ) . iter ( ) {
2189+ assert ! ( htlc. transaction_output_index. unwrap( ) as i32 > prev) ;
2190+ prev = htlc. transaction_output_index . unwrap ( ) as i32 ;
2191+ }
2192+ }
2193+ debug_assert ! ( htlc_outputs. iter( ) . all( |( htlc, _, _) | htlc. transaction_output_index. is_none( ) ) ) ;
2194+ debug_assert ! ( htlc_outputs. iter( ) . all( |( _, sig_opt, _) | sig_opt. is_none( ) ) ) ;
2195+ debug_assert_eq ! ( holder_commitment_tx. trust( ) . htlcs( ) . len( ) , holder_commitment_tx. counterparty_htlc_sigs. len( ) ) ;
2196+
2197+ let mut sources_iter = nondust_htlc_sources. into_iter ( ) ;
2198+
2199+ for ( htlc, counterparty_sig) in holder_commitment_tx. trust ( ) . htlcs ( ) . iter ( )
2200+ . zip ( holder_commitment_tx. counterparty_htlc_sigs . iter ( ) )
2201+ {
2202+ if htlc. offered {
2203+ let source = sources_iter. next ( ) . expect ( "Non-dust HTLC sources didn't match commitment tx" ) ;
2204+ #[ cfg( debug_assertions) ] {
2205+ assert ! ( source. possibly_matches_output( htlc) ) ;
2206+ }
2207+ htlc_outputs. push ( ( htlc. clone ( ) , Some ( counterparty_sig. clone ( ) ) , Some ( source) ) ) ;
2208+ } else {
2209+ htlc_outputs. push ( ( htlc. clone ( ) , Some ( counterparty_sig. clone ( ) ) , None ) ) ;
2210+ }
2211+ }
2212+ debug_assert ! ( sources_iter. next( ) . is_none( ) ) ;
2213+ }
2214+
21642215 let trusted_tx = holder_commitment_tx. trust ( ) ;
21652216 let txid = trusted_tx. txid ( ) ;
21662217 let tx_keys = trusted_tx. keys ( ) ;
@@ -2285,10 +2336,10 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
22852336 let bounded_fee_estimator = LowerBoundedFeeEstimator :: new ( & * fee_estimator) ;
22862337 for update in updates. updates . iter ( ) {
22872338 match update {
2288- ChannelMonitorUpdateStep :: LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, claimed_htlcs } => {
2339+ ChannelMonitorUpdateStep :: LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, claimed_htlcs, nondust_htlc_sources } => {
22892340 log_trace ! ( logger, "Updating ChannelMonitor with latest holder commitment transaction info" ) ;
22902341 if self . lockdown_from_offchain { panic ! ( ) ; }
2291- if let Err ( e) = self . provide_latest_holder_commitment_tx ( commitment_tx. clone ( ) , htlc_outputs. clone ( ) , & claimed_htlcs) {
2342+ if let Err ( e) = self . provide_latest_holder_commitment_tx ( commitment_tx. clone ( ) , htlc_outputs. clone ( ) , & claimed_htlcs, nondust_htlc_sources . clone ( ) ) {
22922343 log_error ! ( logger, "Providing latest holder commitment transaction failed/was refused:" ) ;
22932344 log_error ! ( logger, " {}" , e) ;
22942345 ret = Err ( ( ) ) ;
@@ -4132,7 +4183,7 @@ mod tests {
41324183 }
41334184 }
41344185
4135- macro_rules! preimages_slice_to_htlc_outputs {
4186+ macro_rules! preimages_slice_to_htlcs {
41364187 ( $preimages_slice: expr) => {
41374188 {
41384189 let mut res = Vec :: new( ) ;
@@ -4143,21 +4194,20 @@ mod tests {
41434194 cltv_expiry: 0 ,
41444195 payment_hash: preimage. 1 . clone( ) ,
41454196 transaction_output_index: Some ( idx as u32 ) ,
4146- } , None ) ) ;
4197+ } , ( ) ) ) ;
41474198 }
41484199 res
41494200 }
41504201 }
41514202 }
4152- macro_rules! preimages_to_holder_htlcs {
4203+ macro_rules! preimages_slice_to_htlc_outputs {
41534204 ( $preimages_slice: expr) => {
4154- {
4155- let mut inp = preimages_slice_to_htlc_outputs!( $preimages_slice) ;
4156- let res: Vec <_> = inp. drain( ..) . map( |e| { ( e. 0 , None , e. 1 ) } ) . collect( ) ;
4157- res
4158- }
4205+ preimages_slice_to_htlcs!( $preimages_slice) . into_iter( ) . map( |( htlc, _) | ( htlc, None ) ) . collect( )
41594206 }
41604207 }
4208+ let dummy_sig = crate :: util:: crypto:: sign ( & secp_ctx,
4209+ & bitcoin:: secp256k1:: Message :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ,
4210+ & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
41614211
41624212 macro_rules! test_preimages_exist {
41634213 ( $preimages_slice: expr, $monitor: expr) => {
@@ -4204,13 +4254,15 @@ mod tests {
42044254 let shutdown_pubkey = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
42054255 let best_block = BestBlock :: from_network ( Network :: Testnet ) ;
42064256 let monitor = ChannelMonitor :: new ( Secp256k1 :: new ( ) , keys,
4207- Some ( ShutdownScript :: new_p2wpkh_from_pubkey ( shutdown_pubkey) . into_inner ( ) ) , 0 , & Script :: new ( ) ,
4208- ( OutPoint { txid : Txid :: from_slice ( & [ 43 ; 32 ] ) . unwrap ( ) , index : 0 } , Script :: new ( ) ) ,
4209- & channel_parameters,
4210- Script :: new ( ) , 46 , 0 ,
4211- HolderCommitmentTransaction :: dummy ( ) , best_block, dummy_key) ;
4212-
4213- monitor. provide_latest_holder_commitment_tx ( HolderCommitmentTransaction :: dummy ( ) , preimages_to_holder_htlcs ! ( preimages[ 0 ..10 ] ) ) . unwrap ( ) ;
4257+ Some ( ShutdownScript :: new_p2wpkh_from_pubkey ( shutdown_pubkey) . into_inner ( ) ) , 0 , & Script :: new ( ) ,
4258+ ( OutPoint { txid : Txid :: from_slice ( & [ 43 ; 32 ] ) . unwrap ( ) , index : 0 } , Script :: new ( ) ) ,
4259+ & channel_parameters, Script :: new ( ) , 46 , 0 , HolderCommitmentTransaction :: dummy ( & mut Vec :: new ( ) ) ,
4260+ best_block, dummy_key) ;
4261+
4262+ let mut htlcs = preimages_slice_to_htlcs ! ( preimages[ 0 ..10 ] ) ;
4263+ let dummy_commitment_tx = HolderCommitmentTransaction :: dummy ( & mut htlcs) ;
4264+ monitor. provide_latest_holder_commitment_tx ( dummy_commitment_tx. clone ( ) ,
4265+ htlcs. into_iter ( ) . map ( |( htlc, _) | ( htlc, Some ( dummy_sig) , None ) ) . collect ( ) ) . unwrap ( ) ;
42144266 monitor. provide_latest_counterparty_commitment_tx ( Txid :: from_inner ( Sha256 :: hash ( b"1" ) . into_inner ( ) ) ,
42154267 preimages_slice_to_htlc_outputs ! ( preimages[ 5 ..15 ] ) , 281474976710655 , dummy_key, & logger) ;
42164268 monitor. provide_latest_counterparty_commitment_tx ( Txid :: from_inner ( Sha256 :: hash ( b"2" ) . into_inner ( ) ) ,
@@ -4243,15 +4295,21 @@ mod tests {
42434295
42444296 // Now update holder commitment tx info, pruning only element 18 as we still care about the
42454297 // previous commitment tx's preimages too
4246- monitor. provide_latest_holder_commitment_tx ( HolderCommitmentTransaction :: dummy ( ) , preimages_to_holder_htlcs ! ( preimages[ 0 ..5 ] ) ) . unwrap ( ) ;
4298+ let mut htlcs = preimages_slice_to_htlcs ! ( preimages[ 0 ..5 ] ) ;
4299+ let dummy_commitment_tx = HolderCommitmentTransaction :: dummy ( & mut htlcs) ;
4300+ monitor. provide_latest_holder_commitment_tx ( dummy_commitment_tx. clone ( ) ,
4301+ htlcs. into_iter ( ) . map ( |( htlc, _) | ( htlc, Some ( dummy_sig) , None ) ) . collect ( ) ) . unwrap ( ) ;
42474302 secret[ 0 ..32 ] . clone_from_slice ( & hex:: decode ( "2273e227a5b7449b6e70f1fb4652864038b1cbf9cd7c043a7d6456b7fc275ad8" ) . unwrap ( ) ) ;
42484303 monitor. provide_secret ( 281474976710653 , secret. clone ( ) ) . unwrap ( ) ;
42494304 assert_eq ! ( monitor. inner. lock( ) . unwrap( ) . payment_preimages. len( ) , 12 ) ;
42504305 test_preimages_exist ! ( & preimages[ 0 ..10 ] , monitor) ;
42514306 test_preimages_exist ! ( & preimages[ 18 ..20 ] , monitor) ;
42524307
42534308 // But if we do it again, we'll prune 5-10
4254- monitor. provide_latest_holder_commitment_tx ( HolderCommitmentTransaction :: dummy ( ) , preimages_to_holder_htlcs ! ( preimages[ 0 ..3 ] ) ) . unwrap ( ) ;
4309+ let mut htlcs = preimages_slice_to_htlcs ! ( preimages[ 0 ..3 ] ) ;
4310+ let dummy_commitment_tx = HolderCommitmentTransaction :: dummy ( & mut htlcs) ;
4311+ monitor. provide_latest_holder_commitment_tx ( dummy_commitment_tx,
4312+ htlcs. into_iter ( ) . map ( |( htlc, _) | ( htlc, Some ( dummy_sig) , None ) ) . collect ( ) ) . unwrap ( ) ;
42554313 secret[ 0 ..32 ] . clone_from_slice ( & hex:: decode ( "27cddaa5624534cb6cb9d7da077cf2b22ab21e9b506fd4998a51d54502e99116" ) . unwrap ( ) ) ;
42564314 monitor. provide_secret ( 281474976710652 , secret. clone ( ) ) . unwrap ( ) ;
42574315 assert_eq ! ( monitor. inner. lock( ) . unwrap( ) . payment_preimages. len( ) , 5 ) ;
0 commit comments