Merge pull request #828 from bmancini55/reply_channel_range
[rust-lightning] / lightning / src / ln / channel.rs
index 73f79f3882fd622d101cf72df8bd27a4839f461e..13b2dbb1a1c6a7b9f54b996e03ab6acc6bdcbf11 100644 (file)
@@ -37,9 +37,9 @@ use util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter};
 use util::logger::Logger;
 use util::errors::APIError;
 use util::config::{UserConfig,ChannelConfig};
+use util::scid_utils::scid_from_parts;
 
 use std;
-use std::default::Default;
 use std::{cmp,mem,fmt};
 use std::ops::Deref;
 #[cfg(any(test, feature = "fuzztarget"))]
@@ -368,8 +368,6 @@ pub(super) struct Channel<Signer: Sign> {
        /// could miss the funding_tx_confirmed_in block as well, but it serves as a useful fallback.
        funding_tx_confirmed_in: Option<BlockHash>,
        short_channel_id: Option<u64>,
-       /// Used to verify consistency during ChannelManager deserialization (hence pub(super)).
-       pub(super) last_block_connected: BlockHash,
        funding_tx_confirmations: u64,
 
        counterparty_dust_limit_satoshis: u64,
@@ -568,7 +566,6 @@ impl<Signer: Sign> Channel<Signer> {
 
                        funding_tx_confirmed_in: None,
                        short_channel_id: None,
-                       last_block_connected: Default::default(),
                        funding_tx_confirmations: 0,
 
                        feerate_per_kw: feerate,
@@ -804,7 +801,6 @@ impl<Signer: Sign> Channel<Signer> {
 
                        funding_tx_confirmed_in: None,
                        short_channel_id: None,
-                       last_block_connected: Default::default(),
                        funding_tx_confirmations: 0,
 
                        feerate_per_kw: msg.feerate_per_kw,
@@ -1521,7 +1517,7 @@ impl<Signer: Sign> Channel<Signer> {
                &self.get_counterparty_pubkeys().funding_pubkey
        }
 
-       pub fn funding_created<L: Deref>(&mut self, msg: &msgs::FundingCreated, logger: &L) -> Result<(msgs::FundingSigned, ChannelMonitor<Signer>), ChannelError> where L::Target: Logger {
+       pub fn funding_created<L: Deref>(&mut self, msg: &msgs::FundingCreated, last_block_hash: BlockHash, logger: &L) -> Result<(msgs::FundingSigned, ChannelMonitor<Signer>), ChannelError> where L::Target: Logger {
                if self.is_outbound() {
                        return Err(ChannelError::Close("Received funding_created for an outbound channel?".to_owned()));
                }
@@ -1575,7 +1571,7 @@ impl<Signer: Sign> Channel<Signer> {
                                                          &self.channel_transaction_parameters,
                                                          funding_redeemscript.clone(), self.channel_value_satoshis,
                                                          obscure_factor,
-                                                         holder_commitment_tx);
+                                                         holder_commitment_tx, last_block_hash);
 
                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);
 
@@ -1592,7 +1588,7 @@ impl<Signer: Sign> Channel<Signer> {
 
        /// Handles a funding_signed message from the remote end.
        /// If this call is successful, broadcast the funding transaction (and not before!)
-       pub fn funding_signed<L: Deref>(&mut self, msg: &msgs::FundingSigned, logger: &L) -> Result<ChannelMonitor<Signer>, ChannelError> where L::Target: Logger {
+       pub fn funding_signed<L: Deref>(&mut self, msg: &msgs::FundingSigned, last_block_hash: BlockHash, logger: &L) -> Result<ChannelMonitor<Signer>, ChannelError> where L::Target: Logger {
                if !self.is_outbound() {
                        return Err(ChannelError::Close("Received funding_signed for an inbound channel?".to_owned()));
                }
@@ -1645,7 +1641,7 @@ impl<Signer: Sign> Channel<Signer> {
                                                          &self.channel_transaction_parameters,
                                                          funding_redeemscript.clone(), self.channel_value_satoshis,
                                                          obscure_factor,
-                                                         holder_commitment_tx);
+                                                         holder_commitment_tx, last_block_hash);
 
                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);
 
@@ -3555,20 +3551,16 @@ impl<Signer: Sign> Channel<Signer> {
                                                                }
                                                        }
                                                }
-                                               if height > 0xff_ff_ff || (index_in_block) > 0xff_ff_ff {
-                                                       panic!("Block was bogus - either height 16 million or had > 16 million transactions");
-                                               }
-                                               assert!(txo_idx <= 0xffff); // txo_idx is a (u16 as usize), so this is just listed here for completeness
                                                self.funding_tx_confirmations = 1;
-                                               self.short_channel_id = Some(((height as u64)         << (5*8)) |
-                                                                            ((index_in_block as u64) << (2*8)) |
-                                                                            ((txo_idx as u64)        << (0*8)));
+                                               self.short_channel_id = match scid_from_parts(height as u64, index_in_block as u64, txo_idx as u64) {
+                                                       Ok(scid) => Some(scid),
+                                                       Err(_) => panic!("Block was bogus - either height was > 16 million, had > 16 million transactions, or had > 65k outputs"),
+                                               }
                                        }
                                }
                        }
                }
 
