X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fchannelmonitor.rs;h=be8367ed77b7d8834f3d9777381c009a636338fb;hb=d0dfaf8abc452cbb4ac3dfe07293027e4609698f;hp=b1e7df29cddfa5bcd3a2394453310a97dbb1e176;hpb=7a483e597c9079a280b1ea31d9762d89300097ce;p=rust-lightning diff --git a/src/ln/channelmonitor.rs b/src/ln/channelmonitor.rs index b1e7df29c..be8367ed7 100644 --- a/src/ln/channelmonitor.rs +++ b/src/ln/channelmonitor.rs @@ -295,6 +295,11 @@ pub(crate) const CLTV_CLAIM_BUFFER: u32 = 6; /// network and done a full update_fail_htlc/commitment_signed dance (+ we've updated all our /// copies of ChannelMonitors, including watchtowers). pub(crate) const HTLC_FAIL_TIMEOUT_BLOCKS: u32 = 3; +/// Number of blocks we wait on seeing a confirmed HTLC-Timeout or previous revoked commitment +/// transaction before we fail corresponding inbound HTLCs. This prevents us from failing backwards +/// and then getting a reorg resulting in us losing money. +//TODO: We currently dont actually use this...we should +pub(crate) const HTLC_FAIL_ANTI_REORG_DELAY: u32 = 6; #[derive(Clone, PartialEq)] enum Storage { @@ -1178,6 +1183,7 @@ impl ChannelMonitor { if !inputs.is_empty() || !txn_to_broadcast.is_empty() { // ie we're confident this is actually ours // We're definitely a remote commitment transaction! + log_trace!(self, "Got broadcast of revoked remote commitment transaction, generating general spend tx with {} inputs and {} other txn to broadcast", inputs.len(), txn_to_broadcast.len()); watch_outputs.append(&mut tx.output.clone()); self.remote_commitment_txn_on_chain.insert(commitment_txid, (commitment_number, tx.output.iter().map(|output| { output.script_pubkey.clone() }).collect())); } @@ -1215,6 +1221,7 @@ impl ChannelMonitor { if let &Some(ref txid) = current_remote_commitment_txid { if let Some(&(_, ref latest_outpoints)) = self.remote_claimable_outpoints.get(&txid) { for &(ref payment_hash, ref source, _) in latest_outpoints.iter() { + log_trace!(self, "Failing HTLC with payment_hash {} from current remote commitment tx due to broadcast of revoked remote commitment transaction", log_bytes!(payment_hash.0)); htlc_updated.push(((*source).clone(), None, payment_hash.clone())); } } @@ -1222,6 +1229,7 @@ impl ChannelMonitor { if let &Some(ref txid) = prev_remote_commitment_txid { if let Some(&(_, ref prev_outpoint)) = self.remote_claimable_outpoints.get(&txid) { for &(ref payment_hash, ref source, _) in prev_outpoint.iter() { + log_trace!(self, "Failing HTLC with payment_hash {} from previous remote commitment tx due to broadcast of revoked remote commitment transaction", log_bytes!(payment_hash.0)); htlc_updated.push(((*source).clone(), None, payment_hash.clone())); } } @@ -1778,16 +1786,17 @@ impl ChannelMonitor { let mut payment_data = None; macro_rules! scan_commitment { - ($htlc_outputs: expr, $htlc_sources: expr) => { + ($htlc_outputs: expr, $htlc_sources: expr, $source: expr) => { for &(ref payment_hash, ref source, ref vout) in $htlc_sources.iter() { if &Some(input.previous_output.vout) == vout { + log_trace!(self, "Input spending {}:{} resolves HTLC with payment hash {} from {}", input.previous_output.txid, input.previous_output.vout, log_bytes!(payment_hash.0), $source); payment_data = Some((source.clone(), *payment_hash)); } } if payment_data.is_none() { for htlc_output in $htlc_outputs { if input.previous_output.vout == htlc_output.transaction_output_index { - log_info!(self, "Inbound HTLC timeout at {} from {} resolved by {}", input.previous_output.vout, input.previous_output.txid, tx.txid()); + log_info!(self, "Input spending {}:{} in {} resolves inbound HTLC with timeout from {}", input.previous_output.txid, input.previous_output.vout, tx.txid(), $source); continue 'outer_loop; } } @@ -1797,23 +1806,30 @@ impl ChannelMonitor { if let Some(ref current_local_signed_commitment_tx) = self.current_local_signed_commitment_tx { if input.previous_output.txid == current_local_signed_commitment_tx.txid { - scan_commitment!(current_local_signed_commitment_tx.htlc_outputs.iter().map(|&(ref a, _, _)| a), current_local_signed_commitment_tx.htlc_sources); + scan_commitment!(current_local_signed_commitment_tx.htlc_outputs.iter().map(|&(ref a, _, _)| a), + current_local_signed_commitment_tx.htlc_sources, + "our latest local commitment tx"); } } if let Some(ref prev_local_signed_commitment_tx) = self.prev_local_signed_commitment_tx { if input.previous_output.txid == prev_local_signed_commitment_tx.txid { - scan_commitment!(prev_local_signed_commitment_tx.htlc_outputs.iter().map(|&(ref a, _, _)| a), prev_local_signed_commitment_tx.htlc_sources); + scan_commitment!(prev_local_signed_commitment_tx.htlc_outputs.iter().map(|&(ref a, _, _)| a), + prev_local_signed_commitment_tx.htlc_sources, + "our latest local commitment tx"); } } if let Some(&(ref htlc_outputs, ref htlc_sources)) = self.remote_claimable_outpoints.get(&input.previous_output.txid) { - scan_commitment!(htlc_outputs, htlc_sources); + scan_commitment!(htlc_outputs, htlc_sources, "remote commitment tx"); } // If tx isn't solving htlc output from local/remote commitment tx and htlc isn't outbound we don't need // to broadcast solving backward if let Some((source, payment_hash)) = payment_data { let mut payment_preimage = PaymentPreimage([0; 32]); - if input.witness.len() == 5 && input.witness[4].len() == ACCEPTED_HTLC_SCRIPT_WEIGHT { + if (input.witness.len() == 3 && input.witness[2].len() == OFFERED_HTLC_SCRIPT_WEIGHT && input.witness[1].len() == 33) + || (input.witness.len() == 3 && input.witness[2].len() == ACCEPTED_HTLC_SCRIPT_WEIGHT && input.witness[1].len() == 33) { + log_error!(self, "Remote used revocation sig to take a {} HTLC output at index {} from commitment_tx {}", if input.witness[2].len() == OFFERED_HTLC_SCRIPT_WEIGHT { "offered" } else { "accepted" }, input.previous_output.vout, input.previous_output.txid); + } else if input.witness.len() == 5 && input.witness[4].len() == ACCEPTED_HTLC_SCRIPT_WEIGHT { payment_preimage.0.copy_from_slice(&tx.input[0].witness[3]); htlc_updated.push((source, Some(payment_preimage), payment_hash)); } else if input.witness.len() == 3 && input.witness[2].len() == OFFERED_HTLC_SCRIPT_WEIGHT {