@@ -2430,8 +2430,8 @@ macro_rules! fail_unbroadcast_htlcs {
24302430 debug_assert_eq!( $commitment_tx_confirmed. txid( ) , $commitment_txid_confirmed) ;
24312431
24322432 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 {
24352435 for & ( ref htlc, ref source_option) in latest_outpoints. iter( ) {
24362436 if let & Some ( ref source) = source_option {
24372437 // Check if the HTLC is present in the commitment transaction that was
@@ -2491,10 +2491,10 @@ macro_rules! fail_unbroadcast_htlcs {
24912491 }
24922492 }
24932493 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 ) ) ;
24952495 }
24962496 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 ) ) ;
24982498 }
24992499 } }
25002500}
@@ -2763,15 +2763,15 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
27632763 // If the channel is force closed, try to claim the output from this preimage.
27642764 // First check if a counterparty commitment transaction has been broadcasted:
27652765 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 ) ;
27682768 self . onchain_tx_handler. update_claims_view_from_requests( htlc_claim_reqs, self . best_block. height, self . best_block. height, broadcaster, fee_estimator, logger) ;
27692769 }
27702770 }
27712771 if let Some ( txid) = self . current_counterparty_commitment_txid {
27722772 if txid == confirmed_spend_txid {
27732773 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 ) ) ;
27752775 } else {
27762776 debug_assert ! ( false ) ;
27772777 log_error ! ( logger, "Detected counterparty commitment tx on-chain without tracking commitment number" ) ;
@@ -2782,7 +2782,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
27822782 if let Some ( txid) = self . prev_counterparty_commitment_txid {
27832783 if txid == confirmed_spend_txid {
27842784 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 ) ) ;
27862786 } else {
27872787 debug_assert ! ( false ) ;
27882788 log_error ! ( logger, "Detected counterparty commitment tx on-chain without tracking commitment number" ) ;
@@ -3235,8 +3235,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32353235 /// Returns packages to claim the revoked output(s), as well as additional outputs to watch and
32363236 /// general information about the output that is to the counterparty in the commitment
32373237 /// transaction.
3238- fn check_spend_counterparty_transaction < L : Deref > ( & mut self , tx : & Transaction , height : u32 , block_hash : & BlockHash , logger : & L )
3239- -> ( Vec < PackageTemplate > , TransactionOutputs , CommitmentTxCounterpartyOutputInfo )
3238+ fn check_spend_counterparty_transaction < L : Deref > ( & mut self , tx : & Transaction , height : u32 , block_hash : & BlockHash , per_commitment_option : Option < & Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > > , logger : & L )
3239+ -> ( Vec < PackageTemplate > , TransactionOutputs , CommitmentTxCounterpartyOutputInfo )
32403240 where L :: Target : Logger {
32413241 // Most secp and related errors trying to create keys means we have no hope of constructing
32423242 // a spend transaction...so we return no transactions to broadcast
@@ -3245,7 +3245,6 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32453245 let mut to_counterparty_output_info = None ;
32463246
32473247 let commitment_txid = tx. txid ( ) ; //TODO: This is gonna be a performance bottleneck for watchtowers!
3248- let per_commitment_option = self . counterparty_claimable_outpoints . get ( & commitment_txid) ;
32493248
32503249 macro_rules! ignore_error {
32513250 ( $thing : expr ) => {
@@ -3279,8 +3278,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32793278 }
32803279
32813280 // 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 ( ) {
3281+ if let Some ( per_commitment_claimable_data ) = per_commitment_option {
3282+ for ( htlc, _) in per_commitment_claimable_data {
32843283 if let Some ( transaction_output_index) = htlc. transaction_output_index {
32853284 if transaction_output_index as usize >= tx. output . len ( ) ||
32863285 tx. output [ transaction_output_index as usize ] . value != htlc. amount_msat / 1000 {
@@ -3304,9 +3303,9 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33043303 }
33053304 self . counterparty_commitment_txn_on_chain . insert ( commitment_txid, commitment_number) ;
33063305
3307- if let Some ( per_commitment_data ) = per_commitment_option {
3306+ if let Some ( per_commitment_claimable_data ) = per_commitment_option {
33083307 fail_unbroadcast_htlcs ! ( self , "revoked_counterparty" , commitment_txid, tx, height,
3309- block_hash, per_commitment_data . iter( ) . map( |( htlc, htlc_source) |
3308+ block_hash, per_commitment_claimable_data . iter( ) . map( |( htlc, htlc_source) |
33103309 ( htlc, htlc_source. as_ref( ) . map( |htlc_source| htlc_source. as_ref( ) ) )
33113310 ) , logger) ;
33123311 } else {
@@ -3319,7 +3318,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33193318 block_hash, [ ] . iter( ) . map( |reference| * reference) , logger) ;
33203319 }
33213320 }
3322- } else if let Some ( per_commitment_data ) = per_commitment_option {
3321+ } else if let Some ( per_commitment_claimable_data ) = per_commitment_option {
33233322 // While this isn't useful yet, there is a potential race where if a counterparty
33243323 // revokes a state at the same time as the commitment transaction for that state is
33253324 // confirmed, and the watchtower receives the block before the user, the user could
@@ -3334,12 +3333,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33343333
33353334 log_info ! ( logger, "Got broadcast of non-revoked counterparty commitment transaction {}" , commitment_txid) ;
33363335 fail_unbroadcast_htlcs ! ( self , "counterparty" , commitment_txid, tx, height, block_hash,
3337- per_commitment_data . iter( ) . map( |( htlc, htlc_source) |
3336+ per_commitment_claimable_data . iter( ) . map( |( htlc, htlc_source) |
33383337 ( htlc, htlc_source. as_ref( ) . map( |htlc_source| htlc_source. as_ref( ) ) )
33393338 ) , logger) ;
3340-
33413339 let ( htlc_claim_reqs, counterparty_output_info) =
3342- self . get_counterparty_output_claim_info ( commitment_number, commitment_txid, Some ( tx) ) ;
3340+ self . get_counterparty_output_claim_info ( commitment_number, commitment_txid, Some ( tx) , per_commitment_option ) ;
33433341 to_counterparty_output_info = counterparty_output_info;
33443342 for req in htlc_claim_reqs {
33453343 claimable_outpoints. push ( req) ;
@@ -3350,12 +3348,12 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33503348 }
33513349
33523350 /// 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 > )
3351+ 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 > > ) > > )
33543352 -> ( Vec < PackageTemplate > , CommitmentTxCounterpartyOutputInfo ) {
33553353 let mut claimable_outpoints = Vec :: new ( ) ;
33563354 let mut to_counterparty_output_info: CommitmentTxCounterpartyOutputInfo = None ;
33573355
3358- let htlc_outputs = match self . counterparty_claimable_outpoints . get ( & commitment_txid ) {
3356+ let per_commitment_claimable_data = match per_commitment_option {
33593357 Some ( outputs) => outputs,
33603358 None => return ( claimable_outpoints, to_counterparty_output_info) ,
33613359 } ;
@@ -3394,7 +3392,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33943392 }
33953393 }
33963394
3397- for ( _ , & ( ref htlc, _) ) in htlc_outputs . iter ( ) . enumerate ( ) {
3395+ for & ( ref htlc, _) in per_commitment_claimable_data . iter ( ) {
33983396 if let Some ( transaction_output_index) = htlc. transaction_output_index {
33993397 if let Some ( transaction) = tx {
34003398 if transaction_output_index as usize >= transaction. output . len ( ) ||
@@ -3577,14 +3575,14 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
35773575 /// Cancels any existing pending claims for a commitment that previously confirmed and has now
35783576 /// been replaced by another.
35793577 pub fn cancel_prev_commitment_claims < L : Deref > (
3580- & mut self , logger : & L , confirmed_commitment_txid : & Txid
3578+ & mut self , logger : & L , confirmed_commitment_txid : & Txid , per_commitment_option : Option < & Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > >
35813579 ) where L :: Target : Logger {
35823580 for ( counterparty_commitment_txid, _) in & self . counterparty_commitment_txn_on_chain {
35833581 // Cancel any pending claims for counterparty commitments we've seen confirm.
35843582 if counterparty_commitment_txid == confirmed_commitment_txid {
35853583 continue ;
35863584 }
3587- for ( htlc, _) in self . counterparty_claimable_outpoints . get ( counterparty_commitment_txid ) . unwrap_or ( & vec ! [ ] ) {
3585+ for ( htlc, _) in per_commitment_option . unwrap_or ( & vec ! [ ] ) {
35883586 log_trace ! ( logger, "Canceling claims for previously confirmed counterparty commitment {}" ,
35893587 counterparty_commitment_txid) ;
35903588 let mut outpoint = BitcoinOutPoint { txid : * counterparty_commitment_txid, vout : 0 } ;
@@ -3775,9 +3773,12 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
37753773 & self . channel_id( ) , txid) ;
37763774 self . funding_spend_seen = true ;
37773775 let mut commitment_tx_to_counterparty_output = None ;
3778- if ( tx. input [ 0 ] . sequence . 0 >> 8 * 3 ) as u8 == 0x80 && ( tx. lock_time . to_consensus_u32 ( ) >> 8 * 3 ) as u8 == 0x20 {
3776+ let per_commitment_option = self . counterparty_claimable_outpoints . get ( & tx. txid ( ) ) . map ( |x| x. iter ( )
3777+ . map ( |& ( ref a, ref b) | ( a. clone ( ) , b. clone ( ) ) ) . collect :: < Vec < _ > > ( ) ) ;
3778+
3779+ if ( tx. input [ 0 ] . sequence . 0 >> 8 * 3 ) as u8 == 0x80 && ( tx. lock_time . to_consensus_u32 ( ) >> 8 * 3 ) as u8 == 0x20 {
37793780 let ( mut new_outpoints, new_outputs, counterparty_output_idx_sats) =
3780- self . check_spend_counterparty_transaction ( & tx, height, & block_hash, & logger) ;
3781+ self . check_spend_counterparty_transaction ( & tx, height, & block_hash, per_commitment_option . as_ref ( ) , & logger) ;
37813782 commitment_tx_to_counterparty_output = counterparty_output_idx_sats;
37823783 if !new_outputs. 1 . is_empty ( ) {
37833784 watch_outputs. push ( new_outputs) ;
@@ -3809,7 +3810,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
38093810 // Now that we've detected a confirmed commitment transaction, attempt to cancel
38103811 // pending claims for any commitments that were previously confirmed such that
38113812 // we don't continue claiming inputs that no longer exist.
3812- self . cancel_prev_commitment_claims ( & logger, & txid) ;
3813+ self . cancel_prev_commitment_claims ( & logger, & txid, per_commitment_option . as_ref ( ) ) ;
38133814 }
38143815 }
38153816 if tx. input . len ( ) >= 1 {
@@ -4219,9 +4220,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
42194220 }
42204221
42214222 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 {
42254225 if pending_htlc. payment_hash == $htlc_output. payment_hash && pending_htlc. amount_msat == $htlc_output. amount_msat {
42264226 if let & Some ( ref source) = pending_source {
42274227 log_claim!( "revoked counterparty commitment tx" , false , pending_htlc, true ) ;
@@ -4230,7 +4230,6 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
42304230 }
42314231 }
42324232 }
4233- }
42344233 }
42354234 }
42364235
@@ -4247,9 +4246,13 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
42474246 // resolve the source HTLC with the original sender.
42484247 payment_data = Some ( ( ( * source) . clone( ) , htlc_output. payment_hash, htlc_output. amount_msat) ) ;
42494248 } 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+ }
42514252 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+ }
42534256 }
42544257 }
42554258 if payment_data. is_none( ) {
@@ -4287,7 +4290,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
42874290 }
42884291 }
42894292 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) ) ) ,
42914294 "counterparty commitment tx" , false ) ;
42924295 }
42934296
0 commit comments