X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fchain%2Fchannelmonitor.rs;h=cb267524fb0ff18d1c2f312a8a5741efaa3300a9;hb=966465a282f91a91ec8b058a0dea5f7b0c6bf21c;hp=bde5c12abd90891beae05e6d8f91d03b19444707;hpb=14b761283bfa454f2d08439e3442c0e370f07cde;p=rust-lightning diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index bde5c12a..cb267524 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -36,7 +36,7 @@ use bitcoin::secp256k1; use crate::ln::{PaymentHash, PaymentPreimage}; use crate::ln::msgs::DecodeError; use crate::ln::chan_utils; -use crate::ln::chan_utils::{CounterpartyCommitmentSecrets, HTLCOutputInCommitment, HTLCClaim, ChannelTransactionParameters, HolderCommitmentTransaction}; +use crate::ln::chan_utils::{CommitmentTransaction, CounterpartyCommitmentSecrets, HTLCOutputInCommitment, HTLCClaim, ChannelTransactionParameters, HolderCommitmentTransaction, TxCreationKeys}; use crate::ln::channelmanager::{HTLCSource, SentHTLCId}; use crate::chain; use crate::chain::{BestBlock, WatchedOutput}; @@ -502,6 +502,9 @@ pub(crate) enum ChannelMonitorUpdateStep { htlc_outputs: Vec<(HTLCOutputInCommitment, Option>)>, commitment_number: u64, their_per_commitment_point: PublicKey, + feerate_per_kw: Option, + to_broadcaster_value_sat: Option, + to_countersignatory_value_sat: Option, }, PaymentPreimage { payment_preimage: PaymentPreimage, @@ -544,8 +547,11 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep, }, (1, LatestCounterpartyCommitmentTXInfo) => { (0, commitment_txid, required), + (1, feerate_per_kw, option), (2, commitment_number, required), + (3, to_broadcaster_value_sat, option), (4, their_per_commitment_point, required), + (5, to_countersignatory_value_sat, option), (6, htlc_outputs, required_vec), }, (2, PaymentPreimage) => { @@ -1370,6 +1376,29 @@ impl ChannelMonitor { ret } + /// Gets all of the counterparty commitment transactions provided by the given update. This + /// may be empty if the update doesn't include any new counterparty commitments. Returned + /// commitment transactions are unsigned. + /// + /// This is provided so that watchtower clients in the persistence pipeline are able to build + /// justice transactions for each counterparty commitment upon each update. It's intended to be + /// used within an implementation of [`Persist::update_persisted_channel`], which is provided + /// with a monitor and an update. + /// + /// It is expected that a watchtower client may use this method to retrieve the latest counterparty + /// commitment transaction(s), and then hold the necessary data until a later update in which + /// the monitor has been updated with the corresponding revocation data, at which point the + /// monitor can sign the justice transaction. + /// + /// This will only return a non-empty list for monitor updates that have been created after + /// upgrading to LDK 0.0.117+. Note that no restriction lies on the monitors themselves, which + /// may have been created prior to upgrading. + /// + /// [`Persist::update_persisted_channel`]: crate::chain::chainmonitor::Persist::update_persisted_channel + pub fn counterparty_commitment_txs_from_update(&self, update: &ChannelMonitorUpdate) -> Vec { + self.inner.lock().unwrap().counterparty_commitment_txs_from_update(update) + } + pub(crate) fn get_min_seen_secret(&self) -> u64 { self.inner.lock().unwrap().get_min_seen_secret() } @@ -2122,7 +2151,7 @@ macro_rules! fail_unbroadcast_htlcs { }, }; log_trace!($logger, "Failing HTLC with payment_hash {} from {} counterparty commitment tx due to broadcast of {} commitment transaction {}, waiting for confirmation (at height {})", - log_bytes!(htlc.payment_hash.0), $commitment_tx, $commitment_tx_type, + &htlc.payment_hash, $commitment_tx, $commitment_tx_type, $commitment_txid_confirmed, entry.confirmation_threshold()); $self.onchain_events_awaiting_threshold_conf.push(entry); } @@ -2471,7 +2500,7 @@ impl ChannelMonitorImpl { ret = Err(()); } } - ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number, their_per_commitment_point } => { + ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid, htlc_outputs, commitment_number, their_per_commitment_point, .. } => { log_trace!(logger, "Updating ChannelMonitor with latest counterparty commitment transaction info"); self.provide_latest_counterparty_commitment_tx(*commitment_txid, htlc_outputs.clone(), *commitment_number, *their_per_commitment_point, logger) }, @@ -2543,6 +2572,10 @@ impl ChannelMonitorImpl { } } + #[cfg(debug_assertions)] { + self.counterparty_commitment_txs_from_update(updates); + } + // If the updates succeeded and we were in an already closed channel state, then there's no // need to refuse any updates we expect to receive afer seeing a confirmed commitment. if ret.is_ok() && updates.update_id == CLOSED_CHANNEL_UPDATE_ID && self.latest_update_id == updates.update_id { @@ -2651,6 +2684,55 @@ impl ChannelMonitorImpl { ret } + fn build_counterparty_commitment_tx( + &self, commitment_number: u64, their_per_commitment_point: &PublicKey, + to_broadcaster_value: u64, to_countersignatory_value: u64, feerate_per_kw: u32, + mut nondust_htlcs: Vec<(HTLCOutputInCommitment, Option>)> + ) -> CommitmentTransaction { + let broadcaster_keys = &self.onchain_tx_handler.channel_transaction_parameters + .counterparty_parameters.as_ref().unwrap().pubkeys; + let countersignatory_keys = + &self.onchain_tx_handler.channel_transaction_parameters.holder_pubkeys; + + let broadcaster_funding_key = broadcaster_keys.funding_pubkey; + let countersignatory_funding_key = countersignatory_keys.funding_pubkey; + let keys = TxCreationKeys::from_channel_static_keys(&their_per_commitment_point, + &broadcaster_keys, &countersignatory_keys, &self.onchain_tx_handler.secp_ctx); + let channel_parameters = + &self.onchain_tx_handler.channel_transaction_parameters.as_counterparty_broadcastable(); + + CommitmentTransaction::new_with_auxiliary_htlc_data(commitment_number, + to_broadcaster_value, to_countersignatory_value, broadcaster_funding_key, + countersignatory_funding_key, keys, feerate_per_kw, &mut nondust_htlcs, + channel_parameters) + } + + pub(crate) fn counterparty_commitment_txs_from_update(&self, update: &ChannelMonitorUpdate) -> Vec { + update.updates.iter().filter_map(|update| { + match update { + &ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { commitment_txid, + ref htlc_outputs, commitment_number, their_per_commitment_point, + feerate_per_kw: Some(feerate_per_kw), + to_broadcaster_value_sat: Some(to_broadcaster_value), + to_countersignatory_value_sat: Some(to_countersignatory_value) } => { + + let nondust_htlcs = htlc_outputs.iter().filter_map(|(htlc, _)| { + htlc.transaction_output_index.map(|_| (htlc.clone(), None)) + }).collect::>(); + + let commitment_tx = self.build_counterparty_commitment_tx(commitment_number, + &their_per_commitment_point, to_broadcaster_value, + to_countersignatory_value, feerate_per_kw, nondust_htlcs); + + debug_assert_eq!(commitment_tx.trust().txid(), commitment_txid); + + Some(commitment_tx) + }, + _ => None, + } + }).collect() + } + /// Can only fail if idx is < get_min_seen_secret fn get_secret(&self, idx: u64) -> Option<[u8; 32]> { self.commitment_secrets.get_secret(idx) @@ -3348,7 +3430,7 @@ impl ChannelMonitorImpl { } log_debug!(logger, "HTLC {} failure update in {} has got enough confirmations to be passed upstream", - log_bytes!(payment_hash.0), entry.txid); + &payment_hash, entry.txid); self.pending_monitor_events.push(MonitorEvent::HTLCEvent(HTLCUpdate { payment_hash, payment_preimage: None, @@ -3625,12 +3707,12 @@ impl ChannelMonitorImpl { (outbound_htlc && !$source_avail && (accepted_preimage_claim || offered_preimage_claim)) { log_error!(logger, "Input spending {} ({}:{}) in {} resolves {} HTLC with payment hash {} with {}!", $tx_info, input.previous_output.txid, input.previous_output.vout, tx.txid(), - if outbound_htlc { "outbound" } else { "inbound" }, log_bytes!($htlc.payment_hash.0), + if outbound_htlc { "outbound" } else { "inbound" }, &$htlc.payment_hash, if revocation_sig_claim { "revocation sig" } else { "preimage claim after we'd passed the HTLC resolution back. We can likely claim the HTLC output with a revocation claim" }); } else { log_info!(logger, "Input spending {} ({}:{}) in {} resolves {} HTLC with payment hash {} with {}", $tx_info, input.previous_output.txid, input.previous_output.vout, tx.txid(), - if outbound_htlc { "outbound" } else { "inbound" }, log_bytes!($htlc.payment_hash.0), + if outbound_htlc { "outbound" } else { "inbound" }, &$htlc.payment_hash, if revocation_sig_claim { "revocation sig" } else if accepted_preimage_claim || offered_preimage_claim { "preimage" } else { "timeout" }); } } @@ -3777,7 +3859,7 @@ impl ChannelMonitorImpl { commitment_tx_output_idx: Some(input.previous_output.vout), }, }; - log_info!(logger, "Failing HTLC with payment_hash {} timeout by a spend tx, waiting for confirmation (at height {})", log_bytes!(payment_hash.0), entry.confirmation_threshold()); + log_info!(logger, "Failing HTLC with payment_hash {} timeout by a spend tx, waiting for confirmation (at height {})", &payment_hash, entry.confirmation_threshold()); self.onchain_events_awaiting_threshold_conf.push(entry); } }