Merge pull request #2583 from Evanfeenstra/pub-make-onion
[rust-lightning] / lightning / src / chain / channelmonitor.rs
index 0c207fa8b17429b32e31f1eda65ea0270dcdad82..3f9c83bb54393290c40b9a6784bcce7dd48c53da 100644 (file)
@@ -31,7 +31,7 @@ use bitcoin::hash_types::{Txid, BlockHash, WPubkeyHash};
 
 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};
@@ -67,7 +67,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<ChannelMonitorUpdateStep>,
@@ -134,7 +134,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.
@@ -150,24 +150,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
@@ -487,7 +481,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,
@@ -1037,7 +1031,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signe
 
                writer.write_all(&(self.pending_monitor_events.iter().filter(|ev| match ev {
                        MonitorEvent::HTLCEvent(_) => true,
-                       MonitorEvent::CommitmentTxConfirmed(_) => true,
+                       MonitorEvent::HolderForceClosed(_) => true,
                        _ => false,
                }).count() as u64).to_be_bytes())?;
                for event in self.pending_monitor_events.iter() {
@@ -1046,7 +1040,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Writeable for ChannelMonitorImpl<Signe
                                        0u8.write(writer)?;
                                        upd.write(writer)?;
                                },
-                               MonitorEvent::CommitmentTxConfirmed(_) => 1u8.write(writer)?,
+                               MonitorEvent::HolderForceClosed(_) => 1u8.write(writer)?,
                                _ => {}, // Covered in the TLV writes below
                        }
                }
@@ -1430,7 +1424,8 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
        /// 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.
+       /// 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
@@ -1446,6 +1441,27 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
                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<Transaction, ()> {
+               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()
        }
@@ -1466,21 +1482,20 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
                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<L: Deref>(&self, logger: &L) -> Vec<Transaction>
        where L::Target: Logger {
                self.inner.lock().unwrap().get_latest_holder_commitment_txn(logger)
@@ -2511,7 +2526,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                        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<B: Deref, F: Deref, L: Deref>(&mut self, updates: &ChannelMonitorUpdate, broadcaster: &B, fee_estimator: F, logger: &L) -> Result<(), ()>
@@ -2577,6 +2592,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                                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(());
@@ -2620,10 +2636,10 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                                                }
                                        } 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.");
@@ -2810,6 +2826,31 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                }).collect()
        }
 
+       pub(crate) fn sign_to_local_justice_tx(
+               &self, mut justice_tx: Transaction, input_idx: usize, value: u64, commitment_number: u64
+       ) -> Result<Transaction, ()> {
+               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)
@@ -3342,7 +3383,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                                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 {
@@ -3443,8 +3484,10 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                        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
@@ -3454,7 +3497,8 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
                                // 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));
                                }
@@ -4204,7 +4248,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
                for _ in 0..pending_monitor_events_len {
                        let ev = match <u8 as Readable>::read(reader)? {
                                0 => MonitorEvent::HTLCEvent(Readable::read(reader)?),
-                               1 => MonitorEvent::CommitmentTxConfirmed(funding_info.0),
+                               1 => MonitorEvent::HolderForceClosed(funding_info.0),
                                _ => return Err(DecodeError::InvalidValue)
                        };
                        pending_monitor_events.as_mut().unwrap().push(ev);
@@ -4363,13 +4407,12 @@ mod tests {
        use crate::chain::chaininterface::LowerBoundedFeeEstimator;
 
        use super::ChannelMonitorUpdateStep;
-       use crate::{check_added_monitors, check_closed_broadcast, check_closed_event, check_spends, get_local_commitment_txn, get_monitor, get_route_and_payment_hash, unwrap_send_err};
+       use crate::{check_added_monitors, check_spends, get_local_commitment_txn, get_monitor, get_route_and_payment_hash, unwrap_send_err};
        use crate::chain::{BestBlock, Confirm};
        use crate::chain::channelmonitor::ChannelMonitor;
        use crate::chain::package::{weight_offered_htlc, weight_received_htlc, weight_revoked_offered_htlc, weight_revoked_received_htlc, WEIGHT_REVOKED_OUTPUT};
        use crate::chain::transaction::OutPoint;
        use crate::sign::InMemorySigner;
-       use crate::events::ClosureReason;
        use crate::ln::{PaymentPreimage, PaymentHash};
        use crate::ln::chan_utils;
        use crate::ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, ChannelTransactionParameters, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters};
@@ -4435,18 +4478,14 @@ mod tests {
                let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[1], nodes[0], 100_000);
                unwrap_send_err!(nodes[1].node.send_payment_with_route(&route, payment_hash,
                                RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)
-                       ), true, APIError::ChannelUnavailable { ref err },
-                       assert!(err.contains("ChannelMonitor storage failure")));
-               check_added_monitors!(nodes[1], 2); // After the failure we generate a close-channel monitor update
-               check_closed_broadcast!(nodes[1], true);
-               check_closed_event!(nodes[1], 1, ClosureReason::ProcessingError { err: "ChannelMonitor storage failure".to_string() }, 
-                       [nodes[0].node.get_our_node_id()], 100000);
+                       ), false, APIError::MonitorUpdateInProgress, {});
+               check_added_monitors!(nodes[1], 1);
 
                // Build a new ChannelMonitorUpdate which contains both the failing commitment tx update
                // and provides the claim preimages for the two pending HTLCs. The first update generates
                // an error, but the point of this test is to ensure the later updates are still applied.
                let monitor_updates = nodes[1].chain_monitor.monitor_updates.lock().unwrap();
-               let mut replay_update = monitor_updates.get(&channel.2).unwrap().iter().rev().skip(1).next().unwrap().clone();
+               let mut replay_update = monitor_updates.get(&channel.2).unwrap().iter().rev().next().unwrap().clone();
                assert_eq!(replay_update.updates.len(), 1);
                if let ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. } = replay_update.updates[0] {
                } else { panic!(); }