Handle invalid funding tx in channelmanager
[rust-lightning] / src / ln / channel.rs
index 978be08dc217e4284ef576473a7538fd677ce549..acee06409c3f8479137b1561ac1b2d636cf6c9e2 100644 (file)
@@ -14,7 +14,7 @@ use crypto::digest::Digest;
 use crypto::hkdf::{hkdf_extract,hkdf_expand};
 
 use ln::msgs;
-use ln::msgs::{HandleError, MsgEncodable};
+use ln::msgs::{ErrorAction, HandleError, MsgEncodable};
 use ln::channelmonitor::ChannelMonitor;
 use ln::channelmanager::{PendingForwardHTLCInfo, HTLCFailReason};
 use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGHT,HTLC_TIMEOUT_TX_WEIGHT};
@@ -24,6 +24,7 @@ use chain::transaction::OutPoint;
 use util::{transaction_utils,rng};
 use util::sha2::Sha256;
 
+use std;
 use std::default::Default;
 use std::{cmp,mem};
 use std::time::Instant;
@@ -927,7 +928,7 @@ impl Channel {
                Ok(our_sig)
        }
 
-       pub fn get_update_fulfill_htlc(&mut self, payment_preimage_arg: [u8; 32]) -> Result<Option<(msgs::UpdateFulfillHTLC, ChannelMonitor)>, HandleError> {
+       fn get_update_fulfill_htlc(&mut self, payment_preimage_arg: [u8; 32]) -> Result<(Option<msgs::UpdateFulfillHTLC>, Option<ChannelMonitor>), HandleError> {
                // Either ChannelFunded got set (which means it wont bet unset) or there is no way any
                // caller thought we could have something claimed (cause we wouldn't have accepted in an
                // incoming HTLC anyway). If we got to ShutdownComplete, callers aren't allowed to call us,
@@ -942,13 +943,31 @@ impl Channel {
                let mut payment_hash_calc = [0; 32];
                sha.result(&mut payment_hash_calc);
 
+               let mut pending_idx = std::usize::MAX;
+               for (idx, htlc) in self.pending_htlcs.iter().enumerate() {
+                       if !htlc.outbound && htlc.payment_hash == payment_hash_calc {
+                               if pending_idx != std::usize::MAX {
+                                       panic!("Duplicate HTLC payment_hash, you probably re-used payment preimages, NEVER DO THIS!");
+                               }
+                               pending_idx = idx;
+                       }
+               }
+               if pending_idx == std::usize::MAX {
+                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", action: None});
+               }
+
                // Now update local state:
+               //
+               // We have to put the payment_preimage in the channel_monitor right away here to ensure we
+               // can claim it even if the channel hits the chain before we see their next commitment.
+               self.channel_monitor.provide_payment_preimage(&payment_hash_calc, &payment_preimage_arg);
+
                if (self.channel_state & (ChannelState::AwaitingRemoteRevoke as u32)) == (ChannelState::AwaitingRemoteRevoke as u32) {
                        for pending_update in self.holding_cell_htlc_updates.iter() {
                                match pending_update {
                                        &HTLCUpdateAwaitingACK::ClaimHTLC { ref payment_preimage, .. } => {
                                                if payment_preimage_arg == *payment_preimage {
-                                                       return Ok(None);
+                                                       return Ok((None, None));
                                                }
                                        },
                                        &HTLCUpdateAwaitingACK::FailHTLC { ref payment_hash, .. } => {
@@ -962,49 +981,39 @@ impl Channel {
                        self.holding_cell_htlc_updates.push(HTLCUpdateAwaitingACK::ClaimHTLC {
                                payment_preimage: payment_preimage_arg, payment_hash: payment_hash_calc,
                        });
-                       return Ok(None);
-               }
-
-               let mut htlc_id = 0;
-               let mut htlc_amount_msat = 0;
-               for htlc in self.pending_htlcs.iter_mut() {
-                       if !htlc.outbound && htlc.payment_hash == payment_hash_calc {
-                               if htlc_id != 0 {
-                                       panic!("Duplicate HTLC payment_hash, you probably re-used payment preimages, NEVER DO THIS!");
-                               }
-                               htlc_id = htlc.htlc_id;
-                               htlc_amount_msat += htlc.amount_msat;
-                               if htlc.state == HTLCState::Committed {
-                                       htlc.state = HTLCState::LocalRemoved;
-                                       htlc.local_removed_fulfilled = true;
-                               } else if htlc.state == HTLCState::RemoteAnnounced {
-                                       panic!("Somehow forwarded HTLC prior to remote revocation!");
-                               } else if htlc.state == HTLCState::LocalRemoved || htlc.state == HTLCState::LocalRemovedAwaitingCommitment {
-                                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", action: None});
-                               } else {
-                                       panic!("Have an inbound HTLC when not awaiting remote revoke that had a garbage state");
-                               }
+                       return Ok((None, Some(self.channel_monitor.clone())));
+               }
+
+               let htlc_id = {
+                       let htlc = &mut self.pending_htlcs[pending_idx];
+                       if htlc.state == HTLCState::Committed {
+                               htlc.state = HTLCState::LocalRemoved;
+                               htlc.local_removed_fulfilled = true;
+                       } else if htlc.state == HTLCState::RemoteAnnounced {
+                               panic!("Somehow forwarded HTLC prior to remote revocation!");
+                       } else if htlc.state == HTLCState::LocalRemoved || htlc.state == HTLCState::LocalRemovedAwaitingCommitment {
+                               return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", action: None});
+                       } else {
+                               panic!("Have an inbound HTLC when not awaiting remote revoke that had a garbage state");
                        }
-               }
-               if htlc_amount_msat == 0 {
-                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", action: None});
-               }
-               self.channel_monitor.provide_payment_preimage(&payment_hash_calc, &payment_preimage_arg);
+                       htlc.htlc_id
+               };
 
-               Ok(Some((msgs::UpdateFulfillHTLC {
+               Ok((Some(msgs::UpdateFulfillHTLC {
                        channel_id: self.channel_id(),
                        htlc_id: htlc_id,
                        payment_preimage: payment_preimage_arg,
-               }self.channel_monitor.clone())))
+               }), Some(self.channel_monitor.clone())))
        }
 
-       pub fn get_update_fulfill_htlc_and_commit(&mut self, payment_preimage: [u8; 32]) -> Result<Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned, ChannelMonitor)>, HandleError> {
+       pub fn get_update_fulfill_htlc_and_commit(&mut self, payment_preimage: [u8; 32]) -> Result<(Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)>, Option<ChannelMonitor>), HandleError> {
                match self.get_update_fulfill_htlc(payment_preimage)? {
-                       Some(update_fulfill_htlc) => {
+                       (Some(update_fulfill_htlc), _) => {
                                let (commitment, monitor_update) = self.send_commitment_no_status_check()?;
-                               Ok(Some((update_fulfill_htlc.0, commitment, monitor_update)))
+                               Ok((Some((update_fulfill_htlc, commitment)), Some(monitor_update)))
                        },
-                       None => Ok(None)
+                       (None, Some(channel_monitor)) => Ok((None, Some(channel_monitor))),
+                       (None, None) => Ok((None, None))
                }
        }
 
@@ -1347,7 +1356,7 @@ impl Channel {
                Err(HandleError{err: "Remote tried to fulfill/fail an HTLC we couldn't find", action: None})
        }
 
-       pub fn update_fulfill_htlc(&mut self, msg: &msgs::UpdateFulfillHTLC) -> Result<ChannelMonitor, HandleError> {
+       pub fn update_fulfill_htlc(&mut self, msg: &msgs::UpdateFulfillHTLC) -> Result<(), HandleError> {
                if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
                        return Err(HandleError{err: "Got add HTLC message when channel was not in an operational state", action: None});
                }
@@ -1357,9 +1366,8 @@ impl Channel {
                let mut payment_hash = [0; 32];
                sha.result(&mut payment_hash);
 
-               self.channel_monitor.provide_payment_preimage(&payment_hash, &msg.payment_preimage);
                self.mark_outbound_htlc_removed(msg.htlc_id, Some(payment_hash), None)?;
-               Ok(self.channel_monitor.clone())
+               Ok(())
        }
 
        pub fn update_fail_htlc(&mut self, msg: &msgs::UpdateFailHTLC, fail_reason: HTLCFailReason) -> Result<[u8; 32], HandleError> {
@@ -1491,7 +1499,7 @@ impl Channel {
                                                },
                                                &HTLCUpdateAwaitingACK::ClaimHTLC { payment_preimage, .. } => {
                                                        match self.get_update_fulfill_htlc(payment_preimage) {
-                                                               Ok(update_fulfill_msg_option) => update_fulfill_htlcs.push(update_fulfill_msg_option.unwrap().0),
+                                                               Ok(update_fulfill_msg_option) => update_fulfill_htlcs.push(update_fulfill_msg_option.0.unwrap()),
                                                                Err(e) => {
                                                                        err = Some(e);
                                                                }
@@ -1827,6 +1835,7 @@ impl Channel {
 
        /// Guaranteed to be Some after both FundingLocked messages have been exchanged (and, thus,
        /// is_usable() returns true).
+       /// Allowed in any state (including after shutdown)
        pub fn get_short_channel_id(&self) -> Option<u64> {
                self.short_channel_id
        }
@@ -1837,10 +1846,12 @@ impl Channel {
                self.channel_monitor.get_funding_txo()
        }
 
+       /// Allowed in any state (including after shutdown)
        pub fn get_their_node_id(&self) -> PublicKey {
                self.their_node_id
        }
 
+       /// Allowed in any state (including after shutdown)
        pub fn get_our_htlc_minimum_msat(&self) -> u64 {
                self.our_htlc_minimum_msat
        }
@@ -1849,6 +1860,7 @@ impl Channel {
                self.channel_value_satoshis
        }
 
+       /// Allowed in any state (including after shutdown)
        pub fn get_channel_update_count(&self) -> u32 {
                self.channel_update_count
        }
@@ -1858,6 +1870,7 @@ impl Channel {
        }
 
        /// Gets the fee we'd want to charge for adding an HTLC output to this Channel
+       /// Allowed in any state (including after shutdown)
        pub fn get_our_fee_base_msat(&self, fee_estimator: &FeeEstimator) -> u32 {
                // For lack of a better metric, we calculate what it would cost to consolidate the new HTLC
                // output value back into a transaction with the regular channel output:
@@ -1877,6 +1890,7 @@ impl Channel {
        }
 
        /// Returns true if this channel is fully established and not known to be closing.
+       /// Allowed in any state (including after shutdown)
        pub fn is_usable(&self) -> bool {
                let mask = ChannelState::ChannelFunded as u32 | BOTH_SIDES_SHUTDOWN_MASK;
                (self.channel_state & mask) == (ChannelState::ChannelFunded as u32)
@@ -1884,6 +1898,7 @@ impl Channel {
 
        /// Returns true if this channel is currently available for use. This is a superset of
        /// is_usable() and considers things like the channel being temporarily disabled.
+       /// Allowed in any state (including after shutdown)
        pub fn is_live(&self) -> bool {
                self.is_usable()
        }
@@ -1901,7 +1916,10 @@ impl Channel {
        /// Called by channelmanager based on chain blocks being connected.
        /// Note that we only need to use this to detect funding_signed, anything else is handled by
        /// the channel_monitor.
-       pub fn block_connected(&mut self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]) -> Option<msgs::FundingLocked> {
+       /// In case of Err, the channel may have been closed, at which point the standard requirements
+       /// apply - no calls may be made except those explicitly stated to be allowed post-shutdown.
+       /// Only returns an ErrorAction of DisconnectPeer, if Err.
+       pub fn block_connected(&mut self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]) -> Result<Option<msgs::FundingLocked>, HandleError> {
                let non_shutdown_state = self.channel_state & (!BOTH_SIDES_SHUTDOWN_MASK);
                if self.funding_tx_confirmations > 0 {
                        if header.bitcoin_hash() != self.last_block_connected {
@@ -1925,10 +1943,10 @@ impl Channel {
                                        //a protocol oversight, but I assume I'm just missing something.
                                        let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number);
                                        let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret).unwrap();
-                                       return Some(msgs::FundingLocked {
+                                       return Ok(Some(msgs::FundingLocked {
                                                channel_id: self.channel_id,
                                                next_per_commitment_point: next_per_commitment_point,
-                                       });
+                                       }));
                                }
                        }
                }
@@ -1940,6 +1958,7 @@ impl Channel {
                                                tx.output[txo_idx].value != self.channel_value_satoshis {
                                                self.channel_state = ChannelState::ShutdownComplete as u32;
                                                self.channel_update_count += 1;
+                                               return Err(HandleError{err: "funding tx had wrong script/value", action: Some(ErrorAction::DisconnectPeer{msg: None})});
                                        } else {
                                                self.funding_tx_confirmations = 1;
                                                self.short_channel_id = Some(((height as u64)          << (5*8)) |
@@ -1949,7 +1968,7 @@ impl Channel {
                                }
                        }
                }
-               None
+               Ok(None)
        }
 
        /// Called by channelmanager based on chain blocks being disconnected.
@@ -2323,14 +2342,39 @@ impl Channel {
        }
 
        /// Gets the latest commitment transaction and any dependant transactions for relay (forcing
-       /// shutdown of this channel - no more calls into this Channel may be made afterwards.
-       pub fn force_shutdown(&mut self) -> Vec<Transaction> {
+       /// shutdown of this channel - no more calls into this Channel may be made afterwards except
+       /// those explicitly stated to be allowed after shutdown completes, eg some simple getters).
+       /// Also returns the list of payment_hashes for channels which we can safely fail backwards
+       /// immediately (others we will have to allow to time out).
+       pub fn force_shutdown(&mut self) -> (Vec<Transaction>, Vec<[u8; 32]>) {
                assert!(self.channel_state != ChannelState::ShutdownComplete as u32);
+
+               // We go ahead and "free" any holding cell HTLCs or HTLCs we haven't yet committed to and
+               // return them to fail the payment.
+               let mut dropped_outbound_htlcs = Vec::with_capacity(self.holding_cell_htlc_updates.len());
+               for htlc_update in self.holding_cell_htlc_updates.drain(..) {
+                       match htlc_update {
+                               HTLCUpdateAwaitingACK::AddHTLC { payment_hash, .. } => {
+                                       dropped_outbound_htlcs.push(payment_hash);
+                               },
+                               _ => {}
+                       }
+               }
+
+               for htlc in self.pending_htlcs.drain(..) {
+                       if htlc.state == HTLCState::LocalAnnounced {
+                               dropped_outbound_htlcs.push(htlc.payment_hash);
+                       }
+                       //TODO: Do something with the remaining HTLCs
+                       //(we need to have the ChannelManager monitor them so we can claim the inbound HTLCs
+                       //which correspond)
+               }
+
                self.channel_state = ChannelState::ShutdownComplete as u32;
                self.channel_update_count += 1;
                let mut res = Vec::new();
                mem::swap(&mut res, &mut self.last_local_commitment_txn);
-               res
+               (res, dropped_outbound_htlcs)
        }
 }