Fold sign_holder_commitment_htlc_transactions into sign_holder_commitment
[rust-lightning] / lightning / src / ln / channel.rs
index 32ca3d30b91fd1cd076a7169bab9b0062e9fc3c3..08faea160bb193a0d652a03211d4d2039942f500 100644 (file)
@@ -14,7 +14,7 @@ use bitcoin::blockdata::opcodes;
 use bitcoin::util::bip143;
 use bitcoin::consensus::encode;
 
-use bitcoin::hashes::{Hash, HashEngine};
+use bitcoin::hashes::Hash;
 use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::hash_types::{Txid, BlockHash, WPubkeyHash};
 
@@ -26,14 +26,14 @@ use ln::features::{ChannelFeatures, InitFeatures};
 use ln::msgs;
 use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
 use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT};
-use ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, CommitmentTransaction, HolderCommitmentTransaction, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, MAX_HTLCS};
+use ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputInCommitment, HTLC_SUCCESS_TX_WEIGHT, HTLC_TIMEOUT_TX_WEIGHT, make_funding_redeemscript, ChannelPublicKeys, CommitmentTransaction, HolderCommitmentTransaction, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, MAX_HTLCS, get_commitment_transaction_number_obscure_factor};
 use ln::chan_utils;
 use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
 use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER};
 use chain::transaction::{OutPoint, TransactionData};
 use chain::keysinterface::{ChannelKeys, KeysInterface};
 use util::transaction_utils;
-use util::ser::{Readable, Writeable, Writer};
+use util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter};
 use util::logger::Logger;
 use util::errors::APIError;
 use util::config::{UserConfig,ChannelConfig};
@@ -795,29 +795,6 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
                Ok(chan)
        }
 
-       // Utilities to build transactions:
-
-       fn get_commitment_transaction_number_obscure_factor(&self) -> u64 {
-               let mut sha = Sha256::engine();
-
-               let counterparty_payment_point = &self.get_counterparty_pubkeys().payment_point.serialize();
-               if self.is_outbound() {
-                       sha.input(&self.get_holder_pubkeys().payment_point.serialize());
-                       sha.input(counterparty_payment_point);
-               } else {
-                       sha.input(counterparty_payment_point);
-                       sha.input(&self.get_holder_pubkeys().payment_point.serialize());
-               }
-               let res = Sha256::from_engine(sha).into_inner();
-
-               ((res[26] as u64) << 5*8) |
-               ((res[27] as u64) << 4*8) |
-               ((res[28] as u64) << 3*8) |
-               ((res[29] as u64) << 2*8) |
-               ((res[30] as u64) << 1*8) |
-               ((res[31] as u64) << 0*8)
-       }
-
        /// Transaction nomenclature is somewhat confusing here as there are many different cases - a
        /// transaction is referred to as "a's transaction" implying that a will be able to broadcast
        /// the transaction. Thus, b will generally be sending a signature over such a transaction to
@@ -846,7 +823,7 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
                let mut local_htlc_total_msat = 0;
                let mut value_to_self_msat_offset = 0;
 
