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