-               self.last_block_connected = header.block_hash();
                self.update_time_counter = cmp::max(self.update_time_counter, header.time);
                if self.funding_tx_confirmations > 0 {
                        if self.funding_tx_confirmations == self.minimum_depth as u64 {
@@ -3590,7 +3582,7 @@ impl<Signer: Sign> Channel<Signer> {
                                        // funding_tx_confirmed_in and return.
                                        false
                                };
-                               self.funding_tx_confirmed_in = Some(self.last_block_connected);
+                               self.funding_tx_confirmed_in = Some(header.block_hash());
 
                                //TODO: Note that this must be a duplicate of the previous commitment point they sent us,
                                //as otherwise we will have a commitment transaction that they can't revoke (well, kinda,
@@ -3623,8 +3615,7 @@ impl<Signer: Sign> Channel<Signer> {
                                return true;
                        }
                }
-               self.last_block_connected = header.block_hash();
-               if Some(self.last_block_connected) == self.funding_tx_confirmed_in {
+               if Some(header.block_hash()) == self.funding_tx_confirmed_in {
                        self.funding_tx_confirmations = self.minimum_depth as u64 - 1;
                }
                false
@@ -4433,8 +4424,6 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
 
                self.funding_tx_confirmed_in.write(writer)?;
                self.short_channel_id.write(writer)?;
-
-               self.last_block_connected.write(writer)?;
                self.funding_tx_confirmations.write(writer)?;
 
                self.counterparty_dust_limit_satoshis.write(writer)?;
@@ -4595,8 +4584,6 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
 
                let funding_tx_confirmed_in = Readable::read(reader)?;
                let short_channel_id = Readable::read(reader)?;
-
-               let last_block_connected = Readable::read(reader)?;
                let funding_tx_confirmations = Readable::read(reader)?;
 
                let counterparty_dust_limit_satoshis = Readable::read(reader)?;
@@ -4667,7 +4654,6 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
 
                        funding_tx_confirmed_in,
                        short_channel_id,
-                       last_block_connected,
                        funding_tx_confirmations,
 
                        counterparty_dust_limit_satoshis,
@@ -4922,6 +4908,8 @@ mod tests {
                let secp_ctx = Secp256k1::new();
                let seed = [42; 32];
                let network = Network::Testnet;
+               let chain_hash = genesis_block(network).header.block_hash();
+               let last_block_hash = chain_hash;
                let keys_provider = test_utils::TestKeysInterface::new(&seed, network);
 
                // Go through the flow of opening a channel between two nodes.
@@ -4932,7 +4920,7 @@ mod tests {
                let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, 10000000, 100000, 42, &config).unwrap();
 
                // Create Node B's channel by receiving Node A's open_channel message
-               let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
+               let open_channel_msg = node_a_chan.get_open_channel(chain_hash);
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
                let mut node_b_chan = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, InitFeatures::known(), &open_channel_msg, 7, &config).unwrap();
 
@@ -4947,10 +4935,10 @@ mod tests {
                }]};
                let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
                let funding_created_msg = node_a_chan.get_outbound_funding_created(funding_outpoint, &&logger).unwrap();
-               let (funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, &&logger).unwrap();
+               let (funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, last_block_hash, &&logger).unwrap();
 
                // Node B --> Node A: funding signed
-               let _ = node_a_chan.funding_signed(&funding_signed_msg, &&logger);
+               let _ = node_a_chan.funding_signed(&funding_signed_msg, last_block_hash, &&logger);
 
                // Now disconnect the two nodes and check that the commitment point in
                // Node B's channel_reestablish message is sane.