-               log_trace!(logger, "Building commitment transaction number {} (really {} xor {}) for {}, generated by {} with fee {}...", commitment_number, (INITIAL_COMMITMENT_NUMBER - commitment_number), self.get_commitment_transaction_number_obscure_factor(), if local { "us" } else { "remote" }, if generated_by_local { "us" } else { "remote" }, feerate_per_kw);
+               log_trace!(logger, "Building commitment transaction number {} (really {} xor {}) for {}, generated by {} with fee {}...", commitment_number, (INITIAL_COMMITMENT_NUMBER - commitment_number), get_commitment_transaction_number_obscure_factor(&self.get_holder_pubkeys().payment_point, &self.get_counterparty_pubkeys().payment_point, self.is_outbound()), if local { "us" } else { "remote" }, if generated_by_local { "us" } else { "remote" }, feerate_per_kw);
 
                macro_rules! get_htlc_in_commitment {
                        ($htlc: expr, $offered: expr) => {
@@ -1539,12 +1516,13 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
 
                let funding_redeemscript = self.get_funding_redeemscript();
                let funding_txo_script = funding_redeemscript.to_v0_p2wsh();
+               let obscure_factor = get_commitment_transaction_number_obscure_factor(&self.get_holder_pubkeys().payment_point, &self.get_counterparty_pubkeys().payment_point, self.is_outbound());
                let mut channel_monitor = ChannelMonitor::new(self.holder_keys.clone(),
                                                              &self.shutdown_pubkey, self.get_holder_selected_contest_delay(),
                                                              &self.destination_script, (funding_txo, funding_txo_script.clone()),
                                                              &self.channel_transaction_parameters,
                                                              funding_redeemscript.clone(), self.channel_value_satoshis,
-                                                             self.get_commitment_transaction_number_obscure_factor(),
+                                                             obscure_factor,
                                                              holder_commitment_tx);
 
                channel_monitor.provide_latest_counterparty_commitment_tx(counterparty_initial_commitment_txid, Vec::new(), self.cur_counterparty_commitment_transaction_number, self.counterparty_cur_commitment_point.unwrap(), logger);
@@ -1608,12 +1586,13 @@ impl<ChanSigner: ChannelKeys> Channel<ChanSigner> {
                let funding_redeemscript = self.get_funding_redeemscript();
                let funding_txo = self.get_funding_txo().unwrap();
                let funding_txo_script = funding_redeemscript.to_v0_p2wsh();
+               let obscure_factor = get_commitment_transaction_number_obscure_factor(&self.get_holder_pubkeys().payment_point, &self.get_counterparty_pubkeys().payment_point, self.is_outbound());
                let mut channel_monitor = ChannelMonitor::new(self.holder_keys.clone(),
                                                              &self.shutdown_pubkey, self.get_holder_selected_contest_delay(),
                                                              &self.destination_script, (funding_txo, funding_txo_script),
                                                              &self.channel_transaction_parameters,
                                                              funding_redeemscript.clone(), self.channel_value_satoshis,
-                                                             self.get_commitment_transaction_number_obscure_factor(),
+                                                             obscure_factor,
                                                              holder_commitment_tx);
 
                channel_monitor.provide_latest_counterparty_commitment_tx(counterparty_initial_bitcoin_tx.txid, Vec::new(), self.cur_counterparty_commitment_transaction_number, self.counterparty_cur_commitment_point.unwrap(), logger);
@@ -4076,7 +4055,7 @@ impl Readable for InboundHTLCRemovalReason {
        }
 }
 
-impl<ChanSigner: ChannelKeys + Writeable> Writeable for Channel<ChanSigner> {
+impl<ChanSigner: ChannelKeys> Writeable for Channel<ChanSigner> {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
                // Note that we write out as if remove_uncommitted_htlcs_and_mark_paused had just been
                // called but include holding cell updates (and obviously we don't modify self).
@@ -4093,7 +4072,13 @@ impl<ChanSigner: ChannelKeys + Writeable> Writeable for Channel<ChanSigner> {
 
                self.latest_monitor_update_id.write(writer)?;
 
-               self.holder_keys.write(writer)?;
+               let mut key_data = VecWriter(Vec::new());
+               self.holder_keys.write(&mut key_data)?;
+               assert!(key_data.0.len() < std::usize::MAX);
+               assert!(key_data.0.len() < std::u32::MAX as usize);
+               (key_data.0.len() as u32).write(writer)?;
+               writer.write_all(&key_data.0[..])?;
+
                self.shutdown_pubkey.write(writer)?;
                self.destination_script.write(writer)?;
 
@@ -4258,8 +4243,10 @@ impl<ChanSigner: ChannelKeys + Writeable> Writeable for Channel<ChanSigner> {
        }
 }
 
-impl<ChanSigner: ChannelKeys + Readable> Readable for Channel<ChanSigner> {
-       fn read<R : ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
+const MAX_ALLOC_SIZE: usize = 64*1024;
+impl<'a, ChanSigner: ChannelKeys, K: Deref> ReadableArgs<&'a K> for Channel<ChanSigner>
+               where K::Target: KeysInterface<ChanKeySigner = ChanSigner> {
+       fn read<R : ::std::io::Read>(reader: &mut R, keys_source: &'a K) -> Result<Self, DecodeError> {
                let _ver: u8 = Readable::read(reader)?;
                let min_ver: u8 = Readable::read(reader)?;
                if min_ver > SERIALIZATION_VERSION {
@@ -4275,7 +4262,17 @@ impl<ChanSigner: ChannelKeys + Readable> Readable for Channel<ChanSigner> {
 
                let latest_monitor_update_id = Readable::read(reader)?;
 
-               let holder_keys = Readable::read(reader)?;
+               let keys_len: u32 = Readable::read(reader)?;
+               let mut keys_data = Vec::with_capacity(cmp::min(keys_len as usize, MAX_ALLOC_SIZE));
+               while keys_data.len() != keys_len as usize {
+                       // Read 1KB at a time to avoid accidentally allocating 4GB on corrupted channel keys
+                       let mut data = [0; 1024];
+                       let read_slice = &mut data[0..cmp::min(1024, keys_len as usize - keys_data.len())];
+                       reader.read_exact(read_slice)?;
+                       keys_data.extend_from_slice(read_slice);
+               }
+               let holder_keys = keys_source.read_chan_signer(&keys_data)?;
+
                let shutdown_pubkey = Readable::read(reader)?;
                let destination_script = Readable::read(reader)?;
 
@@ -4493,7 +4490,7 @@ mod tests {
        use ln::channel::{Channel,ChannelKeys,InboundHTLCOutput,OutboundHTLCOutput,InboundHTLCState,OutboundHTLCState,HTLCOutputInCommitment,TxCreationKeys};
        use ln::channel::MAX_FUNDING_SATOSHIS;
        use ln::features::InitFeatures;
-       use ln::msgs::{OptionalField, DataLossProtect};
+       use ln::msgs::{OptionalField, DataLossProtect, DecodeError};
        use ln::chan_utils;
        use ln::chan_utils::{ChannelPublicKeys, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters};
        use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
@@ -4549,6 +4546,7 @@ mod tests {
                        self.chan_keys.clone()
                }
                fn get_secure_random_bytes(&self) -> [u8; 32] { [0; 32] }
+               fn read_chan_signer(&self, _data: &[u8]) -> Result<Self::ChanKeySigner, DecodeError> { panic!(); }
        }
 
        fn public_from_secret_hex(secp_ctx: &Secp256k1<All>, hex: &str) -> PublicKey {
@@ -4744,15 +4742,13 @@ mod tests {
                                        &chan.holder_keys.pubkeys().funding_pubkey,
                                        chan.counterparty_funding_pubkey()
                                );
-                               let holder_sig = chan_keys.sign_holder_commitment(&holder_commitment_tx, &secp_ctx).unwrap();
+                               let (holder_sig, htlc_sigs) = chan_keys.sign_holder_commitment_and_htlcs(&holder_commitment_tx, &secp_ctx).unwrap();
                                assert_eq!(Signature::from_der(&hex::decode($sig_hex).unwrap()[..]).unwrap(), holder_sig, "holder_sig");
 
                                let funding_redeemscript = chan.get_funding_redeemscript();
                                let tx = holder_commitment_tx.add_holder_sig(&funding_redeemscript, holder_sig);
                                assert_eq!(serialize(&tx)[..], hex::decode($tx_hex).unwrap()[..], "tx");
 
-                               let htlc_sigs = chan_keys.sign_holder_commitment_htlc_transactions(&holder_commitment_tx, &secp_ctx).unwrap();
-
                                // ((htlc, counterparty_sig), (index, holder_sig))
                                let mut htlc_sig_iter = holder_commitment_tx.htlcs().iter().zip(&holder_commitment_tx.counterparty_htlc_sigs).zip(htlc_sigs.iter().enumerate());
 
@@ -5128,6 +5124,65 @@ mod tests {
                test_commitment!("304402202ade0142008309eb376736575ad58d03e5b115499709c6db0b46e36ff394b492022037b63d78d66404d6504d4c4ac13be346f3d1802928a6d3ad95a6a944227161a2",
                                 "304402207e8d51e0c570a5868a78414f4e0cbfaed1106b171b9581542c30718ee4eb95ba02203af84194c97adf98898c9afe2f2ed4a7f8dba05a2dfab28ac9d9c604aa49a379",
                                 "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8001c0c62d0000000000160014cc1b07838e387deacd0e5232e1e8b49f4c29e484040047304402207e8d51e0c570a5868a78414f4e0cbfaed1106b171b9581542c30718ee4eb95ba02203af84194c97adf98898c9afe2f2ed4a7f8dba05a2dfab28ac9d9c604aa49a3790147304402202ade0142008309eb376736575ad58d03e5b115499709c6db0b46e36ff394b492022037b63d78d66404d6504d4c4ac13be346f3d1802928a6d3ad95a6a944227161a201475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", {});
+
+               // commitment tx with 3 htlc outputs, 2 offered having the same amount and preimage
+               chan.value_to_self_msat = 7_000_000_000 - 2_000_000;
+               chan.feerate_per_kw = 253;
+               chan.pending_inbound_htlcs.clear();
+               chan.pending_inbound_htlcs.push({
+                       let mut out = InboundHTLCOutput{
+                               htlc_id: 1,
+                               amount_msat: 2000000,
+                               cltv_expiry: 501,
+                               payment_hash: PaymentHash([0; 32]),
+                               state: InboundHTLCState::Committed,
+                       };
+                       out.payment_hash.0 = Sha256::hash(&hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()).into_inner();
+                       out
+               });
+               chan.pending_outbound_htlcs.clear();
+               chan.pending_outbound_htlcs.push({
+                       let mut out = OutboundHTLCOutput{
+                               htlc_id: 6,
+                               amount_msat: 5000000,
+                               cltv_expiry: 506,
+                               payment_hash: PaymentHash([0; 32]),
+                               state: OutboundHTLCState::Committed,
+                               source: HTLCSource::dummy(),
+                       };
+                       out.payment_hash.0 = Sha256::hash(&hex::decode("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).into_inner();
+                       out
+               });
+               chan.pending_outbound_htlcs.push({
+                       let mut out = OutboundHTLCOutput{
+                               htlc_id: 5,
+                               amount_msat: 5000000,
+                               cltv_expiry: 505,
+                               payment_hash: PaymentHash([0; 32]),
+                               state: OutboundHTLCState::Committed,
+                               source: HTLCSource::dummy(),
+                       };
+                       out.payment_hash.0 = Sha256::hash(&hex::decode("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).into_inner();
+                       out
+               });
+
+               test_commitment!("30440220048705bec5288d28b3f29344b8d124853b1af423a568664d2c6f02c8ea886525022060f998a461052a2476b912db426ea2a06700953a241135c7957f2e79bc222df9",
+                                "3045022100c4f1d60b6fca9febc8b39de1a31e84c5f7c4b41c97239ef05f4350aa484c6b5e02200c5134ac8b20eb7a29d0dd4a501f6aa8fefb8489171f4cb408bd2a32324ab03f",
+                                "02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8005d007000000000000220020748eba944fedc8827f6b06bc44678f93c0f9e6078b35c6331ed31e75f8ce0c2d8813000000000000220020305c12e1a0bc21e283c131cea1c66d68857d28b7b2fce0a6fbc40c164852121b8813000000000000220020305c12e1a0bc21e283c131cea1c66d68857d28b7b2fce0a6fbc40c164852121bc0c62d0000000000160014cc1b07838e387deacd0e5232e1e8b49f4c29e484a79f6a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400483045022100c4f1d60b6fca9febc8b39de1a31e84c5f7c4b41c97239ef05f4350aa484c6b5e02200c5134ac8b20eb7a29d0dd4a501f6aa8fefb8489171f4cb408bd2a32324ab03f014730440220048705bec5288d28b3f29344b8d124853b1af423a568664d2c6f02c8ea886525022060f998a461052a2476b912db426ea2a06700953a241135c7957f2e79bc222df901475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220", {
+
+                                 { 0,
+                                 "304502210081cbb94121761d34c189cd4e6a281feea6f585060ad0ba2632e8d6b3c6bb8a6c02201007981bbd16539d63df2805b5568f1f5688cd2a885d04706f50db9b77ba13c6",
+                                 "304502210090ed76aeb21b53236a598968abc66e2024691d07b62f53ddbeca8f93144af9c602205f873af5a0c10e62690e9aba09740550f194a9dc455ba4c1c23f6cde7704674c",
+                                 "0200000000010189a326e23addc28323dbadcb4e71c2c17088b6e8fa184103e552f44075dddc34000000000000000000011f070000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050048304502210081cbb94121761d34c189cd4e6a281feea6f585060ad0ba2632e8d6b3c6bb8a6c02201007981bbd16539d63df2805b5568f1f5688cd2a885d04706f50db9b77ba13c60148304502210090ed76aeb21b53236a598968abc66e2024691d07b62f53ddbeca8f93144af9c602205f873af5a0c10e62690e9aba09740550f194a9dc455ba4c1c23f6cde7704674c012001010101010101010101010101010101010101010101010101010101010101018a76a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c8201208763a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce23988527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae677502f501b175ac686800000000" },
+                                 { 1,
+                                 "304402201d0f09d2bf7bc245a4f17980e1e9164290df16c70c6a2ff1592f5030d6108581022061e744a7dc151b36bf0aff7a4f1812ba90b8b03633bb979a270d19858fd960c5",
+                                 "30450221009aef000d2e843a4202c1b1a2bf554abc9a7902bf49b2cb0759bc507456b7ebad02204e7c3d193ede2fd2b4cd6b39f51a920e581e35575e357e44d7b699c40ce61d39",
+                                 "0200000000010189a326e23addc28323dbadcb4e71c2c17088b6e8fa184103e552f44075dddc3401000000000000000001e1120000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e050047304402201d0f09d2bf7bc245a4f17980e1e9164290df16c70c6a2ff1592f5030d6108581022061e744a7dc151b36bf0aff7a4f1812ba90b8b03633bb979a270d19858fd960c5014830450221009aef000d2e843a4202c1b1a2bf554abc9a7902bf49b2cb0759bc507456b7ebad02204e7c3d193ede2fd2b4cd6b39f51a920e581e35575e357e44d7b699c40ce61d3901008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9142002cc93ebefbb1b73f0af055dcc27a0b504ad7688ac6868f9010000" },
+                                 { 2,
+                                 "30440220010bf035d5823596e50dce2076a4d9f942d8d28031c9c428b901a02b6b8140de02203250e8e4a08bc5b4ecdca4d0eedf98223e02e3ac1c0206b3a7ffdb374aa21e5f",
+                                 "30440220073de0067b88e425b3018b30366bfeda0ccb703118ccd3d02ead08c0f53511d002203fac50ac0e4cf8a3af0b4b1b12e801650591f748f8ddf1e089c160f10b69e511",
+                                 "0200000000010189a326e23addc28323dbadcb4e71c2c17088b6e8fa184103e552f44075dddc3402000000000000000001e1120000000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e05004730440220010bf035d5823596e50dce2076a4d9f942d8d28031c9c428b901a02b6b8140de02203250e8e4a08bc5b4ecdca4d0eedf98223e02e3ac1c0206b3a7ffdb374aa21e5f014730440220073de0067b88e425b3018b30366bfeda0ccb703118ccd3d02ead08c0f53511d002203fac50ac0e4cf8a3af0b4b1b12e801650591f748f8ddf1e089c160f10b69e51101008576a91414011f7254d96b819c76986c277d115efce6f7b58763ac67210394854aa6eab5b2a8122cc726e9dded053a2184d88256816826d6231c068d4a5b7c820120876475527c21030d417a46946384f88d5f3337267c5e579765875dc4daca813e21734b140639e752ae67a9142002cc93ebefbb1b73f0af055dcc27a0b504ad7688ac6868fa010000" }
+               } );
        }
 
        #[test]