@@ -2771,8 +2771,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
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- let htlc_outputs: Vec < HTLCOutputInCommitment > = self . counterparty_claimable_outpoints . get ( & txid) . unwrap_or ( & vec ! [ ] ) . iter ( ) . map ( |( htlc, _) | htlc. clone ( ) ) . collect ( ) ;
2775- claim_htlcs ! ( * commitment_number, txid, htlc_outputs. as_ref( ) ) ;
2774+ claim_htlcs ! ( * commitment_number, txid, self . counterparty_claimable_outpoints. get( & txid) ) ;
27762775 } else {
27772776 debug_assert ! ( false ) ;
27782777 log_error ! ( logger, "Detected counterparty commitment tx on-chain without tracking commitment number" ) ;
@@ -2783,8 +2782,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
27832782 if let Some ( txid) = self . prev_counterparty_commitment_txid {
27842783 if txid == confirmed_spend_txid {
27852784 if let Some ( commitment_number) = self . counterparty_commitment_txn_on_chain . get ( & txid) {
2786- let htlc_outputs: Vec < HTLCOutputInCommitment > = self . counterparty_claimable_outpoints . get ( & txid) . unwrap_or ( & vec ! [ ] ) . iter ( ) . map ( |( htlc, _) | htlc. clone ( ) ) . collect ( ) ;
2787- claim_htlcs ! ( * commitment_number, txid, htlc_outputs. as_ref( ) ) ;
2785+ claim_htlcs ! ( * commitment_number, txid, self . counterparty_claimable_outpoints. get( & txid) ) ;
27882786 } else {
27892787 debug_assert ! ( false ) ;
27902788 log_error ! ( logger, "Detected counterparty commitment tx on-chain without tracking commitment number" ) ;
@@ -3237,8 +3235,8 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32373235 /// Returns packages to claim the revoked output(s), as well as additional outputs to watch and
32383236 /// general information about the output that is to the counterparty in the commitment
32393237 /// transaction.
3240- fn check_spend_counterparty_transaction < L : Deref > ( & mut self , tx : & Transaction , height : u32 , block_hash : & BlockHash , per_commitment_claimable_outpoints : & Vec < HTLCOutputInCommitment > , logger : & L )
3241- -> ( 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 )
32423240 where L :: Target : Logger {
32433241 // Most secp and related errors trying to create keys means we have no hope of constructing
32443242 // a spend transaction...so we return no transactions to broadcast
@@ -3247,7 +3245,6 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32473245 let mut to_counterparty_output_info = None ;
32483246
32493247 let commitment_txid = tx. txid ( ) ; //TODO: This is gonna be a performance bottleneck for watchtowers!
3250- let per_commitment_option = self . counterparty_claimable_outpoints . get ( & commitment_txid) ;
32513248
32523249 macro_rules! ignore_error {
32533250 ( $thing : expr ) => {
@@ -3281,32 +3278,34 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
32813278 }
32823279
32833280 // Then, try to find revoked htlc outputs
3284- for htlc in per_commitment_claimable_outpoints {
3285- if let Some ( transaction_output_index) = htlc. transaction_output_index {
3286- if transaction_output_index as usize >= tx. output . len ( ) ||
3281+ if let Some ( per_commitment_claimable_data) = per_commitment_option {
3282+ for ( htlc, _) in per_commitment_claimable_data {
3283+ if let Some ( transaction_output_index) = htlc. transaction_output_index {
3284+ if transaction_output_index as usize >= tx. output . len ( ) ||
32873285 tx. output [ transaction_output_index as usize ] . value != htlc. amount_msat / 1000 {
3288- // per_commitment_data is corrupt or our commitment signing key leaked!
3289- return ( claimable_outpoints, ( commitment_txid, watch_outputs) ,
3290- to_counterparty_output_info) ;
3286+ // per_commitment_data is corrupt or our commitment signing key leaked!
3287+ return ( claimable_outpoints, ( commitment_txid, watch_outputs) ,
3288+ to_counterparty_output_info) ;
3289+ }
3290+ let revk_htlc_outp = RevokedHTLCOutput :: build ( per_commitment_point, self . counterparty_commitment_params . counterparty_delayed_payment_base_key , self . counterparty_commitment_params . counterparty_htlc_base_key , per_commitment_key, htlc. amount_msat / 1000 , htlc. clone ( ) , & self . onchain_tx_handler . channel_transaction_parameters . channel_type_features ) ;
3291+ let justice_package = PackageTemplate :: build_package ( commitment_txid, transaction_output_index, PackageSolvingData :: RevokedHTLCOutput ( revk_htlc_outp) , htlc. cltv_expiry , height) ;
3292+ claimable_outpoints. push ( justice_package) ;
32913293 }
3292- let revk_htlc_outp = RevokedHTLCOutput :: build ( per_commitment_point, self . counterparty_commitment_params . counterparty_delayed_payment_base_key , self . counterparty_commitment_params . counterparty_htlc_base_key , per_commitment_key, htlc. amount_msat / 1000 , htlc. clone ( ) , & self . onchain_tx_handler . channel_transaction_parameters . channel_type_features ) ;
3293- let justice_package = PackageTemplate :: build_package ( commitment_txid, transaction_output_index, PackageSolvingData :: RevokedHTLCOutput ( revk_htlc_outp) , htlc. cltv_expiry , height) ;
3294- claimable_outpoints. push ( justice_package) ;
32953294 }
32963295 }
32973296
32983297 // Last, track onchain revoked commitment transaction and fail backward outgoing HTLCs as payment path is broken
3299- if !claimable_outpoints. is_empty ( ) || !per_commitment_claimable_outpoints . is_empty ( ) { // ie we're confident this is actually ours
3298+ if !claimable_outpoints. is_empty ( ) || per_commitment_option . is_some ( ) { // ie we're confident this is actually ours
33003299 // We're definitely a counterparty commitment transaction!
33013300 log_error ! ( logger, "Got broadcast of revoked counterparty commitment transaction, going to generate general spend tx with {} inputs" , claimable_outpoints. len( ) ) ;
33023301 for ( idx, outp) in tx. output . iter ( ) . enumerate ( ) {
33033302 watch_outputs. push ( ( idx as u32 , outp. clone ( ) ) ) ;
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,13 +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- let per_commitment_htlc_outputs : Vec < HTLCOutputInCommitment > = per_commitment_data. iter ( ) . map ( |( a, _) | a. clone ( ) ) . collect ( ) ;
3341- // let per_commitment_htlc_outputs = per_commitment_data.iter().map(|&(ref htlc, _)| htlc.clone()).collect();
33423339 let ( htlc_claim_reqs, counterparty_output_info) =
3343- self . get_counterparty_output_claim_info ( commitment_number, commitment_txid, Some ( tx) , per_commitment_htlc_outputs . as_ref ( ) ) ;
3340+ self . get_counterparty_output_claim_info ( commitment_number, commitment_txid, Some ( tx) , per_commitment_option ) ;
33443341 to_counterparty_output_info = counterparty_output_info;
33453342 for req in htlc_claim_reqs {
33463343 claimable_outpoints. push ( req) ;
@@ -3351,15 +3348,16 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33513348 }
33523349
33533350 /// 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 > , per_commitment_claimable_outpoints : & Vec < HTLCOutputInCommitment > )
3355- -> ( Vec < PackageTemplate > , CommitmentTxCounterpartyOutputInfo ) {
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 > > ) > > )
3352+ -> ( Vec < PackageTemplate > , CommitmentTxCounterpartyOutputInfo ) {
33563353 let mut claimable_outpoints = Vec :: new ( ) ;
33573354 let mut to_counterparty_output_info: CommitmentTxCounterpartyOutputInfo = None ;
33583355
3359- if per_commitment_claimable_outpoints . is_empty ( ) || self . their_cur_per_commitment_points . is_none ( ) {
3356+ if per_commitment_option . is_none ( ) || self . their_cur_per_commitment_points . is_none ( ) {
33603357 return ( claimable_outpoints, to_counterparty_output_info) ;
33613358 }
33623359 let per_commitment_points = self . their_cur_per_commitment_points . as_ref ( ) . unwrap ( ) ;
3360+ let per_commitment_claimable_data = per_commitment_option. unwrap ( ) ;
33633361
33643362 let per_commitment_point =
33653363 // If the counterparty commitment tx is the latest valid state, use their latest
@@ -3391,7 +3389,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
33913389 }
33923390 }
33933391
3394- for & ref htlc in per_commitment_claimable_outpoints . iter ( ) {
3392+ for & ( ref htlc, _ ) in per_commitment_claimable_data . iter ( ) {
33953393 if let Some ( transaction_output_index) = htlc. transaction_output_index {
33963394 if let Some ( transaction) = tx {
33973395 if transaction_output_index as usize >= transaction. output . len ( ) ||
@@ -3574,14 +3572,14 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
35743572 /// Cancels any existing pending claims for a commitment that previously confirmed and has now
35753573 /// been replaced by another.
35763574 pub fn cancel_prev_commitment_claims < L : Deref > (
3577- & mut self , logger : & L , confirmed_commitment_txid : & Txid , per_commitment_claimable_outpoints : & Vec < HTLCOutputInCommitment >
3575+ & mut self , logger : & L , confirmed_commitment_txid : & Txid , per_commitment_option : Option < & Vec < ( HTLCOutputInCommitment , Option < Box < HTLCSource > > ) > >
35783576 ) where L :: Target : Logger {
35793577 for ( counterparty_commitment_txid, _) in & self . counterparty_commitment_txn_on_chain {
35803578 // Cancel any pending claims for counterparty commitments we've seen confirm.
35813579 if counterparty_commitment_txid == confirmed_commitment_txid {
35823580 continue ;
35833581 }
3584- for htlc in per_commitment_claimable_outpoints {
3582+ for ( htlc, _ ) in per_commitment_option . unwrap_or ( & vec ! [ ] ) {
35853583 log_trace ! ( logger, "Canceling claims for previously confirmed counterparty commitment {}" ,
35863584 counterparty_commitment_txid) ;
35873585 let mut outpoint = BitcoinOutPoint { txid : * counterparty_commitment_txid, vout : 0 } ;
@@ -3766,16 +3764,20 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
37663764 // (except for HTLC transactions for channels with anchor outputs), which is an easy
37673765 // way to filter out any potential non-matching txn for lazy filters.
37683766 let prevout = & tx. input [ 0 ] . previous_output ;
3769- let per_commitment_claimable_outpoints : Vec < HTLCOutputInCommitment > = self . counterparty_claimable_outpoints . get ( & tx . txid ( ) ) . unwrap_or ( & vec ! [ ] ) . iter ( ) . map ( | ( htlc , _ ) | htlc . clone ( ) ) . collect ( ) ;
3767+
37703768 if prevout. txid == self . funding_info . 0 . txid && prevout. vout == self . funding_info . 0 . index as u32 {
37713769 let mut balance_spendable_csv = None ;
37723770 log_info ! ( logger, "Channel {} closed by funding output spend in txid {}." ,
37733771 & self . channel_id( ) , txid) ;
37743772 self . funding_spend_seen = true ;
37753773 let mut commitment_tx_to_counterparty_output = None ;
3776- if ( tx. input [ 0 ] . sequence . 0 >> 8 * 3 ) as u8 == 0x80 && ( tx. lock_time . to_consensus_u32 ( ) >> 8 * 3 ) as u8 == 0x20 {
3774+
3775+ let per_commitment_option = self . counterparty_claimable_outpoints . get ( & tx. txid ( ) ) . map ( |x| ( x. iter ( )
3776+ . map ( |& ( ref a, ref b) | ( a. clone ( ) , b. clone ( ) ) ) . collect :: < Vec < _ > > ( ) ) ) ;
3777+
3778+ if ( tx. input [ 0 ] . sequence . 0 >> 8 * 3 ) as u8 == 0x80 && ( tx. lock_time . to_consensus_u32 ( ) >> 8 * 3 ) as u8 == 0x20 {
37773779 let ( mut new_outpoints, new_outputs, counterparty_output_idx_sats) =
3778- self . check_spend_counterparty_transaction ( & tx, height, & block_hash, & per_commitment_claimable_outpoints , & logger) ;
3780+ self . check_spend_counterparty_transaction ( & tx, height, & block_hash, per_commitment_option . as_ref ( ) , & logger) ;
37793781 commitment_tx_to_counterparty_output = counterparty_output_idx_sats;
37803782 if !new_outputs. 1 . is_empty ( ) {
37813783 watch_outputs. push ( new_outputs) ;
@@ -3785,7 +3787,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
37853787 if let Some ( ( mut new_outpoints, new_outputs) ) = self . check_spend_holder_transaction ( & tx, height, & block_hash, & logger) {
37863788 #[ cfg( not( fuzzing) ) ]
37873789 debug_assert ! ( commitment_tx_to_counterparty_output. is_none( ) ,
3788- "A commitment transaction matched as both a counterparty and local commitment tx?" ) ;
3790+ "A commitment transaction matched as both a counterparty and local commitment tx?" ) ;
37893791 if !new_outputs. 1 . is_empty ( ) {
37903792 watch_outputs. push ( new_outputs) ;
37913793 }
@@ -3794,6 +3796,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
37943796 }
37953797 }
37963798 }
3799+
37973800 self . onchain_events_awaiting_threshold_conf . push ( OnchainEventEntry {
37983801 txid,
37993802 transaction : Some ( ( * tx) . clone ( ) ) ,
@@ -3807,7 +3810,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
38073810 // Now that we've detected a confirmed commitment transaction, attempt to cancel
38083811 // pending claims for any commitments that were previously confirmed such that
38093812 // we don't continue claiming inputs that no longer exist.
3810- self . cancel_prev_commitment_claims ( & logger, & txid, & per_commitment_claimable_outpoints ) ;
3813+ self . cancel_prev_commitment_claims ( & logger, & txid, per_commitment_option . as_ref ( ) ) ;
38113814 }
38123815 }
38133816 if tx. input . len ( ) >= 1 {
@@ -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