Merge pull request #1311 from TheBlueMatt/2022-02-0conf-part-1
[rust-lightning] / lightning / src / ln / channel.rs
index dd9fcbea9a8fa2bf05c21c9cf34c04b5e8698660..71e0ea121a929f2533c3af47714a50264e83b962 100644 (file)
@@ -695,6 +695,19 @@ pub(super) struct Channel<Signer: Sign> {
 
        /// This channel's type, as negotiated during channel open
        channel_type: ChannelTypeFeatures,
+
+       // Our counterparty can offer us SCID aliases which they will map to this channel when routing
+       // outbound payments. These can be used in invoice route hints to avoid explicitly revealing
+       // the channel's funding UTXO.
+       // We only bother storing the most recent SCID alias at any time, though our counterparty has
+       // to store all of them.
+       latest_inbound_scid_alias: Option<u64>,
+
+       // We always offer our counterparty a static SCID alias, which we recognize as for this channel
+       // if we see it in HTLC forwarding instructions. We don't bother rotating the alias given we
+       // don't currently support node id aliases and eventually privacy should be provided with
+       // blinded paths instead of simple scid+node_id aliases.
+       outbound_scid_alias: u64,
 }
 
 #[cfg(any(test, fuzzing))]
@@ -800,7 +813,8 @@ impl<Signer: Sign> Channel<Signer> {
        // Constructors:
        pub fn new_outbound<K: Deref, F: Deref>(
                fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures,
-               channel_value_satoshis: u64, push_msat: u64, user_id: u64, config: &UserConfig, current_chain_height: u32
+               channel_value_satoshis: u64, push_msat: u64, user_id: u64, config: &UserConfig, current_chain_height: u32,
+               outbound_scid_alias: u64
        ) -> Result<Channel<Signer>, APIError>
        where K::Target: KeysInterface<Signer = Signer>,
              F::Target: FeeEstimator,
@@ -947,6 +961,9 @@ impl<Signer: Sign> Channel<Signer> {
 
                        workaround_lnd_bug_4006: None,
 
+                       latest_inbound_scid_alias: None,
+                       outbound_scid_alias,
+
                        #[cfg(any(test, fuzzing))]
                        historical_inbound_htlc_fulfills: HashSet::new(),
 
@@ -984,7 +1001,8 @@ impl<Signer: Sign> Channel<Signer> {
        /// Assumes chain_hash has already been checked and corresponds with what we expect!
        pub fn new_from_req<K: Deref, F: Deref, L: Deref>(
                fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures,
-               msg: &msgs::OpenChannel, user_id: u64, config: &UserConfig, current_chain_height: u32, logger: &L
+               msg: &msgs::OpenChannel, user_id: u64, config: &UserConfig, current_chain_height: u32, logger: &L,
+               outbound_scid_alias: u64
        ) -> Result<Channel<Signer>, ChannelError>
                where K::Target: KeysInterface<Signer = Signer>,
                      F::Target: FeeEstimator,
@@ -1252,6 +1270,9 @@ impl<Signer: Sign> Channel<Signer> {
 
                        workaround_lnd_bug_4006: None,
 
+                       latest_inbound_scid_alias: None,
+                       outbound_scid_alias,
+
                        #[cfg(any(test, fuzzing))]
                        historical_inbound_htlc_fulfills: HashSet::new(),
 
@@ -2151,6 +2172,15 @@ impl<Signer: Sign> Channel<Signer> {
                        return Err(ChannelError::Ignore("Peer sent funding_locked when we needed a channel_reestablish. The peer is likely lnd, see https://github.com/lightningnetwork/lnd/issues/4006".to_owned()));
                }
 
+               if let Some(scid_alias) = msg.short_channel_id_alias {
+                       if Some(scid_alias) != self.short_channel_id {
+                               // The scid alias provided can be used to route payments *from* our counterparty,
+                               // i.e. can be used for inbound payments and provided in invoices, but is not used
+                               // when routing outbound payments.
+                               self.latest_inbound_scid_alias = Some(scid_alias);
+                       }
+               }
+
                let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
 
                if non_shutdown_state == ChannelState::FundingSent as u32 {
@@ -2158,17 +2188,28 @@ impl<Signer: Sign> Channel<Signer> {
                } else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) {
                        self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & MULTI_STATE_FLAGS);
                        self.update_time_counter += 1;
-               } else if (self.channel_state & (ChannelState::ChannelFunded as u32) != 0 &&
-                                // Note that funding_signed/funding_created will have decremented both by 1!
-                                self.cur_holder_commitment_transaction_number == INITIAL_COMMITMENT_NUMBER - 1 &&
-                                self.cur_counterparty_commitment_transaction_number == INITIAL_COMMITMENT_NUMBER - 1) ||
-                               // If we reconnected before sending our funding locked they may still resend theirs:
-                               (self.channel_state & (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) ==
-                                                     (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32)) {
-                       if self.counterparty_cur_commitment_point != Some(msg.next_per_commitment_point) {
+               } else if self.channel_state & (ChannelState::ChannelFunded as u32) != 0 ||
+                       // If we reconnected before sending our funding locked they may still resend theirs:
+                       (self.channel_state & (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) ==
+                                             (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32))
+               {
+                       // They probably disconnected/reconnected and re-sent the funding_locked, which is
+                       // required, or they're sending a fresh SCID alias.
+                       let expected_point =
+                               if self.cur_counterparty_commitment_transaction_number == INITIAL_COMMITMENT_NUMBER - 1 {
+                                       // If they haven't ever sent an updated point, the point they send should match
+                                       // the current one.
+                                       self.counterparty_cur_commitment_point
+                               } else {
+                                       // If they have sent updated points, funding_locked is always supposed to match
+                                       // their "first" point, which we re-derive here.
+                                       Some(PublicKey::from_secret_key(&self.secp_ctx, &SecretKey::from_slice(
+                                                       &self.commitment_secrets.get_secret(INITIAL_COMMITMENT_NUMBER - 1).expect("We should have all prev secrets available")
+                                               ).expect("We already advanced, so previous secret keys should have been validated already")))
+                               };
+                       if expected_point != Some(msg.next_per_commitment_point) {
                                return Err(ChannelError::Close("Peer sent a reconnect funding_locked with a different point".to_owned()));
                        }
-                       // They probably disconnected/reconnected and re-sent the funding_locked, which is required
                        return Ok(None);
                } else {
                        return Err(ChannelError::Close("Peer sent a funding_locked at a strange time".to_owned()));
@@ -3457,6 +3498,7 @@ impl<Signer: Sign> Channel<Signer> {
                        Some(msgs::FundingLocked {
                                channel_id: self.channel_id(),
                                next_per_commitment_point,
+                               short_channel_id_alias: Some(self.outbound_scid_alias),
                        })
                } else { None };
 
@@ -3678,6 +3720,7 @@ impl<Signer: Sign> Channel<Signer> {
                                funding_locked: Some(msgs::FundingLocked {
                                        channel_id: self.channel_id(),
                                        next_per_commitment_point,
+                                       short_channel_id_alias: Some(self.outbound_scid_alias),
                                }),
                                raa: None, commitment_update: None, mon_update: None,
                                order: RAACommitmentOrder::CommitmentFirst,
@@ -3713,6 +3756,7 @@ impl<Signer: Sign> Channel<Signer> {
                        Some(msgs::FundingLocked {
                                channel_id: self.channel_id(),
                                next_per_commitment_point,
+                               short_channel_id_alias: Some(self.outbound_scid_alias),
                        })
                } else { None };
 
@@ -4195,6 +4239,22 @@ impl<Signer: Sign> Channel<Signer> {
                self.short_channel_id
        }
 
+       /// Allowed in any state (including after shutdown)
+       pub fn latest_inbound_scid_alias(&self) -> Option<u64> {
+               self.latest_inbound_scid_alias
+       }
+
+       /// Allowed in any state (including after shutdown)
+       pub fn outbound_scid_alias(&self) -> u64 {
+               self.outbound_scid_alias
+       }
+       /// Only allowed immediately after deserialization if get_outbound_scid_alias returns 0,
+       /// indicating we were written by LDK prior to 0.0.106 which did not set outbound SCID aliases.
+       pub fn set_outbound_scid_alias(&mut self, outbound_scid_alias: u64) {
+               assert_eq!(self.outbound_scid_alias, 0);
+               self.outbound_scid_alias = outbound_scid_alias;
+       }
+
        /// Returns the funding_txo we either got from our peer, or were given by
        /// get_outbound_funding_created.
        pub fn get_funding_txo(&self) -> Option<OutPoint> {
@@ -4443,10 +4503,12 @@ impl<Signer: Sign> Channel<Signer> {
                if need_commitment_update {
                        if self.channel_state & (ChannelState::MonitorUpdateFailed as u32) == 0 {
                                if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 {
-                                       let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
+                                       let next_per_commitment_point =
+                                               self.holder_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, &self.secp_ctx);
                                        return Some(msgs::FundingLocked {
                                                channel_id: self.channel_id,
                                                next_per_commitment_point,
+                                               short_channel_id_alias: Some(self.outbound_scid_alias),
                                        });
                                }
                        } else {
@@ -5765,6 +5827,8 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
                        (13, self.channel_creation_height, required),
                        (15, preimages, vec_type),
                        (17, self.announcement_sigs_state, required),
+                       (19, self.latest_inbound_scid_alias, option),
+                       (21, self.outbound_scid_alias, required),
                });
 
                Ok(())
@@ -6020,6 +6084,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
                // If we read an old Channel, for simplicity we just treat it as "we never sent an
                // AnnouncementSignatures" which implies we'll re-send it on reconnect, but that's fine.
                let mut announcement_sigs_state = Some(AnnouncementSigsState::NotSent);
+               let mut latest_inbound_scid_alias = None;
+               let mut outbound_scid_alias = None;
 
                read_tlv_fields!(reader, {
                        (0, announcement_sigs, option),
@@ -6035,6 +6101,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
                        (13, channel_creation_height, option),
                        (15, preimages_opt, vec_type),
                        (17, announcement_sigs_state, option),
+                       (19, latest_inbound_scid_alias, option),
+                       (21, outbound_scid_alias, option),
                });
 
                if let Some(preimages) = preimages_opt {
@@ -6169,6 +6237,10 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
 
                        workaround_lnd_bug_4006: None,
 
+                       latest_inbound_scid_alias,
+                       // Later in the ChannelManager deserialization phase we scan for channels and assign scid aliases if its missing
+                       outbound_scid_alias: outbound_scid_alias.unwrap_or(0),
+
                        #[cfg(any(test, fuzzing))]
                        historical_inbound_htlc_fulfills,
 
@@ -6291,7 +6363,7 @@ mod tests {
                let secp_ctx = Secp256k1::new();
                let node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let config = UserConfig::default();
-               match Channel::<EnforcingSigner>::new_outbound(&&fee_estimator, &&keys_provider, node_id, &features, 10000000, 100000, 42, &config, 0) {
+               match Channel::<EnforcingSigner>::new_outbound(&&fee_estimator, &&keys_provider, node_id, &features, 10000000, 100000, 42, &config, 0, 42) {
                        Err(APIError::IncompatibleShutdownScript { script }) => {
                                assert_eq!(script.into_inner(), non_v0_segwit_shutdown_script.into_inner());
                        },
@@ -6313,7 +6385,7 @@ mod tests {
 
                let node_a_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let config = UserConfig::default();
-               let node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_a_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
+               let node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_a_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0, 42).unwrap();
 
                // Now change the fee so we can check that the fee in the open_channel message is the
                // same as the old fee.
@@ -6339,13 +6411,13 @@ mod tests {
                // Create Node A's channel pointing to Node B's pubkey
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let config = UserConfig::default();
-               let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
+               let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0, 42).unwrap();
 
                // Create Node B's channel by receiving Node A's open_channel message
                // Make sure A's dust limit is as we expect.
                let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_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, 0, &&logger).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, 0, &&logger, 42).unwrap();
 
                // Node B --> Node A: accept channel, explicitly setting B's dust limit.
                let mut accept_channel_msg = node_b_chan.accept_inbound_channel();
@@ -6409,7 +6481,7 @@ mod tests {
 
                let node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let config = UserConfig::default();
-               let mut chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
+               let mut chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0, 42).unwrap();
 
                let commitment_tx_fee_0_htlcs = Channel::<EnforcingSigner>::commit_tx_fee_msat(chan.feerate_per_kw, 0, chan.opt_anchors());
                let commitment_tx_fee_1_htlc = Channel::<EnforcingSigner>::commit_tx_fee_msat(chan.feerate_per_kw, 1, chan.opt_anchors());
@@ -6458,12 +6530,12 @@ mod tests {
                // Create Node A's channel pointing to Node B's pubkey
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let config = UserConfig::default();
-               let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
+               let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0, 42).unwrap();
 
                // Create Node B's channel by receiving Node A's open_channel message
                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, 0, &&logger).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, 0, &&logger, 42).unwrap();
 
                // Node B --> Node A: accept channel
                let accept_channel_msg = node_b_chan.accept_inbound_channel();
@@ -6520,7 +6592,7 @@ mod tests {
                // Create a channel.
                let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let config = UserConfig::default();
-               let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
+               let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0, 42).unwrap();
                assert!(node_a_chan.counterparty_forwarding_info.is_none());
                assert_eq!(node_a_chan.holder_htlc_minimum_msat, 1); // the default
                assert!(node_a_chan.counterparty_forwarding_info().is_none());
@@ -6585,7 +6657,7 @@ mod tests {
                let counterparty_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
                let mut config = UserConfig::default();
                config.channel_options.announced_channel = false;
-               let mut chan = Channel::<InMemorySigner>::new_outbound(&&feeest, &&keys_provider, counterparty_node_id, &InitFeatures::known(), 10_000_000, 100000, 42, &config, 0).unwrap(); // Nothing uses their network key in this test
+               let mut chan = Channel::<InMemorySigner>::new_outbound(&&feeest, &&keys_provider, counterparty_node_id, &InitFeatures::known(), 10_000_000, 100000, 42, &config, 0, 42).unwrap(); // Nothing uses their network key in this test
                chan.holder_dust_limit_satoshis = 546;
                chan.counterparty_selected_channel_reserve_satoshis = Some(0); // Filled in in accept_channel