From 149fa129fe5048876407068a870a27a57b530130 Mon Sep 17 00:00:00 2001 From: G8XSU <3442979+G8XSU@users.noreply.github.com> Date: Fri, 31 May 2024 15:26:57 -0700 Subject: [PATCH] Watch all outputs irrespective of claimable outpoints. This removes dependency of watched_outputs from per_commitment_claimable_outpoints, it is required since we will no longer have direct access to per_commitment_claimable_outpoints once we start publishing PersistClaimInfo as part of #3049. --- lightning/src/chain/channelmonitor.rs | 56 ++++++++++++--------------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index f33abee53..6992eb192 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -3233,16 +3233,14 @@ impl ChannelMonitorImpl { /// height > height + CLTV_SHARED_CLAIM_BUFFER. In any case, will install monitoring for /// HTLC-Success/HTLC-Timeout transactions. /// - /// Returns packages to claim the revoked output(s), as well as additional outputs to watch and - /// general information about the output that is to the counterparty in the commitment - /// transaction. + /// Returns packages to claim the revoked output(s) and general information about the output that + /// is to the counterparty in the commitment transaction. fn check_spend_counterparty_transaction(&mut self, tx: &Transaction, height: u32, block_hash: &BlockHash, logger: &L) - -> (Vec, TransactionOutputs, CommitmentTxCounterpartyOutputInfo) + -> (Vec, CommitmentTxCounterpartyOutputInfo) where L::Target: Logger { // Most secp and related errors trying to create keys means we have no hope of constructing // a spend transaction...so we return no transactions to broadcast let mut claimable_outpoints = Vec::new(); - let mut watch_outputs = Vec::new(); let mut to_counterparty_output_info = None; let commitment_txid = tx.txid(); //TODO: This is gonna be a performance bottleneck for watchtowers! @@ -3252,7 +3250,7 @@ impl ChannelMonitorImpl { ( $thing : expr ) => { match $thing { Ok(a) => a, - Err(_) => return (claimable_outpoints, (commitment_txid, watch_outputs), to_counterparty_output_info) + Err(_) => return (claimable_outpoints, to_counterparty_output_info) } }; } @@ -3286,8 +3284,7 @@ impl ChannelMonitorImpl { if transaction_output_index as usize >= tx.output.len() || tx.output[transaction_output_index as usize].value != htlc.to_bitcoin_amount() { // per_commitment_data is corrupt or our commitment signing key leaked! - return (claimable_outpoints, (commitment_txid, watch_outputs), - to_counterparty_output_info); + return (claimable_outpoints, to_counterparty_output_info); } 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); let justice_package = PackageTemplate::build_package(commitment_txid, transaction_output_index, PackageSolvingData::RevokedHTLCOutput(revk_htlc_outp), htlc.cltv_expiry, height); @@ -3300,9 +3297,6 @@ impl ChannelMonitorImpl { if !claimable_outpoints.is_empty() || per_commitment_option.is_some() { // ie we're confident this is actually ours // We're definitely a counterparty commitment transaction! log_error!(logger, "Got broadcast of revoked counterparty commitment transaction, going to generate general spend tx with {} inputs", claimable_outpoints.len()); - for (idx, outp) in tx.output.iter().enumerate() { - watch_outputs.push((idx as u32, outp.clone())); - } self.counterparty_commitment_txn_on_chain.insert(commitment_txid, commitment_number); if let Some(per_commitment_claimable_data) = per_commitment_option { @@ -3328,9 +3322,6 @@ impl ChannelMonitorImpl { // already processed the block, resulting in the counterparty_commitment_txn_on_chain entry // not being generated by the above conditional. Thus, to be safe, we go ahead and // insert it here. - for (idx, outp) in tx.output.iter().enumerate() { - watch_outputs.push((idx as u32, outp.clone())); - } self.counterparty_commitment_txn_on_chain.insert(commitment_txid, commitment_number); log_info!(logger, "Got broadcast of non-revoked counterparty commitment transaction {}", commitment_txid); @@ -3346,7 +3337,7 @@ impl ChannelMonitorImpl { } } - (claimable_outpoints, (commitment_txid, watch_outputs), to_counterparty_output_info) + (claimable_outpoints, to_counterparty_output_info) } /// Returns the HTLC claim package templates and the counterparty output info @@ -3778,24 +3769,25 @@ impl ChannelMonitorImpl { self.funding_spend_seen = true; let mut commitment_tx_to_counterparty_output = None; if (tx.input[0].sequence.0 >> 8*3) as u8 == 0x80 && (tx.lock_time.to_consensus_u32() >> 8*3) as u8 == 0x20 { - let (mut new_outpoints, new_outputs, counterparty_output_idx_sats) = - self.check_spend_counterparty_transaction(&tx, height, &block_hash, &logger); - commitment_tx_to_counterparty_output = counterparty_output_idx_sats; - if !new_outputs.1.is_empty() { - watch_outputs.push(new_outputs); - } - claimable_outpoints.append(&mut new_outpoints); - if new_outpoints.is_empty() { - if let Some((mut new_outpoints, new_outputs)) = self.check_spend_holder_transaction(&tx, height, &block_hash, &logger) { - #[cfg(not(fuzzing))] - debug_assert!(commitment_tx_to_counterparty_output.is_none(), - "A commitment transaction matched as both a counterparty and local commitment tx?"); - if !new_outputs.1.is_empty() { - watch_outputs.push(new_outputs); - } - claimable_outpoints.append(&mut new_outpoints); - balance_spendable_csv = Some(self.on_holder_tx_csv); + if let Some((mut new_outpoints, new_outputs)) = self.check_spend_holder_transaction(&tx, height, &block_hash, &logger) { + if !new_outputs.1.is_empty() { + watch_outputs.push(new_outputs); + } + + claimable_outpoints.append(&mut new_outpoints); + balance_spendable_csv = Some(self.on_holder_tx_csv); + } else { + let mut new_watch_outputs = Vec::new(); + for (idx, outp) in tx.output.iter().enumerate() { + new_watch_outputs.push((idx as u32, outp.clone())); } + watch_outputs.push((txid, new_watch_outputs)); + + let (mut new_outpoints, counterparty_output_idx_sats) = + self.check_spend_counterparty_transaction(&tx, height, &block_hash, &logger); + commitment_tx_to_counterparty_output = counterparty_output_idx_sats; + + claimable_outpoints.append(&mut new_outpoints); } } self.onchain_events_awaiting_threshold_conf.push(OnchainEventEntry { -- 2.39.5