@@ -2430,8 +2430,8 @@ macro_rules! fail_unbroadcast_htlcs {
2430
2430
debug_assert_eq!( $commitment_tx_confirmed. txid( ) , $commitment_txid_confirmed) ;
2431
2431
2432
2432
macro_rules! check_htlc_fails {
2433
- ( $txid: expr, $commitment_tx: expr) => {
2434
- if let Some ( ref latest_outpoints) = $self . counterparty_claimable_outpoints . get ( $txid ) {
2433
+ ( $txid: expr, $commitment_tx: expr, $per_commitment_outpoints : expr ) => {
2434
+ if let Some ( ref latest_outpoints) = $per_commitment_outpoints {
2435
2435
for & ( ref htlc, ref source_option) in latest_outpoints. iter( ) {
2436
2436
if let & Some ( ref source) = source_option {
2437
2437
// Check if the HTLC is present in the commitment transaction that was
@@ -2491,10 +2491,10 @@ macro_rules! fail_unbroadcast_htlcs {
2491
2491
}
2492
2492
}
2493
2493
if let Some ( ref txid) = $self. current_counterparty_commitment_txid {
2494
- check_htlc_fails!( txid, "current" ) ;
2494
+ check_htlc_fails!( txid, "current" , $self . counterparty_claimable_outpoints . get ( txid ) ) ;
2495
2495
}
2496
2496
if let Some ( ref txid) = $self. prev_counterparty_commitment_txid {
2497
- check_htlc_fails!( txid, "previous" ) ;
2497
+ check_htlc_fails!( txid, "previous" , $self . counterparty_claimable_outpoints . get ( txid ) ) ;
2498
2498
}
2499
2499
} }
2500
2500
}
@@ -2763,15 +2763,15 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
2763
2763
// If the channel is force closed, try to claim the output from this preimage.
2764
2764
// First check if a counterparty commitment transaction has been broadcasted:
2765
2765
macro_rules! claim_htlcs {
2766
- ( $commitment_number: expr, $txid: expr) => {
2767
- let ( htlc_claim_reqs, _) = self . get_counterparty_output_claim_info( $commitment_number, $txid, None ) ;
2766
+ ( $commitment_number: expr, $txid: expr, $htlcs : expr ) => {
2767
+ let ( htlc_claim_reqs, _) = self . get_counterparty_output_claim_info( $commitment_number, $txid, None , $htlcs ) ;
2768
2768
self . onchain_tx_handler. update_claims_view_from_requests( htlc_claim_reqs, self . best_block. height, self . best_block. height, broadcaster, fee_estimator, logger) ;
2769
2769
}
2770
2770
}
2771
2771
if let Some ( txid) = self . current_counterparty_commitment_txid {
2772
2772
if txid == confirmed_spend_txid {
2773
2773
if let Some ( commitment_number) = self . counterparty_commitment_txn_on_chain . get ( & txid) {
2774
- claim_htlcs ! ( * commitment_number, txid) ;
2774
+ claim_htlcs ! ( * commitment_number, txid, self . counterparty_claimable_outpoints . get ( & txid ) ) ;
2775
2775
} else {
2776
2776
debug_assert ! ( false ) ;
2777
2777
log_error ! ( logger, "Detected counterparty commitment tx on-chain without tracking commitment number" ) ;
@@ -2782,7 +2782,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
2782
2782
if let Some ( txid) = self . prev_counterparty_commitment_txid {
2783
2783
if txid == confirmed_spend_txid {
2784
2784
if let Some ( commitment_number) = self . counterparty_commitment_txn_on_chain . get ( & txid) {
2785
- claim_htlcs ! ( * commitment_number, txid) ;
2785
+ claim_htlcs ! ( * commitment_number, txid, self . counterparty_claimable_outpoints . get ( & txid ) ) ;
2786
2786
} else {
2787
2787
debug_assert ! ( false ) ;
2788
2788
log_error ! ( logger, "Detected counterparty commitment tx on-chain without tracking commitment number" ) ;
@@ -3279,8 +3279,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3279
3279
}
3280
3280
3281
3281
// Then, try to find revoked htlc outputs
3282
- if let Some ( ref per_commitment_data ) = per_commitment_option {
3283
- for ( _ , & ( ref htlc, _) ) in per_commitment_data . iter ( ) . enumerate ( ) {
3282
+ if let Some ( per_commitment_claimable_data ) = per_commitment_option {
3283
+ for ( htlc, _) in per_commitment_claimable_data {
3284
3284
if let Some ( transaction_output_index) = htlc. transaction_output_index {
3285
3285
if transaction_output_index as usize >= tx. output . len ( ) ||
3286
3286
tx. output [ transaction_output_index as usize ] . value != htlc. amount_msat / 1000 {
@@ -3304,9 +3304,9 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3304
3304
}
3305
3305
self . counterparty_commitment_txn_on_chain . insert ( commitment_txid, commitment_number) ;
3306
3306
3307
- if let Some ( per_commitment_data ) = per_commitment_option {
3307
+ if let Some ( per_commitment_claimable_data ) = per_commitment_option {
3308
3308
fail_unbroadcast_htlcs ! ( self , "revoked_counterparty" , commitment_txid, tx, height,
3309
- block_hash, per_commitment_data . iter( ) . map( |( htlc, htlc_source) |
3309
+ block_hash, per_commitment_claimable_data . iter( ) . map( |( htlc, htlc_source) |
3310
3310
( htlc, htlc_source. as_ref( ) . map( |htlc_source| htlc_source. as_ref( ) ) )
3311
3311
) , logger) ;
3312
3312
} else {
@@ -3319,7 +3319,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3319
3319
block_hash, [ ] . iter( ) . map( |reference| * reference) , logger) ;
3320
3320
}
3321
3321
}
3322
- } else if let Some ( per_commitment_data ) = per_commitment_option {
3322
+ } else if let Some ( per_commitment_claimable_data ) = per_commitment_option {
3323
3323
// While this isn't useful yet, there is a potential race where if a counterparty
3324
3324
// revokes a state at the same time as the commitment transaction for that state is
3325
3325
// confirmed, and the watchtower receives the block before the user, the user could
@@ -3334,12 +3334,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3334
3334
3335
3335
log_info ! ( logger, "Got broadcast of non-revoked counterparty commitment transaction {}" , commitment_txid) ;
3336
3336
fail_unbroadcast_htlcs ! ( self , "counterparty" , commitment_txid, tx, height, block_hash,
3337
- per_commitment_data . iter( ) . map( |( htlc, htlc_source) |
3337
+ per_commitment_claimable_data . iter( ) . map( |( htlc, htlc_source) |
3338
3338
( htlc, htlc_source. as_ref( ) . map( |htlc_source| htlc_source. as_ref( ) ) )
3339
3339
) , logger) ;
3340
-
3341
3340
let ( htlc_claim_reqs, counterparty_output_info) =
3342
- self . get_counterparty_output_claim_info ( commitment_number, commitment_txid, Some ( tx) ) ;
3341
+ self . get_counterparty_output_claim_info ( commitment_number, commitment_txid, Some ( tx) , per_commitment_option ) ;
3343
3342
to_counterparty_output_info = counterparty_output_info;
3344
3343
for req in htlc_claim_reqs {
3345
3344
claimable_outpoints. push ( req) ;
@@ -3350,12 +3349,12 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3350
3349
}
3351
3350
3352
3351
/// Returns the HTLC claim package templates and the counterparty output info
3353
- fn get_counterparty_output_claim_info ( & self , commitment_number : u64 , commitment_txid : Txid , tx : Option < & Transaction > )
3352
+ fn get_counterparty_output_claim_info ( & self , commitment_number : u64 , commitment_txid : Txid , tx : Option < & Transaction > , per_commitment_option : Option < & Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > > )
3354
3353
-> ( Vec < PackageTemplate > , CommitmentTxCounterpartyOutputInfo ) {
3355
3354
let mut claimable_outpoints = Vec :: new ( ) ;
3356
3355
let mut to_counterparty_output_info: CommitmentTxCounterpartyOutputInfo = None ;
3357
3356
3358
- let htlc_outputs = match self . counterparty_claimable_outpoints . get ( & commitment_txid ) {
3357
+ let per_commitment_claimable_data = match per_commitment_option {
3359
3358
Some ( outputs) => outputs,
3360
3359
None => return ( claimable_outpoints, to_counterparty_output_info) ,
3361
3360
} ;
@@ -3394,7 +3393,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3394
3393
}
3395
3394
}
3396
3395
3397
- for ( _ , & ( ref htlc, _) ) in htlc_outputs . iter ( ) . enumerate ( ) {
3396
+ for & ( ref htlc, _) in per_commitment_claimable_data . iter ( ) {
3398
3397
if let Some ( transaction_output_index) = htlc. transaction_output_index {
3399
3398
if let Some ( transaction) = tx {
3400
3399
if transaction_output_index as usize >= transaction. output . len ( ) ||
@@ -3584,6 +3583,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
3584
3583
if counterparty_commitment_txid == confirmed_commitment_txid {
3585
3584
continue ;
3586
3585
}
3586
+ // If we have generated claims for counterparty_commitment_txid earlier, we can rely on always
3587
+ // having claim related htlcs for counterparty_commitment_txid in counterparty_claimable_outpoints.
3587
3588
for ( htlc, _) in self . counterparty_claimable_outpoints . get ( counterparty_commitment_txid) . unwrap_or ( & vec ! [ ] ) {
3588
3589
log_trace ! ( logger, "Canceling claims for previously confirmed counterparty commitment {}" ,
3589
3590
counterparty_commitment_txid) ;
@@ -4219,9 +4220,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
4219
4220
}
4220
4221
4221
4222
macro_rules! check_htlc_valid_counterparty {
4222
- ( $counterparty_txid: expr, $htlc_output: expr) => {
4223
- if let Some ( txid) = $counterparty_txid {
4224
- for & ( ref pending_htlc, ref pending_source) in self . counterparty_claimable_outpoints. get( & txid) . unwrap( ) {
4223
+ ( $htlc_output: expr, $per_commitment_data: expr) => {
4224
+ for & ( ref pending_htlc, ref pending_source) in $per_commitment_data {
4225
4225
if pending_htlc. payment_hash == $htlc_output. payment_hash && pending_htlc. amount_msat == $htlc_output. amount_msat {
4226
4226
if let & Some ( ref source) = pending_source {
4227
4227
log_claim!( "revoked counterparty commitment tx" , false , pending_htlc, true ) ;
@@ -4230,7 +4230,6 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
4230
4230
}
4231
4231
}
4232
4232
}
4233
- }
4234
4233
}
4235
4234
}
4236
4235
@@ -4247,9 +4246,13 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
4247
4246
// resolve the source HTLC with the original sender.
4248
4247
payment_data = Some ( ( ( * source) . clone( ) , htlc_output. payment_hash, htlc_output. amount_msat) ) ;
4249
4248
} else if !$holder_tx {
4250
- check_htlc_valid_counterparty!( self . current_counterparty_commitment_txid, htlc_output) ;
4249
+ if let Some ( current_counterparty_commitment_txid) = & self . current_counterparty_commitment_txid {
4250
+ check_htlc_valid_counterparty!( htlc_output, self . counterparty_claimable_outpoints. get( current_counterparty_commitment_txid) . unwrap( ) ) ;
4251
+ }
4251
4252
if payment_data. is_none( ) {
4252
- check_htlc_valid_counterparty!( self . prev_counterparty_commitment_txid, htlc_output) ;
4253
+ if let Some ( prev_counterparty_commitment_txid) = & self . prev_counterparty_commitment_txid {
4254
+ check_htlc_valid_counterparty!( htlc_output, self . counterparty_claimable_outpoints. get( prev_counterparty_commitment_txid) . unwrap( ) ) ;
4255
+ }
4253
4256
}
4254
4257
}
4255
4258
if payment_data. is_none( ) {
@@ -4287,7 +4290,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
4287
4290
}
4288
4291
}
4289
4292
if let Some ( ref htlc_outputs) = self . counterparty_claimable_outpoints . get ( & input. previous_output . txid ) {
4290
- scan_commitment ! ( htlc_outputs. iter( ) . map( |& ( ref a, ref b) | ( a, ( b. as_ref( ) . clone ( ) ) . map( |boxed| & * * boxed) ) ) ,
4293
+ scan_commitment ! ( htlc_outputs. iter( ) . map( |& ( ref a, ref b) | ( a, b. as_ref( ) . map( |boxed| & * * boxed) ) ) ,
4291
4294
"counterparty commitment tx" , false ) ;
4292
4295
}
4293
4296
0 commit comments