Fix update_fee handling, add TODOs
[rust-lightning] / src / ln / channel.rs
index a3b3289eb65505f5194b54bae6d0ae0224a23374..0af02e9c8c33ef456cfa9cd4ba22f54b35649e80 100644 (file)
@@ -13,7 +13,6 @@ use secp256k1;
 
 use crypto::digest::Digest;
 use crypto::hkdf::{hkdf_extract,hkdf_expand};
-use crypto::sha2::Sha256;
 
 use ln::msgs;
 use ln::msgs::{HandleError, MsgEncodable};
@@ -22,9 +21,8 @@ use ln::channelmanager::PendingForwardHTLCInfo;
 use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment};
 use ln::chan_utils;
 use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
-use util::transaction_utils;
-
-use rand::{thread_rng,Rng};
+use util::{transaction_utils,rng};
+use util::sha2::Sha256;
 
 use std::default::Default;
 use std::cmp;
@@ -43,34 +41,33 @@ pub struct ChannelKeys {
 
 impl ChannelKeys {
        pub fn new_from_seed(seed: &[u8; 32]) -> Result<ChannelKeys, secp256k1::Error> {
-               let sha = Sha256::new();
                let mut prk = [0; 32];
-               hkdf_extract(sha, b"rust-lightning key gen salt", seed, &mut prk);
+               hkdf_extract(Sha256::new(), b"rust-lightning key gen salt", seed, &mut prk);
                let secp_ctx = Secp256k1::new();
 
                let mut okm = [0; 32];
-               hkdf_expand(sha, &prk, b"rust-lightning funding key info", &mut okm);
-               let funding_key = try!(SecretKey::from_slice(&secp_ctx, &okm));
+               hkdf_expand(Sha256::new(), &prk, b"rust-lightning funding key info", &mut okm);
+               let funding_key = SecretKey::from_slice(&secp_ctx, &okm)?;
 
-               hkdf_expand(sha, &prk, b"rust-lightning revocation base key info", &mut okm);
-               let revocation_base_key = try!(SecretKey::from_slice(&secp_ctx, &okm));
+               hkdf_expand(Sha256::new(), &prk, b"rust-lightning revocation base key info", &mut okm);
+               let revocation_base_key = SecretKey::from_slice(&secp_ctx, &okm)?;
 
-               hkdf_expand(sha, &prk, b"rust-lightning payment base key info", &mut okm);
-               let payment_base_key = try!(SecretKey::from_slice(&secp_ctx, &okm));
+               hkdf_expand(Sha256::new(), &prk, b"rust-lightning payment base key info", &mut okm);
+               let payment_base_key = SecretKey::from_slice(&secp_ctx, &okm)?;
 
-               hkdf_expand(sha, &prk, b"rust-lightning delayed payment base key info", &mut okm);
-               let delayed_payment_base_key = try!(SecretKey::from_slice(&secp_ctx, &okm));
+               hkdf_expand(Sha256::new(), &prk, b"rust-lightning delayed payment base key info", &mut okm);
+               let delayed_payment_base_key = SecretKey::from_slice(&secp_ctx, &okm)?;
 
-               hkdf_expand(sha, &prk, b"rust-lightning htlc base key info", &mut okm);
-               let htlc_base_key = try!(SecretKey::from_slice(&secp_ctx, &okm));
+               hkdf_expand(Sha256::new(), &prk, b"rust-lightning htlc base key info", &mut okm);
+               let htlc_base_key = SecretKey::from_slice(&secp_ctx, &okm)?;
 
-               hkdf_expand(sha, &prk, b"rust-lightning channel close key info", &mut okm);
-               let channel_close_key = try!(SecretKey::from_slice(&secp_ctx, &okm));
+               hkdf_expand(Sha256::new(), &prk, b"rust-lightning channel close key info", &mut okm);
+               let channel_close_key = SecretKey::from_slice(&secp_ctx, &okm)?;
 
-               hkdf_expand(sha, &prk, b"rust-lightning channel monitor claim key info", &mut okm);
-               let channel_monitor_claim_key = try!(SecretKey::from_slice(&secp_ctx, &okm));
+               hkdf_expand(Sha256::new(), &prk, b"rust-lightning channel monitor claim key info", &mut okm);
+               let channel_monitor_claim_key = SecretKey::from_slice(&secp_ctx, &okm)?;
 
-               hkdf_expand(sha, &prk, b"rust-lightning local commitment seed info", &mut okm);
+               hkdf_expand(Sha256::new(), &prk, b"rust-lightning local commitment seed info", &mut okm);
 
                Ok(ChannelKeys {
                        funding_key: funding_key,
@@ -214,7 +211,7 @@ pub struct Channel {
        channel_monitor: ChannelMonitor,
 }
 
-const OUR_MAX_HTLCS: u16 = 1; //TODO
+const OUR_MAX_HTLCS: u16 = 5; //TODO
 const CONF_TARGET: u32 = 12; //TODO: Should be much higher
 /// Confirmation count threshold at which we close a channel. Ideally we'd keep the channel around
 /// on ice until the funding transaction gets more confirmations, but the LN protocol doesn't
@@ -275,12 +272,11 @@ impl Channel {
                        panic!("funding value > 2^24");
                }
 
-               let mut rng = thread_rng();
                let feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Normal);
                let background_feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Background);
 
                let mut key_seed = [0u8; 32];
-               rng.fill_bytes(&mut key_seed);
+               rng::fill_bytes(&mut key_seed);
                let chan_keys = match ChannelKeys::new_from_seed(&key_seed) {
                        Ok(key) => key,
                        Err(_) => panic!("RNG is busted!")
@@ -297,7 +293,7 @@ impl Channel {
                Channel {
                        user_id: user_id,
 
-                       channel_id: Uint256([rng.gen(), rng.gen(), rng.gen(), rng.gen()]),
+                       channel_id: rng::rand_uint256(),
                        channel_state: ChannelState::OurInitSent as u32,
                        channel_outbound: true,
                        secp_ctx: secp_ctx,
@@ -367,14 +363,16 @@ impl Channel {
                if msg.push_msat > (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000 {
                        return Err(HandleError{err: "push_msat more than highest possible value", msg: None});
                }
-               //TODO Check if dust_limit is sane?
+               if msg.dust_limit_satoshis > 21000000 * 100000000 {
+                       return Err(HandleError{err: "Peer never wants payout outputs?", msg: None});
+               }
                if msg.max_htlc_value_in_flight_msat > msg.funding_satoshis * 1000 {
                        return Err(HandleError{err: "Bogus max_htlc_value_in_flight_satoshis", msg: None});
                }
                if msg.htlc_minimum_msat >= (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000 {
                        return Err(HandleError{err: "Minimum htlc value is full channel value", msg: None});
                }
-               Channel::check_remote_fee(fee_estimator, msg.feerate_per_kw).unwrap();
+               Channel::check_remote_fee(fee_estimator, msg.feerate_per_kw)?;
                if msg.to_self_delay > MAX_LOCAL_BREAKDOWN_TIMEOUT {
                        return Err(HandleError{err: "They wanted our payments to be delayed by a needlessly long period", msg: None});
                }
@@ -391,9 +389,8 @@ impl Channel {
 
                let background_feerate = fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Background);
 
-               let mut rng = thread_rng();
                let mut key_seed = [0u8; 32];
-               rng.fill_bytes(&mut key_seed);
+               rng::fill_bytes(&mut key_seed);
                let chan_keys = match ChannelKeys::new_from_seed(&key_seed) {
                        Ok(key) => key,
                        Err(_) => panic!("RNG is busted!")
@@ -610,7 +607,7 @@ impl Channel {
        /// The result is a transaction which we can revoke ownership of (ie a "local" transaction)
        /// TODO Some magic rust shit to compile-time check this?
        fn build_local_transaction_keys(&self, commitment_number: u64) -> Result<TxCreationKeys, HandleError> {
-               let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &try!(self.build_local_commitment_secret(commitment_number))).unwrap();
+               let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(commitment_number)?).unwrap();
                let delayed_payment_base = PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.delayed_payment_base_key).unwrap();
                let htlc_basepoint = PublicKey::from_secret_key(&self.secp_ctx, &self.local_keys.htlc_base_key).unwrap();
 
@@ -768,6 +765,7 @@ impl Channel {
 
                let mut htlc_id = 0;
                let mut htlc_amount_msat = 0;
+               //TODO: swap_remove since we dont need to maintain ordering here
                self.pending_htlcs.retain(|ref htlc| {
                        if !htlc.outbound && htlc.payment_hash == payment_hash {
                                if htlc_id != 0 {
@@ -782,8 +780,9 @@ impl Channel {
                        return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", msg: None});
                }
 
+               //TODO: This is racy af, they may have pending messages in flight to us that will not have
+               //received this yet!
                self.value_to_self_msat += htlc_amount_msat;
-
                Ok(msgs::UpdateFulfillHTLC {
                        channel_id: self.channel_id(),
                        htlc_id: htlc_id,
@@ -791,17 +790,51 @@ impl Channel {
                })
        }
 
+       pub fn get_update_fail_htlc(&mut self, payment_hash: &[u8; 32], err_packet: msgs::OnionErrorPacket) -> Result<msgs::UpdateFailHTLC, HandleError> {
+               if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
+                       return Err(HandleError{err: "Was asked to fail an HTLC when channel was not in an operational state", msg: None});
+               }
+
+               let mut htlc_id = 0;
+               let mut htlc_amount_msat = 0;
+               //TODO: swap_remove since we dont need to maintain ordering here
+               self.pending_htlcs.retain(|ref htlc| {
+                       if !htlc.outbound && htlc.payment_hash == *payment_hash {
+                               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;
+                               false
+                       } else { true }
+               });
+               if htlc_amount_msat == 0 {
+                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given payment preimage", msg: None});
+               }
+
+               //TODO: This is racy af, they may have pending messages in flight to us that will not have
+               //received this yet!
+
+               Ok(msgs::UpdateFailHTLC {
+                       channel_id: self.channel_id(),
+                       htlc_id,
+                       reason: err_packet
+               })
+       }
+
        // Message handlers:
 
        pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel) -> Result<(), HandleError> {
                // Check sanity of message fields:
-               //TODO Check if dust_limit is sane?
                if !self.channel_outbound {
                        return Err(HandleError{err: "Got an accept_channel message from an inbound peer", msg: None});
                }
                if self.channel_state != ChannelState::OurInitSent as u32 {
                        return Err(HandleError{err: "Got an accept_channel message at a strange time", msg: None});
                }
+               if msg.dust_limit_satoshis > 21000000 * 100000000 {
+                       return Err(HandleError{err: "Peer never wants payout outputs?", msg: None});
+               }
                if msg.max_htlc_value_in_flight_msat > self.channel_value_satoshis * 1000 {
                        return Err(HandleError{err: "Bogus max_htlc_value_in_flight_satoshis", msg: None});
                }
@@ -845,12 +878,12 @@ impl Channel {
        fn funding_created_signature(&mut self, sig: &Signature) -> Result<(Transaction, Signature), HandleError> {
                let funding_script = self.get_funding_redeemscript();
 
-               let remote_keys = try!(self.build_remote_transaction_keys());
-               let remote_initial_commitment_tx = try!(self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false)).0;
+               let remote_keys = self.build_remote_transaction_keys()?;
+               let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false)?.0;
                let remote_sighash = secp_call!(Message::from_slice(&bip143::SighashComponents::new(&remote_initial_commitment_tx).sighash_all(&remote_initial_commitment_tx, 0, &funding_script, self.channel_value_satoshis)[..]));
 
-               let local_keys = try!(self.build_local_transaction_keys(self.cur_local_commitment_transaction_number));
-               let local_initial_commitment_tx = try!(self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false)).0;
+               let local_keys = self.build_local_transaction_keys(self.cur_local_commitment_transaction_number)?;
+               let local_initial_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false)?.0;
                let local_sighash = secp_call!(Message::from_slice(&bip143::SighashComponents::new(&local_initial_commitment_tx).sighash_all(&local_initial_commitment_tx, 0, &funding_script, self.channel_value_satoshis)[..]));
 
                // They sign the "local" commitment transaction, allowing us to broadcast the tx if we wish.
@@ -911,8 +944,8 @@ impl Channel {
 
                let funding_script = self.get_funding_redeemscript();
 
-               let local_keys = try!(self.build_local_transaction_keys(self.cur_local_commitment_transaction_number));
-               let local_initial_commitment_tx = try!(self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false)).0;
+               let local_keys = self.build_local_transaction_keys(self.cur_local_commitment_transaction_number)?;
+               let local_initial_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false)?.0;
                let local_sighash = secp_call!(Message::from_slice(&bip143::SighashComponents::new(&local_initial_commitment_tx).sighash_all(&local_initial_commitment_tx, 0, &funding_script, self.channel_value_satoshis)[..]));
 
                // They sign the "local" commitment transaction, allowing us to broadcast the tx if we wish.
@@ -981,8 +1014,10 @@ impl Channel {
                if htlc_inbound_value_msat + msg.amount_msat > Channel::get_our_max_htlc_value_in_flight_msat(self.channel_value_satoshis) {
                        return Err(HandleError{err: "Remote HTLC add would put them over their max HTLC value in flight", msg: None});
                }
-               // Check our_channel_reserve_satoshis:
-               if htlc_inbound_value_msat + htlc_outbound_value_msat + msg.amount_msat > (self.channel_value_satoshis - Channel::get_our_channel_reserve_satoshis(self.channel_value_satoshis)) * 1000 {
+               // Check our_channel_reserve_satoshis (we're getting paid, so they have to at least meet
+               // the reserve_satoshis we told them to always have as direct payment so that they lose
+               // something if we punish them for broadcasting an old state).
+               if htlc_inbound_value_msat + htlc_outbound_value_msat + msg.amount_msat + self.value_to_self_msat > (self.channel_value_satoshis - Channel::get_our_channel_reserve_satoshis(self.channel_value_satoshis)) * 1000 {
                        return Err(HandleError{err: "Remote HTLC add would put them over their reserve value", msg: None});
                }
                if self.next_remote_htlc_id != msg.htlc_id {
@@ -1010,7 +1045,7 @@ impl Channel {
        }
 
        /// Removes an outbound HTLC which has been commitment_signed by the remote end
-       fn remove_htlc(&mut self, htlc_id: u64, check_preimage: Option<[u8; 32]>) -> Result<HTLCOutput, HandleError> {
+       fn remove_outbound_htlc(&mut self, htlc_id: u64, check_preimage: Option<[u8; 32]>) -> Result<HTLCOutput, HandleError> {
                let mut found_idx = None;
                for (idx, ref htlc) in self.pending_htlcs.iter().enumerate() {
                        if htlc.outbound && htlc.htlc_id == htlc_id {
@@ -1026,7 +1061,7 @@ impl Channel {
                        }
                }
                match found_idx {
-                       None => Err(HandleError{err: "Remote tried to fulfill an HTLC we couldn't find", msg: None}),
+                       None => Err(HandleError{err: "Remote tried to fulfill/fail an HTLC we couldn't find", msg: None}),
                        Some(idx) => {
                                Ok(self.pending_htlcs.swap_remove(idx))
                        }
@@ -1061,7 +1096,7 @@ impl Channel {
                        //TODO: Need to examine the type of err - if its a fee issue or similar we may want to
                        //fail it back the route, if its a temporary issue we can ignore it...
                        if update_add_msgs.len() > 0 {
-                               Ok(Some((update_add_msgs, try!(self.send_commitment()))))
+                               Ok(Some((update_add_msgs, self.send_commitment()?)))
                        } else {
                                Err(err.unwrap())
                        }
@@ -1096,9 +1131,7 @@ impl Channel {
                let mut payment_hash = [0; 32];
                sha.result(&mut payment_hash);
 
-               //TODO: Tell channel_monitor about the payment_preimage
-
-               match self.remove_htlc(msg.htlc_id, Some(payment_hash)) {
+               match self.remove_outbound_htlc(msg.htlc_id, Some(payment_hash)) {
                        Err(e) => return Err(e),
                        Ok(htlc) => {
                                //TODO: Double-check that we didn't exceed some limits (or value_to_self went
@@ -1110,43 +1143,40 @@ impl Channel {
                self.check_and_free_holding_cell_htlcs()
        }
 
-
-       pub fn update_fail_htlc(&mut self, msg: &msgs::UpdateFailHTLC) -> Result<Option<(Vec<msgs::UpdateAddHTLC>, msgs::CommitmentSigned)>, HandleError> {
+       pub fn update_fail_htlc(&mut self, msg: &msgs::UpdateFailHTLC) -> Result<([u8; 32], Option<(Vec<msgs::UpdateAddHTLC>, msgs::CommitmentSigned)>), 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", msg: None});
                }
 
-               //TODO: Lots of checks here (and implementation after the remove?)
-
-               match self.remove_htlc(msg.htlc_id, None) {
+               let payment_hash = match self.remove_outbound_htlc(msg.htlc_id, None) {
                        Err(e) => return Err(e),
-                       Ok(_htlc) => {
+                       Ok(htlc) => {
                                //TODO: Double-check that we didn't exceed some limits (or value_to_self went
                                //negative here?)
-                               ////TODO: Something?
+                               htlc.payment_hash
                        }
-               }
+               };
 
-               self.check_and_free_holding_cell_htlcs()
+               let holding_cell_freedom = self.check_and_free_holding_cell_htlcs()?;
+               Ok((payment_hash, holding_cell_freedom))
        }
 
-       pub fn update_fail_malformed_htlc(&mut self, msg: &msgs::UpdateFailMalformedHTLC) -> Result<Option<(Vec<msgs::UpdateAddHTLC>, msgs::CommitmentSigned)>, HandleError> {
+       pub fn update_fail_malformed_htlc(&mut self, msg: &msgs::UpdateFailMalformedHTLC) -> Result<([u8; 32], Option<(Vec<msgs::UpdateAddHTLC>, msgs::CommitmentSigned)>), 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", msg: None});
                }
 
-               //TODO: Lots of checks here (and implementation after the remove?)
-
-               match self.remove_htlc(msg.htlc_id, None) {
+               let payment_hash = match self.remove_outbound_htlc(msg.htlc_id, None) {
                        Err(e) => return Err(e),
-                       Ok(_htlc) => {
+                       Ok(htlc) => {
                                //TODO: Double-check that we didn't exceed some limits (or value_to_self went
                                //negative here?)
-                               ////TODO: Something?
+                               htlc.payment_hash
                        }
-               }
+               };
 
-               self.check_and_free_holding_cell_htlcs()
+               let holding_cell_freedom = self.check_and_free_holding_cell_htlcs()?;
+               Ok((payment_hash, holding_cell_freedom))
        }
 
        pub fn commitment_signed(&mut self, msg: &msgs::CommitmentSigned) -> Result<(msgs::RevokeAndACK, Vec<PendingForwardHTLCInfo>), HandleError> {
@@ -1156,8 +1186,8 @@ impl Channel {
 
                let funding_script = self.get_funding_redeemscript();
 
-               let local_keys = try!(self.build_local_transaction_keys(self.cur_local_commitment_transaction_number));
-               let local_commitment_tx = try!(self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false));
+               let local_keys = self.build_local_transaction_keys(self.cur_local_commitment_transaction_number)?;
+               let local_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false)?;
                let local_sighash = secp_call!(Message::from_slice(&bip143::SighashComponents::new(&local_commitment_tx.0).sighash_all(&local_commitment_tx.0, 0, &funding_script, self.channel_value_satoshis)[..]));
                secp_call!(self.secp_ctx.verify(&local_sighash, &msg.signature, &self.their_funding_pubkey));
 
@@ -1166,13 +1196,13 @@ impl Channel {
                }
 
                for (idx, ref htlc) in local_commitment_tx.1.iter().enumerate() {
-                       let htlc_tx = try!(self.build_htlc_transaction(&local_commitment_tx.0.txid(), htlc, true, &local_keys));
+                       let htlc_tx = self.build_htlc_transaction(&local_commitment_tx.0.txid(), htlc, true, &local_keys)?;
                        let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &local_keys, htlc.offered);
                        let htlc_sighash = secp_call!(Message::from_slice(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx, 0, &htlc_redeemscript, htlc.amount_msat / 1000)[..]));
                        secp_call!(self.secp_ctx.verify(&htlc_sighash, &msg.htlc_signatures[idx], &local_keys.b_htlc_key));
                }
 
-               let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &try!(self.build_local_commitment_secret(self.cur_local_commitment_transaction_number - 1))).unwrap();
+               let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &self.build_local_commitment_secret(self.cur_local_commitment_transaction_number - 1)?).unwrap();
                let per_commitment_secret = chan_utils::build_commitment_secret(self.local_keys.commitment_seed, self.cur_local_commitment_transaction_number);
 
                //TODO: Store htlc keys in our channel_watcher
@@ -1208,7 +1238,7 @@ impl Channel {
                if PublicKey::from_secret_key(&self.secp_ctx, &get_key!(&self.secp_ctx, &msg.per_commitment_secret)).unwrap() != self.their_cur_commitment_point {
                        return Err(HandleError{err: "Got a revoke commitment secret which didn't correspond to their current pubkey", msg: None});
                }
-               try!(self.channel_monitor.provide_secret(self.cur_remote_commitment_transaction_number, msg.per_commitment_secret));
+               self.channel_monitor.provide_secret(self.cur_remote_commitment_transaction_number, msg.per_commitment_secret)?;
 
                // Update state now that we've passed all the can-fail calls...
                // (note that we may still fail to generate the new commitment_signed message, but that's
@@ -1230,7 +1260,7 @@ impl Channel {
         if self.channel_outbound {
                        return Err(HandleError{err: "Non-funding remote tried to update channel fee", msg: None});
         }
-               Channel::check_remote_fee(fee_estimator, msg.feerate_per_kw).unwrap();
+               Channel::check_remote_fee(fee_estimator, msg.feerate_per_kw)?;
                self.feerate_per_kw = msg.feerate_per_kw as u64;
                Ok(())
        }
@@ -1393,7 +1423,7 @@ impl Channel {
                        panic!("Tried to send an open_channel for a channel that has already advanced");
                }
 
-               let local_commitment_secret = try!(self.build_local_commitment_secret(self.cur_local_commitment_transaction_number));
+               let local_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number)?;
 
                Ok(msgs::OpenChannel {
                        chain_hash: chain_hash,
@@ -1429,7 +1459,7 @@ impl Channel {
                        panic!("Tried to send an accept_channel for a channel that has already advanced");
                }
 
-               let local_commitment_secret = try!(self.build_local_commitment_secret(self.cur_local_commitment_transaction_number));
+               let local_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number)?;
 
                Ok(msgs::AcceptChannel {
                        temporary_channel_id: self.channel_id,
@@ -1453,8 +1483,8 @@ impl Channel {
        fn get_outbound_funding_created_signature(&mut self) -> Result<Signature, HandleError> {
                let funding_script = self.get_funding_redeemscript();
 
-               let remote_keys = try!(self.build_remote_transaction_keys());
-               let remote_initial_commitment_tx = try!(self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false)).0;
+               let remote_keys = self.build_remote_transaction_keys()?;
+               let remote_initial_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, false)?.0;
                let remote_sighash = secp_call!(Message::from_slice(&bip143::SighashComponents::new(&remote_initial_commitment_tx).sighash_all(&remote_initial_commitment_tx, 0, &funding_script, self.channel_value_satoshis)[..]));
 
                // We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish.
@@ -1565,7 +1595,7 @@ impl Channel {
                        return Err(HandleError{err: "Cannot send value that would put us over our max HTLC value in flight", msg: None});
                }
                // Check their_channel_reserve_satoshis:
-               if htlc_outbound_value_msat + amount_msat > (self.channel_value_satoshis - self.their_channel_reserve_satoshis) * 1000 - htlc_inbound_value_msat {
+               if htlc_inbound_value_msat + htlc_outbound_value_msat + amount_msat + (self.channel_value_satoshis * 1000 - self.value_to_self_msat) > (self.channel_value_satoshis - self.their_channel_reserve_satoshis) * 1000 {
                        return Err(HandleError{err: "Cannot send value that would put us over our reserve value", msg: None});
                }
 
@@ -1615,15 +1645,15 @@ impl Channel {
 
                let funding_script = self.get_funding_redeemscript();
 
-               let remote_keys = try!(self.build_remote_transaction_keys());
-               let remote_commitment_tx = try!(self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, true));
+               let remote_keys = self.build_remote_transaction_keys()?;
+               let remote_commitment_tx = self.build_commitment_transaction(self.cur_remote_commitment_transaction_number, &remote_keys, false, true)?;
                let remote_sighash = secp_call!(Message::from_slice(&bip143::SighashComponents::new(&remote_commitment_tx.0).sighash_all(&remote_commitment_tx.0, 0, &funding_script, self.channel_value_satoshis)[..]));
                let our_sig = secp_call!(self.secp_ctx.sign(&remote_sighash, &self.local_keys.funding_key));
 
                let mut htlc_sigs = Vec::new();
 
                for ref htlc in remote_commitment_tx.1.iter() {
-                       let htlc_tx = try!(self.build_htlc_transaction(&remote_commitment_tx.0.txid(), htlc, false, &remote_keys));
+                       let htlc_tx = self.build_htlc_transaction(&remote_commitment_tx.0.txid(), htlc, false, &remote_keys)?;
                        let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &remote_keys, htlc.offered);
                        let htlc_sighash = secp_call!(Message::from_slice(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx, 0, &htlc_redeemscript, htlc.amount_msat / 1000)[..]));
                        let our_htlc_key = secp_call!(chan_utils::derive_private_key(&self.secp_ctx, &remote_keys.per_commitment_point, &self.local_keys.htlc_base_key));
@@ -1645,9 +1675,9 @@ impl Channel {
        /// Shorthand for calling send_htlc() followed by send_commitment(), see docs on those for
        /// more info.
        pub fn send_htlc_and_commit(&mut self, amount_msat: u64, payment_hash: [u8; 32], cltv_expiry: u32, onion_routing_packet: msgs::OnionPacket) -> Result<Option<(msgs::UpdateAddHTLC, msgs::CommitmentSigned)>, HandleError> {
-               match try!(self.send_htlc(amount_msat, payment_hash, cltv_expiry, onion_routing_packet)) {
+               match self.send_htlc(amount_msat, payment_hash, cltv_expiry, onion_routing_packet)? {
                        Some(update_add_htlc) =>
-                               Ok(Some((update_add_htlc, try!(self.send_commitment())))),
+                               Ok(Some((update_add_htlc, self.send_commitment()?))),
                        None => Ok(None)
                }
        }