Remove user_payment_id
[rust-lightning] / lightning / src / ln / channel.rs
index 3e2b05d080976dfa5e79fad667889b1b2e73917e..e0f7a1ae7c2bae2aee35c5f8310389729a3be0cb 100644 (file)
@@ -23,7 +23,7 @@ use bitcoin::secp256k1::{Secp256k1,Signature};
 use bitcoin::secp256k1;
 
 use ln::{PaymentPreimage, PaymentHash};
-use ln::features::{ChannelFeatures, InitFeatures};
+use ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures};
 use ln::msgs;
 use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
 use ln::script::{self, ShutdownScript};
@@ -32,9 +32,10 @@ use ln::chan_utils::{CounterpartyCommitmentSecrets, TxCreationKeys, HTLCOutputIn
 use ln::chan_utils;
 use chain::BestBlock;
 use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
-use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, HTLC_FAIL_BACK_BUFFER};
+use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS};
 use chain::transaction::{OutPoint, TransactionData};
 use chain::keysinterface::{Sign, KeysInterface};
+use util::events::ClosureReason;
 use util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter};
 use util::logger::Logger;
 use util::errors::APIError;
@@ -378,6 +379,11 @@ pub const FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE: u64 = 2;
 #[cfg(not(fuzzing))]
 const FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE: u64 = 2;
 
+/// If we fail to see a funding transaction confirmed on-chain within this many blocks after the
+/// channel creation on an inbound channel, we simply force-close and move on.
+/// This constant is the one suggested in BOLT 2.
+pub(crate) const FUNDING_CONF_DEADLINE_BLOCKS: u32 = 2016;
+
 // TODO: We should refactor this to be an Inbound/OutboundChannel until initial setup handshaking
 // has been completed, and then turn into a Channel to get compiler-time enforcement of things like
 // calling channel_id() before we're set up or things like get_outbound_funding_signed on an
@@ -475,6 +481,10 @@ pub(super) struct Channel<Signer: Sign> {
        funding_tx_confirmed_in: Option<BlockHash>,
        funding_tx_confirmation_height: u32,
        short_channel_id: Option<u64>,
+       /// Either the height at which this channel was created or the height at which it was last
+       /// serialized if it was serialized by versions prior to 0.0.103.
+       /// We use this to close if funding is never broadcasted.
+       channel_creation_height: u32,
 
        counterparty_dust_limit_satoshis: u64,
        #[cfg(test)]
@@ -550,6 +560,9 @@ pub(super) struct Channel<Signer: Sign> {
        // is fine, but as a sanity check in our failure to generate the second claim, we check here
        // that the original was a claim, and that we aren't now trying to fulfill a failed HTLC.
        historical_inbound_htlc_fulfills: HashSet<u64>,
+
+       /// This channel's type, as negotiated during channel open
+       channel_type: ChannelTypeFeatures,
 }
 
 #[cfg(any(test, feature = "fuzztarget"))]
@@ -643,7 +656,10 @@ 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) -> Result<Channel<Signer>, APIError>
+       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
+       ) -> Result<Channel<Signer>, APIError>
        where K::Target: KeysInterface<Signer = Signer>,
              F::Target: FeeEstimator,
        {
@@ -731,6 +747,7 @@ impl<Signer: Sign> Channel<Signer> {
                        funding_tx_confirmed_in: None,
                        funding_tx_confirmation_height: 0,
                        short_channel_id: None,
+                       channel_creation_height: current_chain_height,
 
                        feerate_per_kw: feerate,
                        counterparty_dust_limit_satoshis: 0,
@@ -775,6 +792,11 @@ impl<Signer: Sign> Channel<Signer> {
 
                        #[cfg(any(test, feature = "fuzztarget"))]
                        historical_inbound_htlc_fulfills: HashSet::new(),
+
+                       // We currently only actually support one channel type, so don't retry with new types
+                       // on error messages. When we support more we'll need fallback support (assuming we
+                       // want to support old types).
+                       channel_type: ChannelTypeFeatures::only_static_remote_key(),
                })
        }
 
