Merge pull request #231 from philipr-za/philip-204-check-commitment-transaction-fee
[rust-lightning] / src / ln / channel.rs
index 57070e41d5fe27aa2085a4155952a9618a218a34..d0a4644abdfa7164a25275ca2738f4a3e535b093 100644 (file)
@@ -2,11 +2,9 @@ use bitcoin::blockdata::block::BlockHeader;
 use bitcoin::blockdata::script::{Script,Builder};
 use bitcoin::blockdata::transaction::{TxIn, TxOut, Transaction, SigHashType};
 use bitcoin::blockdata::opcodes;
-use bitcoin::util::hash::{Sha256dHash, Hash160};
+use bitcoin::util::hash::{BitcoinHash, Sha256dHash, Hash160};
 use bitcoin::util::bip143;
-use bitcoin::network;
-use bitcoin::network::serialize::{BitcoinHash, RawDecoder, RawEncoder};
-use bitcoin::network::encodable::{ConsensusEncodable, ConsensusDecodable};
+use bitcoin::consensus::encode::{self, Encodable, Decodable};
 
 use secp256k1::key::{PublicKey,SecretKey};
 use secp256k1::{Secp256k1,Message,Signature};
@@ -439,7 +437,7 @@ impl Channel {
 
                let secp_ctx = Secp256k1::new();
                let channel_monitor = ChannelMonitor::new(&chan_keys.revocation_base_key, &chan_keys.delayed_payment_base_key,
-                                                         &chan_keys.htlc_base_key, BREAKDOWN_TIMEOUT,
+                                                         &chan_keys.htlc_base_key, &chan_keys.payment_base_key, &keys_provider.get_shutdown_pubkey(), BREAKDOWN_TIMEOUT,
                                                          keys_provider.get_destination_script(), logger.clone());
 
                Ok(Channel {
@@ -627,9 +625,10 @@ impl Channel {
 
                let secp_ctx = Secp256k1::new();
                let mut channel_monitor = ChannelMonitor::new(&chan_keys.revocation_base_key, &chan_keys.delayed_payment_base_key,
-                                                             &chan_keys.htlc_base_key, BREAKDOWN_TIMEOUT,
+                                                             &chan_keys.htlc_base_key, &chan_keys.payment_base_key, &keys_provider.get_shutdown_pubkey(), BREAKDOWN_TIMEOUT,
                                                              keys_provider.get_destination_script(), logger.clone());
                channel_monitor.set_their_base_keys(&msg.htlc_basepoint, &msg.delayed_payment_basepoint);
+               channel_monitor.provide_their_next_revocation_point(Some((INITIAL_COMMITMENT_NUMBER, msg.first_per_commitment_point)));
                channel_monitor.set_their_to_self_delay(msg.to_self_delay);
 
                let mut chan = Channel {
@@ -1123,8 +1122,9 @@ impl Channel {
                Ok(our_sig)
        }
 
-       /// May return an IgnoreError, but should not, and will always return Ok(_) when
-       /// debug_assertions are turned on
+       /// Per HTLC, only one get_update_fail_htlc or get_update_fulfill_htlc call may be made.
+       /// In such cases we debug_assert!(false) and return an IgnoreError. Thus, will always return
+       /// Ok(_) if debug assertions are turned on and preconditions are met.
        fn get_update_fulfill_htlc(&mut self, htlc_id_arg: u64, 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
@@ -1176,7 +1176,9 @@ impl Channel {
                                        &HTLCUpdateAwaitingACK::FailHTLC { htlc_id, .. } => {
                                                if htlc_id_arg == htlc_id {
                                                        debug_assert!(false, "Tried to fulfill an HTLC we already had a holding-cell failure on");
-                                                       return Err(HandleError{err: "Unable to find a pending HTLC which matched the given HTLC ID", action: Some(msgs::ErrorAction::IgnoreError)});
+                                                       // Return the new channel monitor in a last-ditch effort to hit the
+                                                       // chain and claim the funds
+                                                       return Ok((None, Some(self.channel_monitor.clone())));
                                                }
                                        },
                                        _ => {}
@@ -1216,8 +1218,9 @@ impl Channel {
                }
        }
 
-       /// May return an IgnoreError, but should not, and will always return Ok(_) when
-       /// debug_assertions are turned on
+       /// Per HTLC, only one get_update_fail_htlc or get_update_fulfill_htlc call may be made.
+       /// In such cases we debug_assert!(false) and return an IgnoreError. Thus, will always return
+       /// Ok(_) if debug assertions are turned on and preconditions are met.
        pub fn get_update_fail_htlc(&mut self, htlc_id_arg: u64, err_packet: msgs::OnionErrorPacket) -> Result<Option<msgs::UpdateFailHTLC>, HandleError> {
                if (self.channel_state & (ChannelState::ChannelFunded as u32)) != (ChannelState::ChannelFunded as u32) {
                        panic!("Was asked to fail an HTLC when channel was not in an operational state");
@@ -1350,6 +1353,7 @@ impl Channel {
                }
 
                self.channel_monitor.set_their_base_keys(&msg.htlc_basepoint, &msg.delayed_payment_basepoint);
+               self.channel_monitor.provide_their_next_revocation_point(Some((INITIAL_COMMITMENT_NUMBER, msg.first_per_commitment_point)));
 
                self.their_dust_limit_satoshis = msg.dust_limit_satoshis;
                self.their_max_htlc_value_in_flight_msat = cmp::min(msg.max_htlc_value_in_flight_msat, self.channel_value_satoshis * 1000);
@@ -1374,22 +1378,25 @@ impl Channel {
                Ok(())
        }
 
-       fn funding_created_signature(&mut self, sig: &Signature) -> Result<(Transaction, Signature), HandleError> {
+       fn funding_created_signature(&mut self, sig: &Signature) -> Result<(Transaction, Transaction, Signature, TxCreationKeys), HandleError> {
                let funding_script = self.get_funding_redeemscript();
 
                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, self.feerate_per_kw).0;
+               let mut local_initial_commitment_tx = self.build_commitment_transaction(self.cur_local_commitment_transaction_number, &local_keys, true, false, self.feerate_per_kw).0;
                let local_sighash = Message::from_slice(&bip143::SighashComponents::new(&local_initial_commitment_tx).sighash_all(&local_initial_commitment_tx.input[0], &funding_script, self.channel_value_satoshis)[..]).unwrap();
 
-               // They sign the "local" commitment transaction, allowing us to broadcast the tx if we wish.
+               // They sign the "local" commitment transaction...
                secp_call!(self.secp_ctx.verify(&local_sighash, &sig, &self.their_funding_pubkey.unwrap()), "Invalid funding_created signature from peer", self.channel_id());
 
+               // ...and we sign it, allowing us to broadcast the tx if we wish
+               self.sign_commitment_transaction(&mut local_initial_commitment_tx, sig);
+
                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, self.feerate_per_kw).0;
                let remote_sighash = Message::from_slice(&bip143::SighashComponents::new(&remote_initial_commitment_tx).sighash_all(&remote_initial_commitment_tx.input[0], &funding_script, self.channel_value_satoshis)[..]).unwrap();
 
                // We sign the "remote" commitment transaction, allowing them to broadcast the tx if they wish.
-               Ok((remote_initial_commitment_tx, self.secp_ctx.sign(&remote_sighash, &self.local_keys.funding_key)))
+               Ok((remote_initial_commitment_tx, local_initial_commitment_tx, self.secp_ctx.sign(&remote_sighash, &self.local_keys.funding_key), local_keys))
        }
 
        pub fn funding_created(&mut self, msg: &msgs::FundingCreated) -> Result<(msgs::FundingSigned, ChannelMonitor), HandleError> {
@@ -1412,7 +1419,7 @@ impl Channel {
                let funding_txo_script = self.get_funding_redeemscript().to_v0_p2wsh();
                self.channel_monitor.set_funding_info((funding_txo, funding_txo_script));
 
-               let (remote_initial_commitment_tx, our_signature) = match self.funding_created_signature(&msg.signature) {
+               let (remote_initial_commitment_tx, local_initial_commitment_tx, our_signature, local_keys) = match self.funding_created_signature(&msg.signature) {
                        Ok(res) => res,
                        Err(e) => {
                                self.channel_monitor.unset_funding_info();
@@ -1423,6 +1430,8 @@ impl Channel {
                // Now that we're past error-generating stuff, update our local state:
 
                self.channel_monitor.provide_latest_remote_commitment_tx_info(&remote_initial_commitment_tx, Vec::new(), self.cur_remote_commitment_transaction_number);
+               self.last_local_commitment_txn = vec![local_initial_commitment_tx.clone()];
+               self.channel_monitor.provide_latest_local_commitment_tx_info(local_initial_commitment_tx, local_keys, self.feerate_per_kw, Vec::new());
                self.channel_state = ChannelState::FundingSent as u32;
                self.channel_id = funding_txo.to_channel_id();
                self.cur_remote_commitment_transaction_number -= 1;
@@ -1492,6 +1501,7 @@ impl Channel {
                        return Err(ChannelError::Close("Peer sent a funding_locked at a strange time"));
                }
 
+               self.channel_monitor.provide_their_next_revocation_point(Some((INITIAL_COMMITMENT_NUMBER - 1 , msg.next_per_commitment_point)));
                self.their_prev_commitment_point = self.their_cur_commitment_point;
                self.their_cur_commitment_point = Some(msg.next_per_commitment_point);
                Ok(())
@@ -1884,7 +1894,8 @@ impl Channel {
                                return Err(HandleError{err: "Got a revoke commitment secret which didn't correspond to their current pubkey", action: None});
                        }
                }
-               self.channel_monitor.provide_secret(self.cur_remote_commitment_transaction_number + 1, msg.per_commitment_secret, Some((self.cur_remote_commitment_transaction_number - 1, msg.next_per_commitment_point)))?;
+               self.channel_monitor.provide_secret(self.cur_remote_commitment_transaction_number + 1, msg.per_commitment_secret)?;
+               self.channel_monitor.provide_their_next_revocation_point(Some((self.cur_remote_commitment_transaction_number - 1, msg.next_per_commitment_point)));
 
                // 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
@@ -2836,6 +2847,16 @@ impl Channel {
                                                self.channel_update_count += 1;
                                                return Err(HandleError{err: "funding tx had wrong script/value", action: Some(ErrorAction::DisconnectPeer{msg: None})});
                                        } else {
+                                               if self.channel_outbound {
+                                                       for input in tx.input.iter() {
+                                                               if input.witness.is_empty() {
+                                                                       // We generated a malleable funding transaction, implying we've
+                                                                       // just exposed ourselves to funds loss to our counterparty.
+                                                                       #[cfg(not(feature = "fuzztarget"))]
+                                                                       panic!("Client called ChannelManager::funding_transaction_generated with bogus transaction!");
+                                                               }
+                                                       }
+                                               }
                                                self.funding_tx_confirmations = 1;
                                                self.short_channel_id = Some(((height as u64)          << (5*8)) |
                                                                             ((*index_in_block as u64) << (2*8)) |
@@ -3524,9 +3545,9 @@ impl Writeable for Channel {
 
                (self.last_local_commitment_txn.len() as u64).write(writer)?;
                for tx in self.last_local_commitment_txn.iter() {
-                       if let Err(e) = tx.consensus_encode(&mut RawEncoder::new(WriterWriteAdaptor(writer))) {
+                       if let Err(e) = tx.consensus_encode(&mut WriterWriteAdaptor(writer)) {
                                match e {
-                                       network::serialize::Error::Io(e) => return Err(e),
+                                       encode::Error::Io(e) => return Err(e),
                                        _ => panic!("last_local_commitment_txn must have been well-formed!"),
                                }
                        }
@@ -3703,7 +3724,7 @@ impl<R : ::std::io::Read> ReadableArgs<R, Arc<Logger>> for Channel {
                let last_local_commitment_txn_count: u64 = Readable::read(reader)?;
                let mut last_local_commitment_txn = Vec::with_capacity(cmp::min(last_local_commitment_txn_count as usize, OUR_MAX_HTLCS as usize*2 + 1));
                for _ in 0..last_local_commitment_txn_count {
-                       last_local_commitment_txn.push(match Transaction::consensus_decode(&mut RawDecoder::new(reader.by_ref())) {
+                       last_local_commitment_txn.push(match Transaction::consensus_decode(reader.by_ref()) {
                                Ok(tx) => tx,
                                Err(_) => return Err(DecodeError::InvalidValue),
                        });
@@ -3831,7 +3852,7 @@ impl<R : ::std::io::Read> ReadableArgs<R, Arc<Logger>> for Channel {
 mod tests {
        use bitcoin::util::hash::{Sha256dHash, Hash160};
        use bitcoin::util::bip143;
-       use bitcoin::network::serialize::serialize;
+       use bitcoin::consensus::encode::serialize;
        use bitcoin::blockdata::script::{Script, Builder};
        use bitcoin::blockdata::transaction::Transaction;
        use bitcoin::blockdata::opcodes;
@@ -3953,7 +3974,7 @@ mod tests {
 
                                chan.sign_commitment_transaction(&mut unsigned_tx.0, &their_signature);
 
-                               assert_eq!(serialize(&unsigned_tx.0).unwrap()[..],
+                               assert_eq!(serialize(&unsigned_tx.0)[..],
                                                hex::decode($tx_hex).unwrap()[..]);
                        };
                }
@@ -3986,7 +4007,7 @@ mod tests {
                                }
 
                                chan.sign_htlc_transaction(&mut htlc_tx, &remote_signature, &preimage, &htlc, &keys).unwrap();
-                               assert_eq!(serialize(&htlc_tx).unwrap()[..],
+                               assert_eq!(serialize(&htlc_tx)[..],
                                                hex::decode($tx_hex).unwrap()[..]);
                        };
                }