X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fchain%2Fchannelmonitor.rs;h=37c3383a3ad566942efcc965742bb6099c53b5c2;hb=b06a652e585735b3d37a795b03c0246026baa1e2;hp=a74c18e725d2bc0a5ec58614bf3cdcf622bed2b0;hpb=830220393f04a7be0418ef0d390fb51ab0215ad0;p=rust-lightning diff --git a/lightning/src/chain/channelmonitor.rs b/lightning/src/chain/channelmonitor.rs index a74c18e7..37c3383a 100644 --- a/lightning/src/chain/channelmonitor.rs +++ b/lightning/src/chain/channelmonitor.rs @@ -22,27 +22,27 @@ use bitcoin::blockdata::block::BlockHeader; use bitcoin::blockdata::transaction::{OutPoint as BitcoinOutPoint, TxOut, Transaction}; -use bitcoin::blockdata::script::{Script, Builder}; -use bitcoin::blockdata::opcodes; +use bitcoin::blockdata::script::Script; use bitcoin::hashes::Hash; use bitcoin::hashes::sha256::Hash as Sha256; -use bitcoin::hash_types::{Txid, BlockHash, WPubkeyHash}; +use bitcoin::hash_types::{Txid, BlockHash}; use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature}; use bitcoin::secp256k1::{SecretKey, PublicKey}; -use bitcoin::secp256k1; +use bitcoin::{secp256k1, EcdsaSighashType}; +use crate::ln::channel::INITIAL_COMMITMENT_NUMBER; 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}; use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator}; use crate::chain::transaction::{OutPoint, TransactionData}; -use crate::sign::{SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, WriteableEcdsaChannelSigner, SignerProvider, EntropySource}; +use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, WriteableEcdsaChannelSigner, SignerProvider, EntropySource}; use crate::chain::onchaintx::{ClaimEvent, OnchainTxHandler}; use crate::chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderFundingOutput, HolderHTLCOutput, PackageSolvingData, PackageTemplate, RevokedOutput, RevokedHTLCOutput}; use crate::chain::Filter; @@ -50,7 +50,7 @@ use crate::util::logger::Logger; use crate::util::ser::{Readable, ReadableArgs, RequiredWrapper, MaybeReadable, UpgradableRequired, Writer, Writeable, U48}; use crate::util::byte_utils; use crate::events::{Event, EventHandler}; -use crate::events::bump_transaction::{ChannelDerivationParameters, AnchorDescriptor, HTLCDescriptor, BumpTransactionEvent}; +use crate::events::bump_transaction::{AnchorDescriptor, BumpTransactionEvent}; use crate::prelude::*; use core::{cmp, mem}; @@ -66,7 +66,7 @@ use crate::sync::{Mutex, LockTestExt}; /// much smaller than a full [`ChannelMonitor`]. However, for large single commitment transaction /// updates (e.g. ones during which there are hundreds of HTLCs pending on the commitment /// transaction), a single update may reach upwards of 1 MiB in serialized size. -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq)] #[must_use] pub struct ChannelMonitorUpdate { pub(crate) updates: Vec, @@ -133,7 +133,7 @@ pub enum MonitorEvent { HTLCEvent(HTLCUpdate), /// A monitor event that the Channel's commitment transaction was confirmed. - CommitmentTxConfirmed(OutPoint), + HolderForceClosed(OutPoint), /// Indicates a [`ChannelMonitor`] update has completed. See /// [`ChannelMonitorUpdateStatus::InProgress`] for more information on how this is used. @@ -149,24 +149,18 @@ pub enum MonitorEvent { /// same [`ChannelMonitor`] have been applied and persisted. monitor_update_id: u64, }, - - /// Indicates a [`ChannelMonitor`] update has failed. See - /// [`ChannelMonitorUpdateStatus::PermanentFailure`] for more information on how this is used. - /// - /// [`ChannelMonitorUpdateStatus::PermanentFailure`]: super::ChannelMonitorUpdateStatus::PermanentFailure - UpdateFailed(OutPoint), } impl_writeable_tlv_based_enum_upgradable!(MonitorEvent, - // Note that Completed and UpdateFailed are currently never serialized to disk as they are - // generated only in ChainMonitor + // Note that Completed is currently never serialized to disk as it is generated only in + // ChainMonitor. (0, Completed) => { (0, funding_txo, required), (2, monitor_update_id, required), }, ; (2, HTLCEvent), - (4, CommitmentTxConfirmed), - (6, UpdateFailed), + (4, HolderForceClosed), + // 6 was `UpdateFailed` until LDK 0.0.117 ); /// Simple structure sent back by `chain::Watch` when an HTLC from a forward channel is detected on @@ -486,7 +480,7 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent, ); -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub(crate) enum ChannelMonitorUpdateStep { LatestHolderCommitmentTXInfo { commitment_tx: HolderCommitmentTransaction, @@ -502,6 +496,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 +541,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) => { @@ -882,6 +882,14 @@ pub(crate) struct ChannelMonitorImpl { /// The node_id of our counterparty counterparty_node_id: Option, + + /// Initial counterparty commmitment data needed to recreate the commitment tx + /// in the persistence pipeline for third-party watchtowers. This will only be present on + /// monitors created after 0.0.117. + /// + /// Ordering of tuple data: (their_per_commitment_point, feerate_per_kw, to_broadcaster_sats, + /// to_countersignatory_sats) + initial_counterparty_commitment_info: Option<(PublicKey, u32, u64, u64)>, } /// Transaction outputs to watch for on-chain spends. @@ -1022,7 +1030,7 @@ impl Writeable for ChannelMonitorImpl true, - MonitorEvent::CommitmentTxConfirmed(_) => true, + MonitorEvent::HolderForceClosed(_) => true, _ => false, }).count() as u64).to_be_bytes())?; for event in self.pending_monitor_events.iter() { @@ -1031,7 +1039,7 @@ impl Writeable for ChannelMonitorImpl 1u8.write(writer)?, + MonitorEvent::HolderForceClosed(_) => 1u8.write(writer)?, _ => {}, // Covered in the TLV writes below } } @@ -1072,6 +1080,7 @@ impl Writeable for ChannelMonitorImpl ChannelMonitor { best_block: BestBlock, counterparty_node_id: PublicKey) -> ChannelMonitor { assert!(commitment_transaction_number_obscure_factor <= (1 << 48)); - let payment_key_hash = WPubkeyHash::hash(&keys.pubkeys().payment_point.serialize()); - let counterparty_payment_script = Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0).push_slice(&payment_key_hash[..]).into_script(); + let counterparty_payment_script = chan_utils::get_counterparty_payment_script( + &channel_parameters.channel_type_features, &keys.pubkeys().payment_point + ); let counterparty_channel_parameters = channel_parameters.counterparty_parameters.as_ref().unwrap(); let counterparty_delayed_payment_base_key = counterparty_channel_parameters.pubkeys.delayed_payment_basepoint; @@ -1162,9 +1172,10 @@ impl ChannelMonitor { (holder_commitment_tx, trusted_tx.commitment_number()) }; - let onchain_tx_handler = - OnchainTxHandler::new(destination_script.clone(), keys, - channel_parameters.clone(), initial_holder_commitment_tx, secp_ctx); + let onchain_tx_handler = OnchainTxHandler::new( + channel_value_satoshis, channel_keys_id, destination_script.clone(), keys, + channel_parameters.clone(), initial_holder_commitment_tx, secp_ctx + ); let mut outputs_to_watch = HashMap::new(); outputs_to_watch.insert(funding_info.0.txid, vec![(funding_info.0.index as u32, funding_info.1.clone())]); @@ -1222,6 +1233,7 @@ impl ChannelMonitor { best_block, counterparty_node_id: Some(counterparty_node_id), + initial_counterparty_commitment_info: None, }) } @@ -1230,11 +1242,31 @@ impl ChannelMonitor { self.inner.lock().unwrap().provide_secret(idx, secret) } + /// A variant of `Self::provide_latest_counterparty_commitment_tx` used to provide + /// additional information to the monitor to store in order to recreate the initial + /// counterparty commitment transaction during persistence (mainly for use in third-party + /// watchtowers). + /// + /// This is used to provide the counterparty commitment information directly to the monitor + /// before the initial persistence of a new channel. + pub(crate) fn provide_initial_counterparty_commitment_tx( + &self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option>)>, + commitment_number: u64, their_cur_per_commitment_point: PublicKey, feerate_per_kw: u32, + to_broadcaster_value_sat: u64, to_countersignatory_value_sat: u64, logger: &L, + ) + where L::Target: Logger + { + self.inner.lock().unwrap().provide_initial_counterparty_commitment_tx(txid, + htlc_outputs, commitment_number, their_cur_per_commitment_point, feerate_per_kw, + to_broadcaster_value_sat, to_countersignatory_value_sat, logger); + } + /// Informs this monitor of the latest counterparty (ie non-broadcastable) commitment transaction. /// The monitor watches for it to be broadcasted and then uses the HTLC information (and /// possibly future revocation/preimage information) to claim outputs where possible. /// We cache also the mapping hash:commitment number to lighten pruning of old preimages by watchtowers. - pub(crate) fn provide_latest_counterparty_commitment_tx( + #[cfg(test)] + fn provide_latest_counterparty_commitment_tx( &self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option>)>, @@ -1280,7 +1312,7 @@ impl ChannelMonitor { &self, updates: &ChannelMonitorUpdate, broadcaster: &B, - fee_estimator: F, + fee_estimator: &F, logger: &L, ) -> Result<(), ()> where @@ -1370,6 +1402,67 @@ impl ChannelMonitor { ret } + /// Gets the counterparty's initial commitment transaction. The returned commitment + /// transaction is unsigned. This is intended to be called during the initial persistence of + /// the monitor (inside an implementation of [`Persist::persist_new_channel`]), to allow for + /// watchtowers in the persistence pipeline to have enough data to form justice transactions. + /// + /// This is similar to [`Self::counterparty_commitment_txs_from_update`], except + /// that for the initial commitment transaction, we don't have a corresponding update. + /// + /// This will only return `Some` for channel monitors that have been created after upgrading + /// to LDK 0.0.117+. + /// + /// [`Persist::persist_new_channel`]: crate::chain::chainmonitor::Persist::persist_new_channel + pub fn initial_counterparty_commitment_tx(&self) -> Option { + self.inner.lock().unwrap().initial_counterparty_commitment_tx() + } + + /// 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. Once revoked, signing a justice transaction can be done using + /// [`Self::sign_to_local_justice_tx`]. + /// + /// 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) + } + + /// Wrapper around [`EcdsaChannelSigner::sign_justice_revoked_output`] to make + /// signing the justice transaction easier for implementors of + /// [`chain::chainmonitor::Persist`]. On success this method returns the provided transaction + /// signing the input at `input_idx`. This method will only produce a valid signature for + /// a transaction spending the `to_local` output of a commitment transaction, i.e. this cannot + /// be used for revoked HTLC outputs. + /// + /// `Value` is the value of the output being spent by the input at `input_idx`, committed + /// in the BIP 143 signature. + /// + /// This method will only succeed if this monitor has received the revocation secret for the + /// provided `commitment_number`. If a commitment number is provided that does not correspond + /// to the commitment transaction being revoked, this will return a signed transaction, but + /// the signature will not be valid. + /// + /// [`EcdsaChannelSigner::sign_justice_revoked_output`]: crate::sign::EcdsaChannelSigner::sign_justice_revoked_output + /// [`Persist`]: crate::chain::chainmonitor::Persist + pub fn sign_to_local_justice_tx(&self, justice_tx: Transaction, input_idx: usize, value: u64, commitment_number: u64) -> Result { + self.inner.lock().unwrap().sign_to_local_justice_tx(justice_tx, input_idx, value, commitment_number) + } + pub(crate) fn get_min_seen_secret(&self) -> u64 { self.inner.lock().unwrap().get_min_seen_secret() } @@ -1390,21 +1483,20 @@ impl ChannelMonitor { self.inner.lock().unwrap().counterparty_node_id } - /// Used by ChannelManager deserialization to broadcast the latest holder state if its copy of - /// the Channel was out-of-date. + /// Used by [`ChannelManager`] deserialization to broadcast the latest holder state if its copy + /// of the channel state was out-of-date. /// /// You may also use this to broadcast the latest local commitment transaction, either because - /// a monitor update failed with [`ChannelMonitorUpdateStatus::PermanentFailure`] or because we've - /// fallen behind (i.e. we've received proof that our counterparty side knows a revocation - /// secret we gave them that they shouldn't know). + /// a monitor update failed or because we've fallen behind (i.e. we've received proof that our + /// counterparty side knows a revocation secret we gave them that they shouldn't know). /// /// Broadcasting these transactions in the second case is UNSAFE, as they allow counterparty /// side to punish you. Nevertheless you may want to broadcast them if counterparty doesn't /// close channel with their commitment transaction after a substantial amount of time. Best /// may be to contact the other node operator out-of-band to coordinate other options available - /// to you. In any-case, the choice is up to you. + /// to you. /// - /// [`ChannelMonitorUpdateStatus::PermanentFailure`]: super::ChannelMonitorUpdateStatus::PermanentFailure + /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager pub fn get_latest_holder_commitment_txn(&self, logger: &L) -> Vec where L::Target: Logger { self.inner.lock().unwrap().get_latest_holder_commitment_txn(logger) @@ -1578,6 +1670,49 @@ impl ChannelMonitor { current_height, &broadcaster, &fee_estimator, &logger, ); } + + /// Returns the descriptors for relevant outputs (i.e., those that we can spend) within the + /// transaction if they exist and the transaction has at least [`ANTI_REORG_DELAY`] + /// confirmations. For [`SpendableOutputDescriptor::DelayedPaymentOutput`] descriptors to be + /// returned, the transaction must have at least `max(ANTI_REORG_DELAY, to_self_delay)` + /// confirmations. + /// + /// Descriptors returned by this method are primarily exposed via [`Event::SpendableOutputs`] + /// once they are no longer under reorg risk. This method serves as a way to retrieve these + /// descriptors at a later time, either for historical purposes, or to replay any + /// missed/unhandled descriptors. For the purpose of gathering historical records, if the + /// channel close has fully resolved (i.e., [`ChannelMonitor::get_claimable_balances`] returns + /// an empty set), you can retrieve all spendable outputs by providing all descendant spending + /// transactions starting from the channel's funding transaction and going down three levels. + /// + /// `tx` is a transaction we'll scan the outputs of. Any transaction can be provided. If any + /// outputs which can be spent by us are found, at least one descriptor is returned. + /// + /// `confirmation_height` must be the height of the block in which `tx` was included in. + pub fn get_spendable_outputs(&self, tx: &Transaction, confirmation_height: u32) -> Vec { + let inner = self.inner.lock().unwrap(); + let current_height = inner.best_block.height; + let mut spendable_outputs = inner.get_spendable_outputs(tx); + spendable_outputs.retain(|descriptor| { + let mut conf_threshold = current_height.saturating_sub(ANTI_REORG_DELAY) + 1; + if let SpendableOutputDescriptor::DelayedPaymentOutput(descriptor) = descriptor { + conf_threshold = cmp::min(conf_threshold, + current_height.saturating_sub(descriptor.to_self_delay as u32) + 1); + } + conf_threshold >= confirmation_height + }); + spendable_outputs + } + + #[cfg(test)] + pub fn get_counterparty_payment_script(&self) -> Script{ + self.inner.lock().unwrap().counterparty_payment_script.clone() + } + + #[cfg(test)] + pub fn set_counterparty_payment_script(&self, script: Script) { + self.inner.lock().unwrap().counterparty_payment_script = script; + } } impl ChannelMonitorImpl { @@ -1617,7 +1752,19 @@ impl ChannelMonitorImpl { }, OnchainEvent::MaturingOutput { descriptor: SpendableOutputDescriptor::DelayedPaymentOutput(ref descriptor) } - if descriptor.outpoint.index as u32 == htlc_commitment_tx_output_idx => { + if event.transaction.as_ref().map(|tx| tx.input.iter().enumerate() + .any(|(input_idx, inp)| + Some(inp.previous_output.txid) == confirmed_txid && + inp.previous_output.vout == htlc_commitment_tx_output_idx && + // A maturing output for an HTLC claim will always be at the same + // index as the HTLC input. This is true pre-anchors, as there's + // only 1 input and 1 output. This is also true post-anchors, + // because we have a SIGHASH_SINGLE|ANYONECANPAY signature from our + // channel counterparty. + descriptor.outpoint.index as usize == input_idx + )) + .unwrap_or(false) + => { debug_assert!(holder_delayed_output_pending.is_none()); holder_delayed_output_pending = Some(event.confirmation_threshold()); }, @@ -1758,8 +1905,7 @@ impl ChannelMonitor { /// confirmations on the claim transaction. /// /// Note that for `ChannelMonitors` which track a channel which went on-chain with versions of - /// LDK prior to 0.0.111, balances may not be fully captured if our counterparty broadcasted - /// a revoked state. + /// LDK prior to 0.0.111, not all or excess balances may be included. /// /// See [`Balance`] for additional details on the types of claimable balances which /// may be returned here and their meanings. @@ -2122,7 +2268,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); } @@ -2145,6 +2291,7 @@ macro_rules! fail_unbroadcast_htlcs { #[cfg(test)] pub fn deliberately_bogus_accepted_htlc_witness_program() -> Vec { + use bitcoin::blockdata::opcodes; let mut ret = [opcodes::all::OP_NOP.to_u8(); 136]; ret[131] = opcodes::all::OP_DROP.to_u8(); ret[132] = opcodes::all::OP_DROP.to_u8(); @@ -2226,6 +2373,25 @@ impl ChannelMonitorImpl { Ok(()) } + pub(crate) fn provide_initial_counterparty_commitment_tx( + &mut self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option>)>, + commitment_number: u64, their_per_commitment_point: PublicKey, feerate_per_kw: u32, + to_broadcaster_value: u64, to_countersignatory_value: u64, logger: &L + ) + where L::Target: Logger + { + self.initial_counterparty_commitment_info = Some((their_per_commitment_point.clone(), + feerate_per_kw, to_broadcaster_value, to_countersignatory_value)); + + #[cfg(debug_assertions)] { + let rebuilt_commitment_tx = self.initial_counterparty_commitment_tx().unwrap(); + debug_assert_eq!(rebuilt_commitment_tx.trust().txid(), txid); + } + + self.provide_latest_counterparty_commitment_tx(txid, htlc_outputs, commitment_number, + their_per_commitment_point, logger); + } + pub(crate) fn provide_latest_counterparty_commitment_tx(&mut self, txid: Txid, htlc_outputs: Vec<(HTLCOutputInCommitment, Option>)>, commitment_number: u64, their_per_commitment_point: PublicKey, logger: &L) where L::Target: Logger { // TODO: Encrypt the htlc_outputs data with the single-hash of the commitment transaction // so that a remote monitor doesn't learn anything unless there is a malicious close. @@ -2366,6 +2532,18 @@ impl ChannelMonitorImpl { { self.payment_preimages.insert(payment_hash.clone(), payment_preimage.clone()); + let confirmed_spend_txid = self.funding_spend_confirmed.or_else(|| { + self.onchain_events_awaiting_threshold_conf.iter().find_map(|event| match event.event { + OnchainEvent::FundingSpendConfirmation { .. } => Some(event.txid), + _ => None, + }) + }); + let confirmed_spend_txid = if let Some(txid) = confirmed_spend_txid { + txid + } else { + return; + }; + // If the channel is force closed, try to claim the output from this preimage. // First check if a counterparty commitment transaction has been broadcasted: macro_rules! claim_htlcs { @@ -2375,14 +2553,24 @@ impl ChannelMonitorImpl { } } if let Some(txid) = self.current_counterparty_commitment_txid { - if let Some(commitment_number) = self.counterparty_commitment_txn_on_chain.get(&txid) { - claim_htlcs!(*commitment_number, txid); + if txid == confirmed_spend_txid { + if let Some(commitment_number) = self.counterparty_commitment_txn_on_chain.get(&txid) { + claim_htlcs!(*commitment_number, txid); + } else { + debug_assert!(false); + log_error!(logger, "Detected counterparty commitment tx on-chain without tracking commitment number"); + } return; } } if let Some(txid) = self.prev_counterparty_commitment_txid { - if let Some(commitment_number) = self.counterparty_commitment_txn_on_chain.get(&txid) { - claim_htlcs!(*commitment_number, txid); + if txid == confirmed_spend_txid { + if let Some(commitment_number) = self.counterparty_commitment_txn_on_chain.get(&txid) { + claim_htlcs!(*commitment_number, txid); + } else { + debug_assert!(false); + log_error!(logger, "Detected counterparty commitment tx on-chain without tracking commitment number"); + } return; } } @@ -2393,13 +2581,22 @@ impl ChannelMonitorImpl { // *we* sign a holder commitment transaction, not when e.g. a watchtower broadcasts one of our // holder commitment transactions. if self.broadcasted_holder_revokable_script.is_some() { - // Assume that the broadcasted commitment transaction confirmed in the current best - // block. Even if not, its a reasonable metric for the bump criteria on the HTLC - // transactions. - let (claim_reqs, _) = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx, self.best_block.height()); - self.onchain_tx_handler.update_claims_view_from_requests(claim_reqs, self.best_block.height(), self.best_block.height(), broadcaster, fee_estimator, logger); - if let Some(ref tx) = self.prev_holder_signed_commitment_tx { - let (claim_reqs, _) = self.get_broadcasted_holder_claims(&tx, self.best_block.height()); + let holder_commitment_tx = if self.current_holder_commitment_tx.txid == confirmed_spend_txid { + Some(&self.current_holder_commitment_tx) + } else if let Some(prev_holder_commitment_tx) = &self.prev_holder_signed_commitment_tx { + if prev_holder_commitment_tx.txid == confirmed_spend_txid { + Some(prev_holder_commitment_tx) + } else { + None + } + } else { + None + }; + if let Some(holder_commitment_tx) = holder_commitment_tx { + // Assume that the broadcasted commitment transaction confirmed in the current best + // block. Even if not, its a reasonable metric for the bump criteria on the HTLC + // transactions. + let (claim_reqs, _) = self.get_broadcasted_holder_claims(&holder_commitment_tx, self.best_block.height()); self.onchain_tx_handler.update_claims_view_from_requests(claim_reqs, self.best_block.height(), self.best_block.height(), broadcaster, fee_estimator, logger); } } @@ -2416,10 +2613,10 @@ impl ChannelMonitorImpl { txs.push(tx); } broadcaster.broadcast_transactions(&txs); - self.pending_monitor_events.push(MonitorEvent::CommitmentTxConfirmed(self.funding_info.0)); + self.pending_monitor_events.push(MonitorEvent::HolderForceClosed(self.funding_info.0)); } - pub fn update_monitor(&mut self, updates: &ChannelMonitorUpdate, broadcaster: &B, fee_estimator: F, logger: &L) -> Result<(), ()> + pub fn update_monitor(&mut self, updates: &ChannelMonitorUpdate, broadcaster: &B, fee_estimator: &F, logger: &L) -> Result<(), ()> where B::Target: BroadcasterInterface, F::Target: FeeEstimator, L::Target: Logger, @@ -2459,7 +2656,7 @@ impl ChannelMonitorImpl { panic!("Attempted to apply ChannelMonitorUpdates out of order, check the update_id before passing an update to update_monitor!"); } let mut ret = Ok(()); - let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&*fee_estimator); + let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&**fee_estimator); for update in updates.updates.iter() { match update { ChannelMonitorUpdateStep::LatestHolderCommitmentTXInfo { commitment_tx, htlc_outputs, claimed_htlcs, nondust_htlc_sources } => { @@ -2471,7 +2668,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) }, @@ -2482,6 +2679,7 @@ impl ChannelMonitorImpl { ChannelMonitorUpdateStep::CommitmentSecret { idx, secret } => { log_trace!(logger, "Updating ChannelMonitor with commitment secret"); if let Err(e) = self.provide_secret(*idx, *secret) { + debug_assert!(false, "Latest counterparty commitment secret was invalid"); log_error!(logger, "Providing latest counterparty commitment secret failed/was refused:"); log_error!(logger, " {}", e); ret = Err(()); @@ -2525,10 +2723,10 @@ impl ChannelMonitorImpl { } } else if !self.holder_tx_signed { log_error!(logger, "WARNING: You have a potentially-unsafe holder commitment transaction available to broadcast"); - log_error!(logger, " in channel monitor for channel {}!", log_bytes!(self.funding_info.0.to_channel_id())); + log_error!(logger, " in channel monitor for channel {}!", &self.funding_info.0.to_channel_id()); log_error!(logger, " Read the docs for ChannelMonitor::get_latest_holder_commitment_txn and take manual action!"); } else { - // If we generated a MonitorEvent::CommitmentTxConfirmed, the ChannelManager + // If we generated a MonitorEvent::HolderForceClosed, the ChannelManager // will still give us a ChannelForceClosed event with !should_broadcast, but we // shouldn't print the scary warning above. log_info!(logger, "Channel off-chain state closed after we broadcasted our latest commitment transaction."); @@ -2543,6 +2741,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 { @@ -2634,6 +2836,7 @@ impl ChannelMonitorImpl { per_commitment_point: self.onchain_tx_handler.signer.get_per_commitment_point( htlc.per_commitment_number, &self.onchain_tx_handler.secp_ctx, ), + feerate_per_kw: 0, htlc: htlc.htlc, preimage: htlc.preimage, counterparty_sig: htlc.counterparty_sig, @@ -2651,6 +2854,91 @@ impl ChannelMonitorImpl { ret } + pub(crate) fn initial_counterparty_commitment_tx(&mut self) -> Option { + let (their_per_commitment_point, feerate_per_kw, to_broadcaster_value, + to_countersignatory_value) = self.initial_counterparty_commitment_info?; + let htlc_outputs = vec![]; + + let commitment_tx = self.build_counterparty_commitment_tx(INITIAL_COMMITMENT_NUMBER, + &their_per_commitment_point, to_broadcaster_value, to_countersignatory_value, + feerate_per_kw, htlc_outputs); + Some(commitment_tx) + } + + 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() + } + + pub(crate) fn sign_to_local_justice_tx( + &self, mut justice_tx: Transaction, input_idx: usize, value: u64, commitment_number: u64 + ) -> Result { + let secret = self.get_secret(commitment_number).ok_or(())?; + let per_commitment_key = SecretKey::from_slice(&secret).map_err(|_| ())?; + let their_per_commitment_point = PublicKey::from_secret_key( + &self.onchain_tx_handler.secp_ctx, &per_commitment_key); + + let revocation_pubkey = chan_utils::derive_public_revocation_key( + &self.onchain_tx_handler.secp_ctx, &their_per_commitment_point, + &self.holder_revocation_basepoint); + let delayed_key = chan_utils::derive_public_key(&self.onchain_tx_handler.secp_ctx, + &their_per_commitment_point, + &self.counterparty_commitment_params.counterparty_delayed_payment_base_key); + let revokeable_redeemscript = chan_utils::get_revokeable_redeemscript(&revocation_pubkey, + self.counterparty_commitment_params.on_counterparty_tx_csv, &delayed_key); + + let sig = self.onchain_tx_handler.signer.sign_justice_revoked_output( + &justice_tx, input_idx, value, &per_commitment_key, &self.onchain_tx_handler.secp_ctx)?; + justice_tx.input[input_idx].witness.push_bitcoin_signature(&sig.serialize_der(), EcdsaSighashType::All); + justice_tx.input[input_idx].witness.push(&[1u8]); + justice_tx.input[input_idx].witness.push(revokeable_redeemscript.as_bytes()); + Ok(justice_tx) + } + /// 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) @@ -3068,7 +3356,7 @@ impl ChannelMonitorImpl { continue; } } else { None }; - if let Some(htlc_tx) = self.onchain_tx_handler.unsafe_get_fully_signed_htlc_tx( + if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx( &::bitcoin::OutPoint { txid, vout }, &preimage) { holder_transactions.push(htlc_tx); } @@ -3183,7 +3471,7 @@ impl ChannelMonitorImpl { if prevout.txid == self.funding_info.0.txid && prevout.vout == self.funding_info.0.index as u32 { let mut balance_spendable_csv = None; log_info!(logger, "Channel {} closed by funding output spend in txid {}.", - log_bytes!(self.funding_info.0.to_channel_id()), txid); + &self.funding_info.0.to_channel_id(), txid); 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.0 >> 8*3) as u8 == 0x20 { @@ -3241,7 +3529,7 @@ impl ChannelMonitorImpl { } self.is_resolving_htlc_output(&tx, height, &block_hash, &logger); - self.is_paying_spendable_output(&tx, height, &block_hash, &logger); + self.check_tx_and_push_spendable_outputs(&tx, height, &block_hash, &logger); } } @@ -3284,8 +3572,10 @@ impl ChannelMonitorImpl { let funding_outp = HolderFundingOutput::build(self.funding_redeemscript.clone(), self.channel_value_satoshis, self.onchain_tx_handler.channel_type_features().clone()); let commitment_package = PackageTemplate::build_package(self.funding_info.0.txid.clone(), self.funding_info.0.index as u32, PackageSolvingData::HolderFundingOutput(funding_outp), self.best_block.height(), self.best_block.height()); claimable_outpoints.push(commitment_package); - self.pending_monitor_events.push(MonitorEvent::CommitmentTxConfirmed(self.funding_info.0)); - let commitment_tx = self.onchain_tx_handler.get_fully_signed_holder_tx(&self.funding_redeemscript); + self.pending_monitor_events.push(MonitorEvent::HolderForceClosed(self.funding_info.0)); + // Although we aren't signing the transaction directly here, the transaction will be signed + // in the claim that is queued to OnchainTxHandler. We set holder_tx_signed here to reject + // new channel updates. self.holder_tx_signed = true; // We can't broadcast our HTLC transactions while the commitment transaction is // unconfirmed. We'll delay doing so until we detect the confirmed commitment in @@ -3295,7 +3585,8 @@ impl ChannelMonitorImpl { // assuming it gets confirmed in the next block. Sadly, we have code which considers // "not yet confirmed" things as discardable, so we cannot do that here. let (mut new_outpoints, _) = self.get_broadcasted_holder_claims(&self.current_holder_commitment_tx, self.best_block.height()); - let new_outputs = self.get_broadcasted_holder_watch_outputs(&self.current_holder_commitment_tx, &commitment_tx); + let unsigned_commitment_tx = self.onchain_tx_handler.get_unsigned_holder_commitment_tx(); + let new_outputs = self.get_broadcasted_holder_watch_outputs(&self.current_holder_commitment_tx, &unsigned_commitment_tx); if !new_outputs.is_empty() { watch_outputs.push((self.current_holder_commitment_tx.txid.clone(), new_outputs)); } @@ -3348,7 +3639,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, @@ -3365,7 +3656,8 @@ impl ChannelMonitorImpl { OnchainEvent::MaturingOutput { descriptor } => { log_debug!(logger, "Descriptor {} has got enough confirmations to be passed upstream", log_spendable!(descriptor)); self.pending_events.push(Event::SpendableOutputs { - outputs: vec![descriptor] + outputs: vec![descriptor], + channel_id: Some(self.funding_info.0.to_channel_id()), }); self.spendable_txids_confirmed.push(entry.txid); }, @@ -3624,12 +3916,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" }); } } @@ -3776,41 +4068,25 @@ 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); } } } } - /// Check if any transaction broadcasted is paying fund back to some address we can assume to own - fn is_paying_spendable_output(&mut self, tx: &Transaction, height: u32, block_hash: &BlockHash, logger: &L) where L::Target: Logger { - let mut spendable_output = None; - for (i, outp) in tx.output.iter().enumerate() { // There is max one spendable output for any channel tx, including ones generated by us - if i > ::core::u16::MAX as usize { - // While it is possible that an output exists on chain which is greater than the - // 2^16th output in a given transaction, this is only possible if the output is not - // in a lightning transaction and was instead placed there by some third party who - // wishes to give us money for no reason. - // Namely, any lightning transactions which we pre-sign will never have anywhere - // near 2^16 outputs both because such transactions must have ~2^16 outputs who's - // scripts are not longer than one byte in length and because they are inherently - // non-standard due to their size. - // Thus, it is completely safe to ignore such outputs, and while it may result in - // us ignoring non-lightning fund to us, that is only possible if someone fills - // nearly a full block with garbage just to hit this case. - continue; - } + fn get_spendable_outputs(&self, tx: &Transaction) -> Vec { + let mut spendable_outputs = Vec::new(); + for (i, outp) in tx.output.iter().enumerate() { if outp.script_pubkey == self.destination_script { - spendable_output = Some(SpendableOutputDescriptor::StaticOutput { + spendable_outputs.push(SpendableOutputDescriptor::StaticOutput { outpoint: OutPoint { txid: tx.txid(), index: i as u16 }, output: outp.clone(), }); - break; } if let Some(ref broadcasted_holder_revokable_script) = self.broadcasted_holder_revokable_script { if broadcasted_holder_revokable_script.0 == outp.script_pubkey { - spendable_output = Some(SpendableOutputDescriptor::DelayedPaymentOutput(DelayedPaymentOutputDescriptor { + spendable_outputs.push(SpendableOutputDescriptor::DelayedPaymentOutput(DelayedPaymentOutputDescriptor { outpoint: OutPoint { txid: tx.txid(), index: i as u16 }, per_commitment_point: broadcasted_holder_revokable_script.1, to_self_delay: self.on_holder_tx_csv, @@ -3819,27 +4095,33 @@ impl ChannelMonitorImpl { channel_keys_id: self.channel_keys_id, channel_value_satoshis: self.channel_value_satoshis, })); - break; } } if self.counterparty_payment_script == outp.script_pubkey { - spendable_output = Some(SpendableOutputDescriptor::StaticPaymentOutput(StaticPaymentOutputDescriptor { + spendable_outputs.push(SpendableOutputDescriptor::StaticPaymentOutput(StaticPaymentOutputDescriptor { outpoint: OutPoint { txid: tx.txid(), index: i as u16 }, output: outp.clone(), channel_keys_id: self.channel_keys_id, channel_value_satoshis: self.channel_value_satoshis, + channel_transaction_parameters: Some(self.onchain_tx_handler.channel_transaction_parameters.clone()), })); - break; } if self.shutdown_script.as_ref() == Some(&outp.script_pubkey) { - spendable_output = Some(SpendableOutputDescriptor::StaticOutput { + spendable_outputs.push(SpendableOutputDescriptor::StaticOutput { outpoint: OutPoint { txid: tx.txid(), index: i as u16 }, output: outp.clone(), }); - break; } } - if let Some(spendable_output) = spendable_output { + spendable_outputs + } + + /// Checks if the confirmed transaction is paying funds back to some address we can assume to + /// own. + fn check_tx_and_push_spendable_outputs( + &mut self, tx: &Transaction, height: u32, block_hash: &BlockHash, logger: &L, + ) where L::Target: Logger { + for spendable_output in self.get_spendable_outputs(tx) { let entry = OnchainEventEntry { txid: tx.txid(), transaction: Some(tx.clone()), @@ -3924,7 +4206,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP 1 => { None }, _ => return Err(DecodeError::InvalidValue), }; - let counterparty_payment_script = Readable::read(reader)?; + let mut counterparty_payment_script: Script = Readable::read(reader)?; let shutdown_script = { let script =