/// 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<L: Deref>(&mut self, tx: &Transaction, height: u32, block_hash: &BlockHash, logger: &L)
- -> (Vec<PackageTemplate>, TransactionOutputs, CommitmentTxCounterpartyOutputInfo)
+ -> (Vec<PackageTemplate>, 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!
( $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)
}
};
}
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);
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 {
// 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);
}
}
- (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
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 {