Support receiving multiple funding_locked messages
[rust-lightning] / lightning / src / ln / channel.rs
index 2b03e2d426d200fa335a14ca50b4de98f3564081..71e0ea121a929f2533c3af47714a50264e83b962 100644 (file)
@@ -46,7 +46,7 @@ use io;
 use prelude::*;
 use core::{cmp,mem,fmt};
 use core::ops::Deref;
-#[cfg(any(test, feature = "fuzztarget", debug_assertions))]
+#[cfg(any(test, fuzzing, debug_assertions))]
 use sync::Mutex;
 use bitcoin::hashes::hex::ToHex;
 
@@ -670,9 +670,9 @@ pub(super) struct Channel<Signer: Sign> {
        // `next_remote_commit_tx_fee_msat` properly predict what the next commitment transaction fee will
        // be, by comparing the cached values to the fee of the tranaction generated by
        // `build_commitment_transaction`.
-       #[cfg(any(test, feature = "fuzztarget"))]
+       #[cfg(any(test, fuzzing))]
        next_local_commitment_tx_fee_info_cached: Mutex<Option<CommitmentTxInfoCached>>,
-       #[cfg(any(test, feature = "fuzztarget"))]
+       #[cfg(any(test, fuzzing))]
        next_remote_commitment_tx_fee_info_cached: Mutex<Option<CommitmentTxInfoCached>>,
 
        /// lnd has a long-standing bug where, upon reconnection, if the channel is not yet confirmed
@@ -684,7 +684,7 @@ pub(super) struct Channel<Signer: Sign> {
        /// See-also <https://github.com/lightningnetwork/lnd/issues/4006>
        pub workaround_lnd_bug_4006: Option<msgs::FundingLocked>,
 
-       #[cfg(any(test, feature = "fuzztarget"))]
+       #[cfg(any(test, fuzzing))]
        // When we receive an HTLC fulfill on an outbound path, we may immediately fulfill the
        // corresponding HTLC on the inbound path. If, then, the outbound path channel is
        // disconnected and reconnected (before we've exchange commitment_signed and revoke_and_ack
@@ -695,9 +695,22 @@ 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, feature = "fuzztarget"))]
+#[cfg(any(test, fuzzing))]
 struct CommitmentTxInfoCached {
        fee: u64,
        total_pending_htlcs: usize,
@@ -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,
@@ -940,14 +954,17 @@ impl<Signer: Sign> Channel<Signer> {
 
                        announcement_sigs: None,
 
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        next_local_commitment_tx_fee_info_cached: Mutex::new(None),
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
 
                        workaround_lnd_bug_4006: None,
 
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       latest_inbound_scid_alias: None,
+                       outbound_scid_alias,
+
+                       #[cfg(any(test, fuzzing))]
                        historical_inbound_htlc_fulfills: HashSet::new(),
 
                        // We currently only actually support one channel type, so don't retry with new types
@@ -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,
@@ -1245,14 +1263,17 @@ impl<Signer: Sign> Channel<Signer> {
 
                        announcement_sigs: None,
 
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        next_local_commitment_tx_fee_info_cached: Mutex::new(None),
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
 
                        workaround_lnd_bug_4006: None,
 
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       latest_inbound_scid_alias: None,
+                       outbound_scid_alias,
+
+                       #[cfg(any(test, fuzzing))]
                        historical_inbound_htlc_fulfills: HashSet::new(),
 
                        channel_type,
@@ -1650,7 +1671,7 @@ impl<Signer: Sign> Channel<Signer> {
                        }
                }
                if pending_idx == core::usize::MAX {
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        // If we failed to find an HTLC to fulfill, make sure it was previously fulfilled and
                        // this is simply a duplicate claim, not previously failed and we lost funds.
                        debug_assert!(self.historical_inbound_htlc_fulfills.contains(&htlc_id_arg));
@@ -1676,7 +1697,7 @@ impl<Signer: Sign> Channel<Signer> {
                                                if htlc_id_arg == htlc_id {
                                                        // Make sure we don't leave latest_monitor_update_id incremented here:
                                                        self.latest_monitor_update_id -= 1;
-                                                       #[cfg(any(test, feature = "fuzztarget"))]
+                                                       #[cfg(any(test, fuzzing))]
                                                        debug_assert!(self.historical_inbound_htlc_fulfills.contains(&htlc_id_arg));
                                                        return UpdateFulfillFetch::DuplicateClaim {};
                                                }
@@ -1697,11 +1718,11 @@ impl<Signer: Sign> Channel<Signer> {
                        self.holding_cell_htlc_updates.push(HTLCUpdateAwaitingACK::ClaimHTLC {
                                payment_preimage: payment_preimage_arg, htlc_id: htlc_id_arg,
                        });
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        self.historical_inbound_htlc_fulfills.insert(htlc_id_arg);
                        return UpdateFulfillFetch::NewClaim { monitor_update, htlc_value_msat, msg: None };
                }
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                self.historical_inbound_htlc_fulfills.insert(htlc_id_arg);
 
                {
@@ -1782,7 +1803,7 @@ impl<Signer: Sign> Channel<Signer> {
                        }
                }
                if pending_idx == core::usize::MAX {
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        // If we failed to find an HTLC to fail, make sure it was previously fulfilled and this
                        // is simply a duplicate fail, not previously failed and we failed-back too early.
                        debug_assert!(self.historical_inbound_htlc_fulfills.contains(&htlc_id_arg));
@@ -1795,7 +1816,7 @@ impl<Signer: Sign> Channel<Signer> {
                                match pending_update {
                                        &HTLCUpdateAwaitingACK::ClaimHTLC { htlc_id, .. } => {
                                                if htlc_id_arg == htlc_id {
-                                                       #[cfg(any(test, feature = "fuzztarget"))]
+                                                       #[cfg(any(test, fuzzing))]
                                                        debug_assert!(self.historical_inbound_htlc_fulfills.contains(&htlc_id_arg));
                                                        return Ok(None);
                                                }
@@ -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()));
@@ -2377,7 +2418,7 @@ impl<Signer: Sign> Channel<Signer> {
 
                let num_htlcs = included_htlcs + addl_htlcs;
                let res = Self::commit_tx_fee_msat(self.feerate_per_kw, num_htlcs, self.opt_anchors());
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                {
                        let mut fee = res;
                        if fee_spike_buffer_htlc.is_some() {
@@ -2455,7 +2496,7 @@ impl<Signer: Sign> Channel<Signer> {
 
                let num_htlcs = included_htlcs + addl_htlcs;
                let res = Self::commit_tx_fee_msat(self.feerate_per_kw, num_htlcs, self.opt_anchors());
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                {
                        let mut fee = res;
                        if fee_spike_buffer_htlc.is_some() {
@@ -2738,7 +2779,7 @@ impl<Signer: Sign> Channel<Signer> {
                                return Err((None, ChannelError::Close("Funding remote cannot afford proposed new fee".to_owned())));
                        }
                }
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                {
                        if self.is_outbound() {
                                let projected_commit_tx_info = self.next_local_commitment_tx_fee_info_cached.lock().unwrap().take();
@@ -3045,7 +3086,7 @@ impl<Signer: Sign> Channel<Signer> {
                        return Err(ChannelError::Close("Received an unexpected revoke_and_ack".to_owned()));
                }
 
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                {
                        *self.next_local_commitment_tx_fee_info_cached.lock().unwrap() = None;
                        *self.next_remote_commitment_tx_fee_info_cached.lock().unwrap() = None;
@@ -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 {
@@ -4476,9 +4538,9 @@ impl<Signer: Sign> Channel<Signer> {
                                                                // If we generated the funding transaction and it doesn't match what it
                                                                // should, the client is really broken and we should just panic and
                                                                // tell them off. That said, because hash collisions happen with high
-                                                               // probability in fuzztarget mode, if we're fuzzing we just close the
+                                                               // probability in fuzzing mode, if we're fuzzing we just close the
                                                                // channel and move on.
-                                                               #[cfg(not(feature = "fuzztarget"))]
+                                                               #[cfg(not(fuzzing))]
                                                                panic!("Client called ChannelManager::funding_transaction_generated with bogus transaction!");
                                                        }
                                                        self.update_time_counter += 1;
@@ -4490,7 +4552,7 @@ impl<Signer: Sign> Channel<Signer> {
                                                                        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"))]
+                                                                               #[cfg(not(fuzzing))]
                                                                                panic!("Client called ChannelManager::funding_transaction_generated with bogus transaction!");
                                                                        }
                                                                }
@@ -4948,9 +5010,9 @@ impl<Signer: Sign> Channel<Signer> {
                // Prior to static_remotekey, my_current_per_commitment_point was critical to claiming
                // current to_remote balances. However, it no longer has any use, and thus is now simply
                // set to a dummy (but valid, as required by the spec) public key.
-               // fuzztarget mode marks a subset of pubkeys as invalid so that we can hit "invalid pubkey"
+               // fuzzing mode marks a subset of pubkeys as invalid so that we can hit "invalid pubkey"
                // branches, but we unwrap it below, so we arbitrarily select a dummy pubkey which is both
-               // valid, and valid in fuzztarget mode's arbitrary validity criteria:
+               // valid, and valid in fuzzing mode's arbitrary validity criteria:
                let mut pk = [2; 33]; pk[1] = 0xff;
                let dummy_pubkey = PublicKey::from_slice(&pk).unwrap();
                let data_loss_protect = if self.cur_counterparty_commitment_transaction_number + 1 < INITIAL_COMMITMENT_NUMBER {
@@ -5236,7 +5298,7 @@ impl<Signer: Sign> Channel<Signer> {
                let counterparty_commitment_txid = commitment_stats.tx.trust().txid();
                let (signature, htlc_signatures);
 
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                {
                        if !self.is_outbound() {
                                let projected_commit_tx_info = self.next_remote_commitment_tx_fee_info_cached.lock().unwrap().take();
@@ -5722,9 +5784,9 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
 
                self.channel_update_status.write(writer)?;
 
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                (self.historical_inbound_htlc_fulfills.len() as u64).write(writer)?;
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                for htlc in self.historical_inbound_htlc_fulfills.iter() {
                        htlc.write(writer)?;
                }
@@ -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(())
@@ -5986,9 +6050,9 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
 
                let channel_update_status = Readable::read(reader)?;
 
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                let mut historical_inbound_htlc_fulfills = HashSet::new();
-               #[cfg(any(test, feature = "fuzztarget"))]
+               #[cfg(any(test, fuzzing))]
                {
                        let htlc_fulfills_len: u64 = Readable::read(reader)?;
                        for _ in 0..htlc_fulfills_len {
@@ -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 {
@@ -6162,14 +6230,18 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
 
                        announcement_sigs,
 
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        next_local_commitment_tx_fee_info_cached: Mutex::new(None),
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       #[cfg(any(test, fuzzing))]
                        next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
 
                        workaround_lnd_bug_4006: None,
 
-                       #[cfg(any(test, feature = "fuzztarget"))]
+                       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,
 
                        channel_type: channel_type.unwrap(),
@@ -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