@@ -799,10 +821,30 @@ impl<Signer: Sign> Channel<Signer> {
 
        /// Creates a new channel from a remote sides' request for one.
        /// Assumes chain_hash has already been checked and corresponds with what we expect!
-       pub fn new_from_req<K: Deref, F: Deref>(fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures, msg: &msgs::OpenChannel, user_id: u64, config: &UserConfig) -> Result<Channel<Signer>, ChannelError>
+       pub fn new_from_req<K: Deref, F: 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
+       ) -> Result<Channel<Signer>, ChannelError>
                where K::Target: KeysInterface<Signer = Signer>,
           F::Target: FeeEstimator
        {
+               // First check the channel type is known, failing before we do anything else if we don't
+               // support this channel type.
+               let channel_type = if let Some(channel_type) = &msg.channel_type {
+                       if channel_type.supports_any_optional_bits() {
+                               return Err(ChannelError::Close("Channel Type field contained optional bits - this is not allowed".to_owned()));
+                       }
+                       if *channel_type != ChannelTypeFeatures::only_static_remote_key() {
+                               return Err(ChannelError::Close("Channel Type was not understood".to_owned()));
+                       }
+                       channel_type.clone()
+               } else {
+                       ChannelTypeFeatures::from_counterparty_init(&their_features)
+               };
+               if !channel_type.supports_static_remote_key() {
+                       return Err(ChannelError::Close("Channel Type was not understood - we require static remote key".to_owned()));
+               }
+
                let holder_signer = keys_provider.get_channel_signer(true, msg.funding_satoshis);
                let pubkeys = holder_signer.pubkeys().clone();
                let counterparty_pubkeys = ChannelPublicKeys {
@@ -995,6 +1037,7 @@ impl<Signer: Sign> Channel<Signer> {
                        funding_tx_confirmed_in: None,
                        funding_tx_confirmation_height: 0,
                        short_channel_id: None,
+                       channel_creation_height: current_chain_height,
 
                        feerate_per_kw: msg.feerate_per_kw,
                        channel_value_satoshis: msg.funding_satoshis,
@@ -1043,6 +1086,8 @@ impl<Signer: Sign> Channel<Signer> {
 
                        #[cfg(any(test, feature = "fuzztarget"))]
                        historical_inbound_htlc_fulfills: HashSet::new(),
+
+                       channel_type,
                };
 
                Ok(chan)
@@ -4090,7 +4135,7 @@ impl<Signer: Sign> Channel<Signer> {
        /// In the first case, we store the confirmation height and calculating the short channel id.
        /// In the second, we simply return an Err indicating we need to be force-closed now.
        pub fn transactions_confirmed<L: Deref>(&mut self, block_hash: &BlockHash, height: u32, txdata: &TransactionData, logger: &L)
-                       -> Result<Option<msgs::FundingLocked>, msgs::ErrorMessage> where L::Target: Logger {
+       -> Result<Option<msgs::FundingLocked>, ClosureReason> where L::Target: Logger {
                let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
                for &(index_in_block, tx) in txdata.iter() {
                        if let Some(funding_txo) = self.get_funding_txo() {
@@ -4111,10 +4156,8 @@ impl<Signer: Sign> Channel<Signer> {
                                                                panic!("Client called ChannelManager::funding_transaction_generated with bogus transaction!");
                                                        }
                                                        self.update_time_counter += 1;
-                                                       return Err(msgs::ErrorMessage {
-                                                               channel_id: self.channel_id(),
-                                                               data: "funding tx had wrong script/value or output index".to_owned()
-                                                       });
+                                                       let err_reason = "funding tx had wrong script/value or output index";
+                                                       return Err(ClosureReason::ProcessingError { err: err_reason.to_owned() });
                                                } else {
                                                        if self.is_outbound() {
                                                                for input in tx.input.iter() {
@@ -4145,10 +4188,7 @@ impl<Signer: Sign> Channel<Signer> {
                                for inp in tx.input.iter() {
                                        if inp.previous_output == funding_txo.into_bitcoin_outpoint() {
                                                log_info!(logger, "Detected channel-closing tx {} spending {}:{}, closing channel {}", tx.txid(), inp.previous_output.txid, inp.previous_output.vout, log_bytes!(self.channel_id()));
-                                               return Err(msgs::ErrorMessage {
-                                                       channel_id: self.channel_id(),
-                                                       data: "Commitment or closing transaction was confirmed on chain.".to_owned()
-                                               });
+                                               return Err(ClosureReason::CommitmentTxConfirmed);
                                        }
                                }
                        }
@@ -4168,9 +4208,12 @@ impl<Signer: Sign> Channel<Signer> {
        /// May return some HTLCs (and their payment_hash) which have timed out and should be failed
        /// back.
        pub fn best_block_updated<L: Deref>(&mut self, height: u32, highest_header_time: u32, logger: &L)
-                       -> Result<(Option<msgs::FundingLocked>, Vec<(HTLCSource, PaymentHash)>), msgs::ErrorMessage> where L::Target: Logger {
+       -> Result<(Option<msgs::FundingLocked>, Vec<(HTLCSource, PaymentHash)>), ClosureReason> where L::Target: Logger {
                let mut timed_out_htlcs = Vec::new();
-               let unforwarded_htlc_cltv_limit = height + HTLC_FAIL_BACK_BUFFER;
+               // This mirrors the check in ChannelManager::decode_update_add_htlc_onion, refusing to
+               // forward an HTLC when our counterparty should almost certainly just fail it for expiring
+               // ~now.
+               let unforwarded_htlc_cltv_limit = height + LATENCY_GRACE_PERIOD_BLOCKS;
                self.holding_cell_htlc_updates.retain(|htlc_update| {
                        match htlc_update {
                                &HTLCUpdateAwaitingACK::AddHTLC { ref payment_hash, ref source, ref cltv_expiry, .. } => {
@@ -4206,11 +4249,17 @@ impl<Signer: Sign> Channel<Signer> {
                        // close the channel and hope we can get the latest state on chain (because presumably
                        // the funding transaction is at least still in the mempool of most nodes).
                        if funding_tx_confirmations < self.minimum_depth.unwrap() as i64 / 2 {
-                               return Err(msgs::ErrorMessage {
-                                       channel_id: self.channel_id(),
-                                       data: format!("Funding transaction was un-confirmed. Locked at {} confs, now have {} confs.", self.minimum_depth.unwrap(), funding_tx_confirmations),
-                               });
+                               let err_reason = format!("Funding transaction was un-confirmed. Locked at {} confs, now have {} confs.",
+                                       self.minimum_depth.unwrap(), funding_tx_confirmations);
+                               return Err(ClosureReason::ProcessingError { err: err_reason });
                        }
+               } else if !self.is_outbound() && self.funding_tx_confirmed_in.is_none() &&
+                               height >= self.channel_creation_height + FUNDING_CONF_DEADLINE_BLOCKS {
+                       log_info!(logger, "Closing channel {} due to funding timeout", log_bytes!(self.channel_id));
+                       // If funding_tx_confirmed_in is unset, the channel must not be active
+                       assert!(non_shutdown_state <= ChannelState::ChannelFunded as u32);
+                       assert_eq!(non_shutdown_state & ChannelState::OurFundingLocked as u32, 0);
+                       return Err(ClosureReason::FundingTimedOut);
                }
 
                Ok((None, timed_out_htlcs))
@@ -4219,7 +4268,7 @@ impl<Signer: Sign> Channel<Signer> {
        /// Indicates the funding transaction is no longer confirmed in the main chain. This may
        /// force-close the channel, but may also indicate a harmless reorganization of a block or two
        /// before the channel has reached funding_locked and we can just wait for more blocks.
-       pub fn funding_transaction_unconfirmed<L: Deref>(&mut self, logger: &L) -> Result<(), msgs::ErrorMessage> where L::Target: Logger {
+       pub fn funding_transaction_unconfirmed<L: Deref>(&mut self, logger: &L) -> Result<(), ClosureReason> where L::Target: Logger {
                if self.funding_tx_confirmation_height != 0 {
                        // We handle the funding disconnection by calling best_block_updated with a height one
                        // below where our funding was connected, implying a reorg back to conf_height - 1.
@@ -4283,7 +4332,7 @@ impl<Signer: Sign> Channel<Signer> {
                                Some(script) => script.clone().into_inner(),
                                None => Builder::new().into_script(),
                        }),
-                       channel_type: None,
+                       channel_type: Some(self.channel_type.clone()),
                }
        }
 
@@ -5227,6 +5276,13 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
                        htlc.write(writer)?;
                }
 
+               // If the channel type is something other than only-static-remote-key, then we need to have
+               // older clients fail to deserialize this channel at all. If the type is
+               // only-static-remote-key, we simply consider it "default" and don't write the channel type
+               // out at all.
+               let chan_type = if self.channel_type != ChannelTypeFeatures::only_static_remote_key() {
+                       Some(&self.channel_type) } else { None };
+
                write_tlv_fields!(writer, {
                        (0, self.announcement_sigs, option),
                        // minimum_depth and counterparty_selected_channel_reserve_satoshis used to have a
@@ -5236,11 +5292,13 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
                        // and new versions map the default values to None and allow the TLV entries here to
                        // override that.
                        (1, self.minimum_depth, option),
+                       (2, chan_type, option),
                        (3, self.counterparty_selected_channel_reserve_satoshis, option),
                        (5, self.config, required),
                        (7, self.shutdown_scriptpubkey, option),
                        (9, self.target_closing_feerate_sats_per_kw, option),
                        (11, self.monitor_pending_finalized_fulfills, vec_type),
+                       (13, self.channel_creation_height, required),
                });
 
                Ok(())
@@ -5248,9 +5306,10 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
 }
 
 const MAX_ALLOC_SIZE: usize = 64*1024;
-impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
+impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
                where K::Target: KeysInterface<Signer = Signer> {
-       fn read<R : io::Read>(reader: &mut R, keys_source: &'a K) -> Result<Self, DecodeError> {
+       fn read<R : io::Read>(reader: &mut R, args: (&'a K, u32)) -> Result<Self, DecodeError> {
+               let (keys_source, serialized_height) = args;
                let ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
 
                let user_id = Readable::read(reader)?;
@@ -5475,16 +5534,29 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
                let mut announcement_sigs = None;
                let mut target_closing_feerate_sats_per_kw = None;
                let mut monitor_pending_finalized_fulfills = Some(Vec::new());
+               // Prior to supporting channel type negotiation, all of our channels were static_remotekey
+               // only, so we default to that if none was written.
+               let mut channel_type = Some(ChannelTypeFeatures::only_static_remote_key());
+               let mut channel_creation_height = Some(serialized_height);
                read_tlv_fields!(reader, {
                        (0, announcement_sigs, option),
                        (1, minimum_depth, option),
+                       (2, channel_type, option),
                        (3, counterparty_selected_channel_reserve_satoshis, option),
                        (5, config, option), // Note that if none is provided we will *not* overwrite the existing one.
                        (7, shutdown_scriptpubkey, option),
                        (9, target_closing_feerate_sats_per_kw, option),
                        (11, monitor_pending_finalized_fulfills, vec_type),
+                       (13, channel_creation_height, option),
                });
 
+               let chan_features = channel_type.as_ref().unwrap();
+               if chan_features.supports_unknown_bits() || chan_features.requires_unknown_bits() {
+                       // If the channel was written by a new version and negotiated with features we don't
+                       // understand yet, refuse to read it.
+                       return Err(DecodeError::UnknownRequiredFeature);
+               }
+
                let mut secp_ctx = Secp256k1::new();
                secp_ctx.seeded_randomize(&keys_source.get_secure_random_bytes());
 
@@ -5540,6 +5612,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
                        funding_tx_confirmed_in,
                        funding_tx_confirmation_height,
                        short_channel_id,
+                       channel_creation_height: channel_creation_height.unwrap(),
 
                        counterparty_dust_limit_satoshis,
                        holder_dust_limit_satoshis,
@@ -5577,6 +5650,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
 
                        #[cfg(any(test, feature = "fuzztarget"))]
                        historical_inbound_htlc_fulfills,
+
+                       channel_type: channel_type.unwrap(),
                })
        }
 }
@@ -5686,7 +5761,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) {
+               match Channel::<EnforcingSigner>::new_outbound(&&fee_estimator, &&keys_provider, node_id, &features, 10000000, 100000, 42, &config, 0) {
                        Err(APIError::IncompatibleShutdownScript { script }) => {
                                assert_eq!(script.into_inner(), non_v0_segwit_shutdown_script.into_inner());
                        },
@@ -5708,7 +5783,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).unwrap();
+               let node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_a_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
 
                // Now change the fee so we can check that the fee in the open_channel message is the
                // same as the old fee.
@@ -5733,13 +5808,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).unwrap();
+               let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).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 node_b_chan = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config).unwrap();
+               let node_b_chan = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config, 0).unwrap();
 
                // Node B --> Node A: accept channel, explicitly setting B's dust limit.
                let mut accept_channel_msg = node_b_chan.get_accept_channel();
@@ -5769,6 +5844,7 @@ mod tests {
                                first_hop_htlc_msat: 548,
                                payment_id: PaymentId([42; 32]),
                                payment_secret: None,
+                               payee: None,
                        }
                });
 
@@ -5802,7 +5878,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).unwrap();
+               let mut chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
 
                let commitment_tx_fee_0_htlcs = chan.commit_tx_fee_msat(0);
                let commitment_tx_fee_1_htlc = chan.commit_tx_fee_msat(1);
@@ -5851,12 +5927,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).unwrap();
+               let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).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).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).unwrap();
 
                // Node B --> Node A: accept channel
                let accept_channel_msg = node_b_chan.get_accept_channel();
@@ -5913,7 +5989,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).unwrap();
+               let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).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());
@@ -5977,7 +6053,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).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).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