Avoid storing a full FinalOnionHopData in OnionPayload::Invoice
[rust-lightning] / lightning / src / ln / channelmanager.rs
index 82dec03bbfbc8783cd0469c7300d819d92daa41b..a28d6347332694af4dab7fc0737dd13a2a38c834 100644 (file)
@@ -18,7 +18,7 @@
 //! imply it needs to fail HTLCs/payments/channels it manages).
 //!
 
-use bitcoin::blockdata::block::{Block, BlockHeader};
+use bitcoin::blockdata::block::BlockHeader;
 use bitcoin::blockdata::transaction::Transaction;
 use bitcoin::blockdata::constants::genesis_block;
 use bitcoin::network::constants::Network;
@@ -40,9 +40,9 @@ use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitor
 use chain::transaction::{OutPoint, TransactionData};
 // Since this struct is returned in `list_channels` methods, expose it here in case users want to
 // construct one themselves.
-use ln::{PaymentHash, PaymentPreimage, PaymentSecret};
+use ln::{inbound_payment, PaymentHash, PaymentPreimage, PaymentSecret};
 use ln::channel::{Channel, ChannelError, ChannelUpdateStatus, UpdateFulfillCommitFetch};
-use ln::features::{InitFeatures, NodeFeatures};
+use ln::features::{ChannelTypeFeatures, InitFeatures, NodeFeatures};
 use routing::router::{PaymentParameters, Route, RouteHop, RoutePath, RouteParameters};
 use ln::msgs;
 use ln::msgs::NetAddress;
@@ -53,7 +53,7 @@ use util::config::UserConfig;
 use util::events::{EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason};
 use util::{byte_utils, events};
 use util::scid_utils::fake_scid;
-use util::ser::{BigSize, FixedLengthReader, Readable, ReadableArgs, MaybeReadable, Writeable, Writer};
+use util::ser::{BigSize, FixedLengthReader, Readable, ReadableArgs, MaybeReadable, Writeable, Writer, VecWriter};
 use util::logger::{Level, Logger};
 use util::errors::APIError;
 
@@ -69,276 +69,7 @@ use core::ops::Deref;
 
 #[cfg(any(test, feature = "std"))]
 use std::time::Instant;
-
-mod inbound_payment {
-       use alloc::string::ToString;
-       use bitcoin::hashes::{Hash, HashEngine};
-       use bitcoin::hashes::cmp::fixed_time_eq;
-       use bitcoin::hashes::hmac::{Hmac, HmacEngine};
-       use bitcoin::hashes::sha256::Hash as Sha256;
-       use chain::keysinterface::{KeyMaterial, KeysInterface, Sign};
-       use ln::{PaymentHash, PaymentPreimage, PaymentSecret};
-       use ln::channelmanager::APIError;
-       use ln::msgs;
-       use ln::msgs::MAX_VALUE_MSAT;
-       use util::chacha20::ChaCha20;
-       use util::crypto::hkdf_extract_expand_thrice;
-       use util::logger::Logger;
-
-       use core::convert::TryInto;
-       use core::ops::Deref;
-
-       const IV_LEN: usize = 16;
-       const METADATA_LEN: usize = 16;
-       const METADATA_KEY_LEN: usize = 32;
-       const AMT_MSAT_LEN: usize = 8;
-       // Used to shift the payment type bits to take up the top 3 bits of the metadata bytes, or to
-       // retrieve said payment type bits.
-       const METHOD_TYPE_OFFSET: usize = 5;
-
-       /// A set of keys that were HKDF-expanded from an initial call to
-       /// [`KeysInterface::get_inbound_payment_key_material`].
-       ///
-       /// [`KeysInterface::get_inbound_payment_key_material`]: crate::chain::keysinterface::KeysInterface::get_inbound_payment_key_material
-       pub(super) struct ExpandedKey {
-               /// The key used to encrypt the bytes containing the payment metadata (i.e. the amount and
-               /// expiry, included for payment verification on decryption).
-               metadata_key: [u8; 32],
-               /// The key used to authenticate an LDK-provided payment hash and metadata as previously
-               /// registered with LDK.
-               ldk_pmt_hash_key: [u8; 32],
-               /// The key used to authenticate a user-provided payment hash and metadata as previously
-               /// registered with LDK.
-               user_pmt_hash_key: [u8; 32],
-       }
-
-       impl ExpandedKey {
-               pub(super) fn new(key_material: &KeyMaterial) -> ExpandedKey {
-                       let (metadata_key, ldk_pmt_hash_key, user_pmt_hash_key) =
-                               hkdf_extract_expand_thrice(b"LDK Inbound Payment Key Expansion", &key_material.0);
-                       Self {
-                               metadata_key,
-                               ldk_pmt_hash_key,
-                               user_pmt_hash_key,
-                       }
-               }
-       }
-
-       enum Method {
-               LdkPaymentHash = 0,
-               UserPaymentHash = 1,
-       }
-
-       impl Method {
-               fn from_bits(bits: u8) -> Result<Method, u8> {
-                       match bits {
-                               bits if bits == Method::LdkPaymentHash as u8 => Ok(Method::LdkPaymentHash),
-                               bits if bits == Method::UserPaymentHash as u8 => Ok(Method::UserPaymentHash),
-                               unknown => Err(unknown),
-                       }
-               }
-       }
-
-       pub(super) fn create<Signer: Sign, K: Deref>(keys: &ExpandedKey, min_value_msat: Option<u64>, invoice_expiry_delta_secs: u32, keys_manager: &K, highest_seen_timestamp: u64) -> Result<(PaymentHash, PaymentSecret), ()>
-               where K::Target: KeysInterface<Signer = Signer>
-       {
-               let metadata_bytes = construct_metadata_bytes(min_value_msat, Method::LdkPaymentHash, invoice_expiry_delta_secs, highest_seen_timestamp)?;
-
-               let mut iv_bytes = [0 as u8; IV_LEN];
-               let rand_bytes = keys_manager.get_secure_random_bytes();
-               iv_bytes.copy_from_slice(&rand_bytes[..IV_LEN]);
-
-               let mut hmac = HmacEngine::<Sha256>::new(&keys.ldk_pmt_hash_key);
-               hmac.input(&iv_bytes);
-               hmac.input(&metadata_bytes);
-               let payment_preimage_bytes = Hmac::from_engine(hmac).into_inner();
-
-               let ldk_pmt_hash = PaymentHash(Sha256::hash(&payment_preimage_bytes).into_inner());
-               let payment_secret = construct_payment_secret(&iv_bytes, &metadata_bytes, &keys.metadata_key);
-               Ok((ldk_pmt_hash, payment_secret))
-       }
-
-       pub(super) fn create_from_hash(keys: &ExpandedKey, min_value_msat: Option<u64>, payment_hash: PaymentHash, invoice_expiry_delta_secs: u32, highest_seen_timestamp: u64) -> Result<PaymentSecret, ()> {
-               let metadata_bytes = construct_metadata_bytes(min_value_msat, Method::UserPaymentHash, invoice_expiry_delta_secs, highest_seen_timestamp)?;
-
-               let mut hmac = HmacEngine::<Sha256>::new(&keys.user_pmt_hash_key);
-               hmac.input(&metadata_bytes);
-               hmac.input(&payment_hash.0);
-               let hmac_bytes = Hmac::from_engine(hmac).into_inner();
-
-               let mut iv_bytes = [0 as u8; IV_LEN];
-               iv_bytes.copy_from_slice(&hmac_bytes[..IV_LEN]);
-
-               Ok(construct_payment_secret(&iv_bytes, &metadata_bytes, &keys.metadata_key))
-       }
-
-       fn construct_metadata_bytes(min_value_msat: Option<u64>, payment_type: Method, invoice_expiry_delta_secs: u32, highest_seen_timestamp: u64) -> Result<[u8; METADATA_LEN], ()> {
-               if min_value_msat.is_some() && min_value_msat.unwrap() > MAX_VALUE_MSAT {
-                       return Err(());
-               }
-
-               let mut min_amt_msat_bytes: [u8; AMT_MSAT_LEN] = match min_value_msat {
-                       Some(amt) => amt.to_be_bytes(),
-                       None => [0; AMT_MSAT_LEN],
-               };
-               min_amt_msat_bytes[0] |= (payment_type as u8) << METHOD_TYPE_OFFSET;
-
-               // We assume that highest_seen_timestamp is pretty close to the current time - it's updated when
-               // we receive a new block with the maximum time we've seen in a header. It should never be more
-               // than two hours in the future.  Thus, we add two hours here as a buffer to ensure we
-               // absolutely never fail a payment too early.
-               // Note that we assume that received blocks have reasonably up-to-date timestamps.
-               let expiry_bytes = (highest_seen_timestamp + invoice_expiry_delta_secs as u64 + 7200).to_be_bytes();
-
-               let mut metadata_bytes: [u8; METADATA_LEN] = [0; METADATA_LEN];
-               metadata_bytes[..AMT_MSAT_LEN].copy_from_slice(&min_amt_msat_bytes);
-               metadata_bytes[AMT_MSAT_LEN..].copy_from_slice(&expiry_bytes);
-
-               Ok(metadata_bytes)
-       }
-
-       fn construct_payment_secret(iv_bytes: &[u8; IV_LEN], metadata_bytes: &[u8; METADATA_LEN], metadata_key: &[u8; METADATA_KEY_LEN]) -> PaymentSecret {
-               let mut payment_secret_bytes: [u8; 32] = [0; 32];
-               let (iv_slice, encrypted_metadata_slice) = payment_secret_bytes.split_at_mut(IV_LEN);
-               iv_slice.copy_from_slice(iv_bytes);
-
-               let chacha_block = ChaCha20::get_single_block(metadata_key, iv_bytes);
-               for i in 0..METADATA_LEN {
-                       encrypted_metadata_slice[i] = chacha_block[i] ^ metadata_bytes[i];
-               }
-               PaymentSecret(payment_secret_bytes)
-       }
-
-       /// Check that an inbound payment's `payment_data` field is sane.
-       ///
-       /// LDK does not store any data for pending inbound payments. Instead, we construct our payment
-       /// secret (and, if supplied by LDK, our payment preimage) to include encrypted metadata about the
-       /// payment.
-       ///
-       /// The metadata is constructed as:
-       ///   payment method (3 bits) || payment amount (8 bytes - 3 bits) || expiry (8 bytes)
-       /// and encrypted using a key derived from [`KeysInterface::get_inbound_payment_key_material`].
-       ///
-       /// Then on payment receipt, we verify in this method that the payment preimage and payment secret
-       /// match what was constructed.
-       ///
-       /// [`create_inbound_payment`] and [`create_inbound_payment_for_hash`] are called by the user to
-       /// construct the payment secret and/or payment hash that this method is verifying. If the former
-       /// method is called, then the payment method bits mentioned above are represented internally as
-       /// [`Method::LdkPaymentHash`]. If the latter, [`Method::UserPaymentHash`].
-       ///
-       /// For the former method, the payment preimage is constructed as an HMAC of payment metadata and
-       /// random bytes. Because the payment secret is also encoded with these random bytes and metadata
-       /// (with the metadata encrypted with a block cipher), we're able to authenticate the preimage on
-       /// payment receipt.
-       ///
-       /// For the latter, the payment secret instead contains an HMAC of the user-provided payment hash
-       /// and payment metadata (encrypted with a block cipher), allowing us to authenticate the payment
-       /// hash and metadata on payment receipt.
-       ///
-       /// See [`ExpandedKey`] docs for more info on the individual keys used.
-       ///
-       /// [`KeysInterface::get_inbound_payment_key_material`]: crate::chain::keysinterface::KeysInterface::get_inbound_payment_key_material
-       /// [`create_inbound_payment`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment
-       /// [`create_inbound_payment_for_hash`]: crate::ln::channelmanager::ChannelManager::create_inbound_payment_for_hash
-       pub(super) fn verify<L: Deref>(payment_hash: PaymentHash, payment_data: msgs::FinalOnionHopData, highest_seen_timestamp: u64, keys: &ExpandedKey, logger: &L) -> Result<Option<PaymentPreimage>, ()>
-               where L::Target: Logger
-       {
-               let (iv_bytes, metadata_bytes) = decrypt_metadata(payment_data.payment_secret, keys);
-
-               let payment_type_res = Method::from_bits((metadata_bytes[0] & 0b1110_0000) >> METHOD_TYPE_OFFSET);
-               let mut amt_msat_bytes = [0; AMT_MSAT_LEN];
-               amt_msat_bytes.copy_from_slice(&metadata_bytes[..AMT_MSAT_LEN]);
-               // Zero out the bits reserved to indicate the payment type.
-               amt_msat_bytes[0] &= 0b00011111;
-               let min_amt_msat: u64 = u64::from_be_bytes(amt_msat_bytes.into());
-               let expiry = u64::from_be_bytes(metadata_bytes[AMT_MSAT_LEN..].try_into().unwrap());
-
-               // Make sure to check to check the HMAC before doing the other checks below, to mitigate timing
-               // attacks.
-               let mut payment_preimage = None;
-               match payment_type_res {
-                       Ok(Method::UserPaymentHash) => {
-                               let mut hmac = HmacEngine::<Sha256>::new(&keys.user_pmt_hash_key);
-                               hmac.input(&metadata_bytes[..]);
-                               hmac.input(&payment_hash.0);
-                               if !fixed_time_eq(&iv_bytes, &Hmac::from_engine(hmac).into_inner().split_at_mut(IV_LEN).0) {
-                                       log_trace!(logger, "Failing HTLC with user-generated payment_hash {}: unexpected payment_secret", log_bytes!(payment_hash.0));
-                                       return Err(())
-                               }
-                       },
-                       Ok(Method::LdkPaymentHash) => {
-                               match derive_ldk_payment_preimage(payment_hash, &iv_bytes, &metadata_bytes, keys) {
-                                       Ok(preimage) => payment_preimage = Some(preimage),
-                                       Err(bad_preimage_bytes) => {
-                                               log_trace!(logger, "Failing HTLC with payment_hash {} due to mismatching preimage {}", log_bytes!(payment_hash.0), log_bytes!(bad_preimage_bytes));
-                                               return Err(())
-                                       }
-                               }
-                       },
-                       Err(unknown_bits) => {
-                               log_trace!(logger, "Failing HTLC with payment hash {} due to unknown payment type {}", log_bytes!(payment_hash.0), unknown_bits);
-                               return Err(());
-                       }
-               }
-
-               if payment_data.total_msat < min_amt_msat {
-                       log_trace!(logger, "Failing HTLC with payment_hash {} due to total_msat {} being less than the minimum amount of {} msat", log_bytes!(payment_hash.0), payment_data.total_msat, min_amt_msat);
-                       return Err(())
-               }
-
-               if expiry < highest_seen_timestamp {
-                       log_trace!(logger, "Failing HTLC with payment_hash {}: expired payment", log_bytes!(payment_hash.0));
-                       return Err(())
-               }
-
-               Ok(payment_preimage)
-       }
-
-       pub(super) fn get_payment_preimage(payment_hash: PaymentHash, payment_secret: PaymentSecret, keys: &ExpandedKey) -> Result<PaymentPreimage, APIError> {
-               let (iv_bytes, metadata_bytes) = decrypt_metadata(payment_secret, keys);
-
-               match Method::from_bits((metadata_bytes[0] & 0b1110_0000) >> METHOD_TYPE_OFFSET) {
-                       Ok(Method::LdkPaymentHash) => {
-                               derive_ldk_payment_preimage(payment_hash, &iv_bytes, &metadata_bytes, keys)
-                                       .map_err(|bad_preimage_bytes| APIError::APIMisuseError {
-                                               err: format!("Payment hash {} did not match decoded preimage {}", log_bytes!(payment_hash.0), log_bytes!(bad_preimage_bytes))
-                                       })
-                       },
-                       Ok(Method::UserPaymentHash) => Err(APIError::APIMisuseError {
-                               err: "Expected payment type to be LdkPaymentHash, instead got UserPaymentHash".to_string()
-                       }),
-                       Err(other) => Err(APIError::APIMisuseError { err: format!("Unknown payment type: {}", other) }),
-               }
-       }
-
-       fn decrypt_metadata(payment_secret: PaymentSecret, keys: &ExpandedKey) -> ([u8; IV_LEN], [u8; METADATA_LEN]) {
-               let mut iv_bytes = [0; IV_LEN];
-               let (iv_slice, encrypted_metadata_bytes) = payment_secret.0.split_at(IV_LEN);
-               iv_bytes.copy_from_slice(iv_slice);
-
-               let chacha_block = ChaCha20::get_single_block(&keys.metadata_key, &iv_bytes);
-               let mut metadata_bytes: [u8; METADATA_LEN] = [0; METADATA_LEN];
-               for i in 0..METADATA_LEN {
-                       metadata_bytes[i] = chacha_block[i] ^ encrypted_metadata_bytes[i];
-               }
-
-               (iv_bytes, metadata_bytes)
-       }
-
-       // Errors if the payment preimage doesn't match `payment_hash`. Returns the bad preimage bytes in
-       // this case.
-       fn derive_ldk_payment_preimage(payment_hash: PaymentHash, iv_bytes: &[u8; IV_LEN], metadata_bytes: &[u8; METADATA_LEN], keys: &ExpandedKey) -> Result<PaymentPreimage, [u8; 32]> {
-               let mut hmac = HmacEngine::<Sha256>::new(&keys.ldk_pmt_hash_key);
-               hmac.input(iv_bytes);
-               hmac.input(metadata_bytes);
-               let decoded_payment_preimage = Hmac::from_engine(hmac).into_inner();
-               if !fixed_time_eq(&payment_hash.0, &Sha256::hash(&decoded_payment_preimage).into_inner()) {
-                       return Err(decoded_payment_preimage);
-               }
-               return Ok(PaymentPreimage(decoded_payment_preimage))
-       }
-}
+use util::crypto::sign;
 
 // We hold various information about HTLC relay in the HTLC objects in Channel itself:
 //
@@ -428,20 +159,26 @@ pub(crate) struct HTLCPreviousHopData {
 }
 
 enum OnionPayload {
-       /// Contains a total_msat (which may differ from value if this is a Multi-Path Payment) and a
-       /// payment_secret which prevents path-probing attacks and can associate different HTLCs which
-       /// are part of the same payment.
-       Invoice(msgs::FinalOnionHopData),
+       /// Indicates this incoming onion payload is for the purpose of paying an invoice.
+       Invoice {
+               /// This is only here for backwards-compatibility in serialization, in the future it can be
+               /// removed, breaking clients running 0.0.106 and earlier.
+               _legacy_hop_data: msgs::FinalOnionHopData,
+       },
        /// Contains the payer-provided preimage.
        Spontaneous(PaymentPreimage),
 }
 
+/// HTLCs that are to us and can be failed/claimed by the user
 struct ClaimableHTLC {
        prev_hop: HTLCPreviousHopData,
        cltv_expiry: u32,
+       /// The amount (in msats) of this MPP part
        value: u64,
        onion_payload: OnionPayload,
        timer_ticks: u8,
+       /// The sum total of all MPP parts
+       total_msat: u64,
 }
 
 /// A payment identifier used to uniquely identify a payment to LDK.
@@ -497,6 +234,7 @@ impl core::hash::Hash for HTLCSource {
                }
        }
 }
+#[cfg(not(feature = "grind_signatures"))]
 #[cfg(test)]
 impl HTLCSource {
        pub fn dummy() -> Self {
@@ -887,6 +625,8 @@ impl PendingOutboundPayment {
 /// issues such as overly long function definitions. Note that the ChannelManager can take any
 /// type that implements KeysInterface for its keys manager, but this type alias chooses the
 /// concrete type of the KeysManager.
+///
+/// (C-not exported) as Arcs don't make sense in bindings
 pub type SimpleArcChannelManager<M, T, F, L> = ChannelManager<InMemorySigner, Arc<M>, Arc<T>, Arc<KeysManager>, Arc<F>, Arc<L>>;
 
 /// SimpleRefChannelManager is a type alias for a ChannelManager reference, and is the reference
@@ -897,6 +637,8 @@ pub type SimpleArcChannelManager<M, T, F, L> = ChannelManager<InMemorySigner, Ar
 /// helps with issues such as long function definitions. Note that the ChannelManager can take any
 /// type that implements KeysInterface for its keys manager, but this type alias chooses the
 /// concrete type of the KeysManager.
+///
+/// (C-not exported) as Arcs don't make sense in bindings
 pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, M, T, F, L> = ChannelManager<InMemorySigner, &'a M, &'b T, &'c KeysManager, &'d F, &'e L>;
 
 /// Manager which keeps track of a number of channels and sends messages to the appropriate
@@ -1186,6 +928,12 @@ pub struct ChannelCounterparty {
        /// Information on the fees and requirements that the counterparty requires when forwarding
        /// payments to us through this channel.
        pub forwarding_info: Option<CounterpartyForwardingInfo>,
+       /// The smallest value HTLC (in msat) the remote peer will accept, for this channel. This field
+       /// is only `None` before we have received either the `OpenChannel` or `AcceptChannel` message
+       /// from the remote peer, or for `ChannelCounterparty` objects serialized prior to LDK 0.0.107.
+       pub outbound_htlc_minimum_msat: Option<u64>,
+       /// The largest value HTLC (in msat) the remote peer currently will accept, for this channel.
+       pub outbound_htlc_maximum_msat: Option<u64>,
 }
 
 /// Details of a channel, as returned by ChannelManager::list_channels and ChannelManager::list_usable_channels
@@ -1204,6 +952,10 @@ pub struct ChannelDetails {
        /// Note that, if this has been set, `channel_id` will be equivalent to
        /// `funding_txo.unwrap().to_channel_id()`.
        pub funding_txo: Option<OutPoint>,
+       /// The features which this channel operates with. See individual features for more info.
+       ///
+       /// `None` until negotiation completes and the channel type is finalized.
+       pub channel_type: Option<ChannelTypeFeatures>,
        /// The position of the funding transaction in the chain. None if the funding transaction has
        /// not yet been confirmed and the channel fully opened.
        ///
@@ -1218,6 +970,9 @@ pub struct ChannelDetails {
        /// counterparty will recognize the alias provided here in place of the [`short_channel_id`]
        /// when they see a payment to be routed to us.
        ///
+       /// Our counterparty may choose to rotate this value at any time, though will always recognize
+       /// previous values for inbound payment forwarding.
+       ///
        /// [`short_channel_id`]: Self::short_channel_id
        pub inbound_scid_alias: Option<u64>,
        /// The value, in satoshis, of this channel as appears in the funding output
@@ -1256,6 +1011,13 @@ pub struct ChannelDetails {
        /// conflict-avoidance policy, exactly this amount is not likely to be spendable. However, we
        /// should be able to spend nearly this amount.
        pub outbound_capacity_msat: u64,
+       /// The available outbound capacity for sending a single HTLC to the remote peer. This is
+       /// similar to [`ChannelDetails::outbound_capacity_msat`] but it may be further restricted by
+       /// the current state and per-HTLC limit(s). This is intended for use when routing, allowing us
+       /// to use a limit as close as possible to the HTLC limit we can currently send.
+       ///
+       /// See also [`ChannelDetails::balance_msat`] and [`ChannelDetails::outbound_capacity_msat`].
+       pub next_outbound_htlc_limit_msat: u64,
        /// The available inbound capacity for the remote peer to send HTLCs to us. This does not
        /// include any pending HTLCs which are not yet fully resolved (and, thus, whose balance is not
        /// available for inclusion in new inbound HTLCs).
@@ -1303,12 +1065,20 @@ pub struct ChannelDetails {
        pub is_usable: bool,
        /// True if this channel is (or will be) publicly-announced.
        pub is_public: bool,
+       /// The smallest value HTLC (in msat) we will accept, for this channel. This field
+       /// is only `None` for `ChannelDetails` objects serialized prior to LDK 0.0.107
+       pub inbound_htlc_minimum_msat: Option<u64>,
+       /// The largest value HTLC (in msat) we currently will accept, for this channel.
+       pub inbound_htlc_maximum_msat: Option<u64>,
 }
 
 impl ChannelDetails {
-       /// Gets the SCID which should be used to identify this channel for inbound payments. This
-       /// should be used for providing invoice hints or in any other context where our counterparty
-       /// will forward a payment to us.
+       /// Gets the current SCID which should be used to identify this channel for inbound payments.
+       /// This should be used for providing invoice hints or in any other context where our
+       /// counterparty will forward a payment to us.
+       ///
+       /// This is either the [`ChannelDetails::inbound_scid_alias`], if set, or the
+       /// [`ChannelDetails::short_channel_id`]. See those for more information.
        pub fn get_inbound_payment_scid(&self) -> Option<u64> {
                self.inbound_scid_alias.or(self.short_channel_id)
        }
@@ -1752,8 +1522,6 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
        ///
        /// Non-proportional fees are fixed according to our risk using the provided fee estimator.
        ///
-       /// panics if channel_value_satoshis is >= `MAX_FUNDING_SATOSHIS`!
-       ///
        /// Users need to notify the new ChannelManager when a new block is connected or
        /// disconnected using its `block_connected` and `block_disconnected` methods, starting
        /// from after `params.latest_hash`.
@@ -1913,8 +1681,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                        let channel_state = self.channel_state.lock().unwrap();
                        res.reserve(channel_state.by_id.len());
                        for (channel_id, channel) in channel_state.by_id.iter().filter(f) {
-                               let (inbound_capacity_msat, outbound_capacity_msat) = channel.get_inbound_outbound_available_balance_msat();
-                               let balance_msat = channel.get_balance_msat();
+                               let balance = channel.get_available_balances();
                                let (to_remote_reserve_satoshis, to_self_reserve_satoshis) =
                                        channel.get_holder_counterparty_selected_channel_reserve_satoshis();
                                res.push(ChannelDetails {
@@ -1924,15 +1691,27 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                features: InitFeatures::empty(),
                                                unspendable_punishment_reserve: to_remote_reserve_satoshis,
                                                forwarding_info: channel.counterparty_forwarding_info(),
+                                               // Ensures that we have actually received the `htlc_minimum_msat` value
+                                               // from the counterparty through the `OpenChannel` or `AcceptChannel`
+                                               // message (as they are always the first message from the counterparty).
+                                               // Else `Channel::get_counterparty_htlc_minimum_msat` could return the
+                                               // default `0` value set by `Channel::new_outbound`.
+                                               outbound_htlc_minimum_msat: if channel.have_received_message() {
+                                                       Some(channel.get_counterparty_htlc_minimum_msat()) } else { None },
+                                               outbound_htlc_maximum_msat: channel.get_counterparty_htlc_maximum_msat(),
                                        },
                                        funding_txo: channel.get_funding_txo(),
+                                       // Note that accept_channel (or open_channel) is always the first message, so
+                                       // `have_received_message` indicates that type negotiation has completed.
+                                       channel_type: if channel.have_received_message() { Some(channel.get_channel_type().clone()) } else { None },
                                        short_channel_id: channel.get_short_channel_id(),
                                        inbound_scid_alias: channel.latest_inbound_scid_alias(),
                                        channel_value_satoshis: channel.get_value_satoshis(),
                                        unspendable_punishment_reserve: to_self_reserve_satoshis,
-                                       balance_msat,
-                                       inbound_capacity_msat,
-                                       outbound_capacity_msat,
+                                       balance_msat: balance.balance_msat,
+                                       inbound_capacity_msat: balance.inbound_capacity_msat,
+                                       outbound_capacity_msat: balance.outbound_capacity_msat,
+                                       next_outbound_htlc_limit_msat: balance.next_outbound_htlc_limit_msat,
                                        user_channel_id: channel.get_user_id(),
                                        confirmations_required: channel.minimum_depth(),
                                        force_close_spend_delay: channel.get_counterparty_selected_contest_delay(),
@@ -1940,6 +1719,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        is_funding_locked: channel.is_usable(),
                                        is_usable: channel.is_live(),
                                        is_public: channel.should_announce(),
+                                       inbound_htlc_minimum_msat: Some(channel.get_holder_htlc_minimum_msat()),
+                                       inbound_htlc_maximum_msat: channel.get_holder_htlc_maximum_msat()
                                });
                        }
                }
@@ -2410,15 +2191,19 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        };
                                        let (chan_update_opt, forwardee_cltv_expiry_delta) = if let Some(forwarding_id) = forwarding_id_opt {
                                                let chan = channel_state.as_mut().unwrap().by_id.get_mut(&forwarding_id).unwrap();
-                                               // Leave channel updates as None for private channels.
-                                               let chan_update_opt = if chan.should_announce() {
-                                                       Some(self.get_channel_update_for_unicast(chan).unwrap()) } else { None };
                                                if !chan.should_announce() && !self.default_configuration.accept_forwards_to_priv_channels {
                                                        // Note that the behavior here should be identical to the above block - we
                                                        // should NOT reveal the existence or non-existence of a private channel if
                                                        // we don't allow forwards outbound over them.
-                                                       break Some(("Don't have available channel for forwarding as requested.", 0x4000 | 10, None));
+                                                       break Some(("Refusing to forward to a private channel based on our config.", 0x4000 | 10, None));
                                                }
+                                               if chan.get_channel_type().supports_scid_privacy() && *short_channel_id != chan.outbound_scid_alias() {
+                                                       // `option_scid_alias` (referred to in LDK as `scid_privacy`) means
+                                                       // "refuse to forward unless the SCID alias was used", so we pretend
+                                                       // we don't have the channel here.
+                                                       break Some(("Refusing to forward over real channel SCID as our counterparty requested.", 0x4000 | 10, None));
+                                               }
+                                               let chan_update_opt = self.get_channel_update_for_onion(*short_channel_id, chan).ok();
 
                                                // Note that we could technically not return an error yet here and just hope
                                                // that the connection is reestablished or monitor updated by the time we get
@@ -2468,21 +2253,22 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        break None;
                                }
                                {
-                                       let mut res = Vec::with_capacity(8 + 128);
+                                       let mut res = VecWriter(Vec::with_capacity(chan_update.serialized_length() + 8 + 2));
                                        if let Some(chan_update) = chan_update {
                                                if code == 0x1000 | 11 || code == 0x1000 | 12 {
-                                                       res.extend_from_slice(&byte_utils::be64_to_array(msg.amount_msat));
+                                                       msg.amount_msat.write(&mut res).expect("Writes cannot fail");
                                                }
                                                else if code == 0x1000 | 13 {
-                                                       res.extend_from_slice(&byte_utils::be32_to_array(msg.cltv_expiry));
+                                                       msg.cltv_expiry.write(&mut res).expect("Writes cannot fail");
                                                }
                                                else if code == 0x1000 | 20 {
                                                        // TODO: underspecified, follow https://github.com/lightningnetwork/lightning-rfc/issues/791
-                                                       res.extend_from_slice(&byte_utils::be16_to_array(0));
+                                                       0u16.write(&mut res).expect("Writes cannot fail");
                                                }
-                                               res.extend_from_slice(&chan_update.encode_with_len()[..]);
+                                               (chan_update.serialized_length() as u16).write(&mut res).expect("Writes cannot fail");
+                                               chan_update.write(&mut res).expect("Writes cannot fail");
                                        }
-                                       return_err!(err, code, &res[..]);
+                                       return_err!(err, code, &res.0[..]);
                                }
                        }
                }
@@ -2518,6 +2304,10 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                        Some(id) => id,
                };
 
+               self.get_channel_update_for_onion(short_channel_id, chan)
+       }
+       fn get_channel_update_for_onion(&self, short_channel_id: u64, chan: &Channel<Signer>) -> Result<msgs::ChannelUpdate, LightningError> {
+               log_trace!(self.logger, "Generating channel update for channel {}", log_bytes!(chan.channel_id()));
                let were_node_one = PublicKey::from_secret_key(&self.secp_ctx, &self.our_network_key).serialize()[..] < chan.get_counterparty_node_id().serialize()[..];
 
                let unsigned = msgs::UnsignedChannelUpdate {
@@ -3056,7 +2846,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                        excess_data: Vec::new(),
                };
                let msghash = hash_to_message!(&Sha256dHash::hash(&announcement.encode()[..])[..]);
-               let node_announce_sig = self.secp_ctx.sign(&msghash, &self.our_network_key);
+               let node_announce_sig = sign(&self.secp_ctx, &msghash, &self.our_network_key);
 
                let mut channel_state_lock = self.channel_state.lock().unwrap();
                let channel_state = &mut *channel_state_lock;
@@ -3207,9 +2997,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                                        } else {
                                                                                                panic!("Stated return value requirements in send_htlc() were not met");
                                                                                        }
-                                                                                       let chan_update = self.get_channel_update_for_unicast(chan.get()).unwrap();
+                                                                                       let (failure_code, data) = self.get_htlc_temp_fail_err_and_data(0x1000|7, short_chan_id, chan.get());
                                                                                        failed_forwards.push((htlc_source, payment_hash,
-                                                                                               HTLCFailReason::Reason { failure_code: 0x1000 | 7, data: chan_update.encode_with_len() }
+                                                                                               HTLCFailReason::Reason { failure_code, data }
                                                                                        ));
                                                                                        continue;
                                                                                },
@@ -3312,11 +3102,13 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                        HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
                                                                        routing, incoming_shared_secret, payment_hash, amt_to_forward, .. },
                                                                        prev_funding_outpoint } => {
-                                                               let (cltv_expiry, onion_payload, phantom_shared_secret) = match routing {
-                                                                       PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry, phantom_shared_secret } =>
-                                                                               (incoming_cltv_expiry, OnionPayload::Invoice(payment_data), phantom_shared_secret),
+                                                               let (cltv_expiry, onion_payload, payment_data, phantom_shared_secret) = match routing {
+                                                                       PendingHTLCRouting::Receive { payment_data, incoming_cltv_expiry, phantom_shared_secret } => {
+                                                                               let _legacy_hop_data = payment_data.clone();
+                                                                               (incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data }, Some(payment_data), phantom_shared_secret)
+                                                                       },
                                                                        PendingHTLCRouting::ReceiveKeysend { payment_preimage, incoming_cltv_expiry } =>
-                                                                               (incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage), None),
+                                                                               (incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage), None, None),
                                                                        _ => {
                                                                                panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive");
                                                                        }
@@ -3331,6 +3123,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                        },
                                                                        value: amt_to_forward,
                                                                        timer_ticks: 0,
+                                                                       total_msat: if let Some(data) = &payment_data { data.total_msat } else { amt_to_forward },
                                                                        cltv_expiry,
                                                                        onion_payload,
                                                                };
@@ -3354,7 +3147,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                }
 
                                                                macro_rules! check_total_value {
-                                                                       ($payment_data_total_msat: expr, $payment_secret: expr, $payment_preimage: expr) => {{
+                                                                       ($payment_data: expr, $payment_preimage: expr) => {{
                                                                                let mut payment_received_generated = false;
                                                                                let htlcs = channel_state.claimable_htlcs.entry(payment_hash)
                                                                                        .or_insert(Vec::new());
@@ -3369,10 +3162,10 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                                for htlc in htlcs.iter() {
                                                                                        total_value += htlc.value;
                                                                                        match &htlc.onion_payload {
-                                                                                               OnionPayload::Invoice(htlc_payment_data) => {
-                                                                                                       if htlc_payment_data.total_msat != $payment_data_total_msat {
+                                                                                               OnionPayload::Invoice { .. } => {
+                                                                                                       if htlc.total_msat != $payment_data.total_msat {
                                                                                                                log_trace!(self.logger, "Failing HTLCs with payment_hash {} as the HTLCs had inconsistent total values (eg {} and {})",
-                                                                                                                       log_bytes!(payment_hash.0), $payment_data_total_msat, htlc_payment_data.total_msat);
+                                                                                                                       log_bytes!(payment_hash.0), $payment_data.total_msat, htlc.total_msat);
                                                                                                                total_value = msgs::MAX_VALUE_MSAT;
                                                                                                        }
                                                                                                        if total_value >= msgs::MAX_VALUE_MSAT { break; }
@@ -3380,17 +3173,17 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                                                _ => unreachable!(),
                                                                                        }
                                                                                }
-                                                                               if total_value >= msgs::MAX_VALUE_MSAT || total_value > $payment_data_total_msat {
+                                                                               if total_value >= msgs::MAX_VALUE_MSAT || total_value > $payment_data.total_msat {
                                                                                        log_trace!(self.logger, "Failing HTLCs with payment_hash {} as the total value {} ran over expected value {} (or HTLCs were inconsistent)",
-                                                                                               log_bytes!(payment_hash.0), total_value, $payment_data_total_msat);
+                                                                                               log_bytes!(payment_hash.0), total_value, $payment_data.total_msat);
                                                                                        fail_htlc!(claimable_htlc);
-                                                                               } else if total_value == $payment_data_total_msat {
+                                                                               } else if total_value == $payment_data.total_msat {
                                                                                        htlcs.push(claimable_htlc);
                                                                                        new_events.push(events::Event::PaymentReceived {
                                                                                                payment_hash,
                                                                                                purpose: events::PaymentPurpose::InvoicePayment {
                                                                                                        payment_preimage: $payment_preimage,
-                                                                                                       payment_secret: $payment_secret,
+                                                                                                       payment_secret: $payment_data.payment_secret,
                                                                                                },
                                                                                                amt: total_value,
                                                                                        });
@@ -3415,17 +3208,16 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                match payment_secrets.entry(payment_hash) {
                                                                        hash_map::Entry::Vacant(_) => {
                                                                                match claimable_htlc.onion_payload {
-                                                                                       OnionPayload::Invoice(ref payment_data) => {
-                                                                                               let payment_preimage = match inbound_payment::verify(payment_hash, payment_data.clone(), self.highest_seen_timestamp.load(Ordering::Acquire) as u64, &self.inbound_payment_key, &self.logger) {
+                                                                                       OnionPayload::Invoice { .. } => {
+                                                                                               let payment_data = payment_data.unwrap();
+                                                                                               let payment_preimage = match inbound_payment::verify(payment_hash, &payment_data, self.highest_seen_timestamp.load(Ordering::Acquire) as u64, &self.inbound_payment_key, &self.logger) {
                                                                                                        Ok(payment_preimage) => payment_preimage,
                                                                                                        Err(()) => {
                                                                                                                fail_htlc!(claimable_htlc);
                                                                                                                continue
                                                                                                        }
                                                                                                };
-                                                                                               let payment_data_total_msat = payment_data.total_msat;
-                                                                                               let payment_secret = payment_data.payment_secret.clone();
-                                                                                               check_total_value!(payment_data_total_msat, payment_secret, payment_preimage);
+                                                                                               check_total_value!(payment_data, payment_preimage);
                                                                                        },
                                                                                        OnionPayload::Spontaneous(preimage) => {
                                                                                                match channel_state.claimable_htlcs.entry(payment_hash) {
@@ -3446,14 +3238,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                                }
                                                                        },
                                                                        hash_map::Entry::Occupied(inbound_payment) => {
-                                                                               let payment_data =
-                                                                                       if let OnionPayload::Invoice(ref data) = claimable_htlc.onion_payload {
-                                                                                               data.clone()
-                                                                                       } else {
-                                                                                               log_trace!(self.logger, "Failing new keysend HTLC with payment_hash {} because we already have an inbound payment with the same payment hash", log_bytes!(payment_hash.0));
-                                                                                               fail_htlc!(claimable_htlc);
-                                                                                               continue
-                                                                                       };
+                                                                               if payment_data.is_none() {
+                                                                                       log_trace!(self.logger, "Failing new keysend HTLC with payment_hash {} because we already have an inbound payment with the same payment hash", log_bytes!(payment_hash.0));
+                                                                                       fail_htlc!(claimable_htlc);
+                                                                                       continue
+                                                                               };
+                                                                               let payment_data = payment_data.unwrap();
                                                                                if inbound_payment.get().payment_secret != payment_data.payment_secret {
                                                                                        log_trace!(self.logger, "Failing new HTLC with payment_hash {} as it didn't match our expected payment secret.", log_bytes!(payment_hash.0));
                                                                                        fail_htlc!(claimable_htlc);
@@ -3462,7 +3252,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                                                log_bytes!(payment_hash.0), payment_data.total_msat, inbound_payment.get().min_value_msat.unwrap());
                                                                                        fail_htlc!(claimable_htlc);
                                                                                } else {
-                                                                                       let payment_received_generated = check_total_value!(payment_data.total_msat, payment_data.payment_secret, inbound_payment.get().payment_preimage);
+                                                                                       let payment_received_generated = check_total_value!(payment_data, inbound_payment.get().payment_preimage);
                                                                                        if payment_received_generated {
                                                                                                inbound_payment.remove_entry();
                                                                                        }
@@ -3681,10 +3471,10 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                debug_assert!(false);
                                                return false;
                                        }
-                                       if let OnionPayload::Invoice(ref final_hop_data) = htlcs[0].onion_payload {
+                                       if let OnionPayload::Invoice { .. } = htlcs[0].onion_payload {
                                                // Check if we've received all the parts we need for an MPP (the value of the parts adds to total_msat).
                                                // In this case we're not going to handle any timeouts of the parts here.
-                                               if final_hop_data.total_msat == htlcs.iter().fold(0, |total, htlc| total + htlc.value) {
+                                               if htlcs[0].total_msat == htlcs.iter().fold(0, |total, htlc| total + htlc.value) {
                                                        return true;
                                                } else if htlcs.into_iter().any(|htlc| {
                                                        htlc.timer_ticks += 1;
@@ -3733,6 +3523,51 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                } else { false }
        }
 
+       /// Gets an HTLC onion failure code and error data for an `UPDATE` error, given the error code
+       /// that we want to return and a channel.
+       ///
+       /// This is for failures on the channel on which the HTLC was *received*, not failures
+       /// forwarding
+       fn get_htlc_inbound_temp_fail_err_and_data(&self, desired_err_code: u16, chan: &Channel<Signer>) -> (u16, Vec<u8>) {
+               // We can't be sure what SCID was used when relaying inbound towards us, so we have to
+               // guess somewhat. If its a public channel, we figure best to just use the real SCID (as
+               // we're not leaking that we have a channel with the counterparty), otherwise we try to use
+               // an inbound SCID alias before the real SCID.
+               let scid_pref = if chan.should_announce() {
+                       chan.get_short_channel_id().or(chan.latest_inbound_scid_alias())
+               } else {
+                       chan.latest_inbound_scid_alias().or(chan.get_short_channel_id())
+               };
+               if let Some(scid) = scid_pref {
+                       self.get_htlc_temp_fail_err_and_data(desired_err_code, scid, chan)
+               } else {
+                       (0x4000|10, Vec::new())
+               }
+       }
+
+
+       /// Gets an HTLC onion failure code and error data for an `UPDATE` error, given the error code
+       /// that we want to return and a channel.
+       fn get_htlc_temp_fail_err_and_data(&self, desired_err_code: u16, scid: u64, chan: &Channel<Signer>) -> (u16, Vec<u8>) {
+               debug_assert_eq!(desired_err_code & 0x1000, 0x1000);
+               if let Ok(upd) = self.get_channel_update_for_onion(scid, chan) {
+                       let mut enc = VecWriter(Vec::with_capacity(upd.serialized_length() + 4));
+                       if desired_err_code == 0x1000 | 20 {
+                               // TODO: underspecified, follow https://github.com/lightning/bolts/issues/791
+                               0u16.write(&mut enc).expect("Writes cannot fail");
+                       }
+                       (upd.serialized_length() as u16).write(&mut enc).expect("Writes cannot fail");
+                       upd.write(&mut enc).expect("Writes cannot fail");
+                       (desired_err_code, enc.0)
+               } else {
+                       // If we fail to get a unicast channel_update, it implies we don't yet have an SCID,
+                       // which means we really shouldn't have gotten a payment to be forwarded over this
+                       // channel yet, or if we did it's from a route hint. Either way, returning an error of
+                       // PERM|no_such_channel should be fine.
+                       (0x4000|10, Vec::new())
+               }
+       }
+
        // Fail a list of HTLCs that were just freed from the holding cell. The HTLCs need to be
        // failed backwards or, if they were one of our outgoing HTLCs, then their failure needs to
        // be surfaced to the user.
@@ -3743,11 +3578,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        let (failure_code, onion_failure_data) =
                                                match self.channel_state.lock().unwrap().by_id.entry(channel_id) {
                                                        hash_map::Entry::Occupied(chan_entry) => {
-                                                               if let Ok(upd) = self.get_channel_update_for_unicast(&chan_entry.get()) {
-                                                                       (0x1000|7, upd.encode_with_len())
-                                                               } else {
-                                                                       (0x4000|10, Vec::new())
-                                                               }
+                                                               self.get_htlc_inbound_temp_fail_err_and_data(0x1000|7, &chan_entry.get())
                                                        },
                                                        hash_map::Entry::Vacant(_) => (0x4000|10, Vec::new())
                                                };
@@ -4223,7 +4054,10 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                } else { None };
 
                                                let mut pending_events = self.pending_events.lock().unwrap();
+
+                                               let source_channel_id = Some(prev_outpoint.to_channel_id());
                                                pending_events.push(events::Event::PaymentForwarded {
+                                                       source_channel_id,
                                                        fee_earned_msat,
                                                        claim_from_onchain_tx: from_onchain,
                                                });
@@ -4260,10 +4094,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                // channel_update later through the announcement_signatures process for public
                                // channels, but there's no reason not to just inform our counterparty of our fees
                                // now.
-                               Some(events::MessageSendEvent::SendChannelUpdate {
-                                       node_id: channel.get().get_counterparty_node_id(),
-                                       msg: self.get_channel_update_for_unicast(channel.get()).unwrap(),
-                               })
+                               if let Ok(msg) = self.get_channel_update_for_unicast(channel.get()) {
+                                       Some(events::MessageSendEvent::SendChannelUpdate {
+                                               node_id: channel.get().get_counterparty_node_id(),
+                                               msg,
+                                       })
+                               } else { None }
                        } else { None };
                        chan_restoration_res = handle_chan_restoration_locked!(self, channel_lock, channel_state, channel, updates.raa, updates.commitment_update, updates.order, None, updates.accepted_htlcs, updates.funding_broadcastable, updates.funding_locked, updates.announcement_sigs);
                        if let Some(upd) = channel_update {
@@ -4283,8 +4119,13 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
        ///
        /// The `temporary_channel_id` parameter indicates which inbound channel should be accepted.
        ///
-       /// [`Event::OpenChannelRequest`]: crate::util::events::Event::OpenChannelRequest
-       pub fn accept_inbound_channel(&self, temporary_channel_id: &[u8; 32]) -> Result<(), APIError> {
+       /// For inbound channels, the `user_channel_id` parameter will be provided back in
+       /// [`Event::ChannelClosed::user_channel_id`] to allow tracking of which events correspond
+       /// with which `accept_inbound_channel` call.
+       ///
+       /// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
+       /// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
+       pub fn accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], user_channel_id: u64) -> Result<(), APIError> {
                let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
 
                let mut channel_state_lock = self.channel_state.lock().unwrap();
@@ -4296,7 +4137,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                }
                                channel_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
                                        node_id: channel.get().get_counterparty_node_id(),
-                                       msg: channel.get_mut().accept_inbound_channel(),
+                                       msg: channel.get_mut().accept_inbound_channel(user_channel_id),
                                });
                        }
                        hash_map::Entry::Vacant(_) => {
@@ -4337,7 +4178,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                if !self.default_configuration.manually_accept_inbound_channels {
                                        channel_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
                                                node_id: counterparty_node_id.clone(),
-                                               msg: channel.accept_inbound_channel(),
+                                               msg: channel.accept_inbound_channel(0),
                                        });
                                } else {
                                        let mut pending_events = self.pending_events.lock().unwrap();
@@ -4347,6 +4188,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                        counterparty_node_id: counterparty_node_id.clone(),
                                                        funding_satoshis: msg.funding_satoshis,
                                                        push_msat: msg.push_msat,
+                                                       channel_type: channel.get_channel_type().clone(),
                                                }
                                        );
                                }
@@ -4498,10 +4340,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        // channel_update here if the channel is not public, i.e. we're not sending an
                                        // announcement_signatures.
                                        log_trace!(self.logger, "Sending private initial channel_update for our counterparty on channel {}", log_bytes!(chan.get().channel_id()));
-                                       channel_state.pending_msg_events.push(events::MessageSendEvent::SendChannelUpdate {
-                                               node_id: counterparty_node_id.clone(),
-                                               msg: self.get_channel_update_for_unicast(chan.get()).unwrap(),
-                                       });
+                                       if let Ok(msg) = self.get_channel_update_for_unicast(chan.get()) {
+                                               channel_state.pending_msg_events.push(events::MessageSendEvent::SendChannelUpdate {
+                                                       node_id: counterparty_node_id.clone(),
+                                                       msg,
+                                               });
+                                       }
                                }
                                Ok(())
                        },
@@ -4632,28 +4476,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                        match pending_forward_info {
                                                PendingHTLCStatus::Forward(PendingHTLCInfo { ref incoming_shared_secret, .. }) => {
                                                        let reason = if (error_code & 0x1000) != 0 {
-                                                               if let Ok(upd) = self.get_channel_update_for_unicast(chan) {
-                                                                       onion_utils::build_first_hop_failure_packet(incoming_shared_secret, error_code, &{
-                                                                               let mut res = Vec::with_capacity(8 + 128);
-                                                                               // TODO: underspecified, follow https://github.com/lightningnetwork/lightning-rfc/issues/791
-                                                                               if error_code == 0x1000 | 20 {
-                                                                                       res.extend_from_slice(&byte_utils::be16_to_array(0));
-                                                                               }
-                                                                               res.extend_from_slice(&upd.encode_with_len()[..]);
-                                                                               res
-                                                                       }[..])
-                                                               } else {
-                                                                       // The only case where we'd be unable to
-                                                                       // successfully get a channel update is if the
-                                                                       // channel isn't in the fully-funded state yet,
-                                                                       // implying our counterparty is trying to route
-                                                                       // payments over the channel back to themselves
-                                                                       // (because no one else should know the short_id
-                                                                       // is a lightning channel yet). We should have
-                                                                       // no problem just calling this
-                                                                       // unknown_next_peer (0x4000|10).
-                                                                       onion_utils::build_first_hop_failure_packet(incoming_shared_secret, 0x4000|10, &[])
-                                                               }
+                                                               let (real_code, error_data) = self.get_htlc_inbound_temp_fail_err_and_data(error_code, chan);
+                                                               onion_utils::build_first_hop_failure_packet(incoming_shared_secret, real_code, &error_data)
                                                        } else {
                                                                onion_utils::build_first_hop_failure_packet(incoming_shared_secret, error_code, &[])
                                                        };
@@ -4975,10 +4799,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                // If the channel is in a usable state (ie the channel is not being shut
                                                // down), send a unicast channel_update to our counterparty to make sure
                                                // they have the latest channel parameters.
-                                               channel_update = Some(events::MessageSendEvent::SendChannelUpdate {
-                                                       node_id: chan.get().get_counterparty_node_id(),
-                                                       msg: self.get_channel_update_for_unicast(chan.get()).unwrap(),
-                                               });
+                                               if let Ok(msg) = self.get_channel_update_for_unicast(chan.get()) {
+                                                       channel_update = Some(events::MessageSendEvent::SendChannelUpdate {
+                                                               node_id: chan.get().get_counterparty_node_id(),
+                                                               msg,
+                                                       });
+                                               }
                                        }
                                        let need_lnd_workaround = chan.get_mut().workaround_lnd_bug_4006.take();
                                        chan_restoration_res = handle_chan_restoration_locked!(
@@ -5488,18 +5314,17 @@ where
        F::Target: FeeEstimator,
        L::Target: Logger,
 {
-       fn block_connected(&self, block: &Block, height: u32) {
+       fn filtered_block_connected(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) {
                {
                        let best_block = self.best_block.read().unwrap();
-                       assert_eq!(best_block.block_hash(), block.header.prev_blockhash,
+                       assert_eq!(best_block.block_hash(), header.prev_blockhash,
                                "Blocks must be connected in chain-order - the connected header must build on the last connected header");
                        assert_eq!(best_block.height(), height - 1,
                                "Blocks must be connected in chain-order - the connected block height must be one greater than the previous height");
                }
 
-               let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
-               self.transactions_confirmed(&block.header, &txdata, height);
-               self.best_block_updated(&block.header, height);
+               self.transactions_confirmed(header, txdata, height);
+               self.best_block_updated(header, height);
        }
 
        fn block_disconnected(&self, header: &BlockHeader, height: u32) {
@@ -5649,20 +5474,21 @@ where
                                let res = f(channel);
                                if let Ok((funding_locked_opt, mut timed_out_pending_htlcs, announcement_sigs)) = res {
                                        for (source, payment_hash) in timed_out_pending_htlcs.drain(..) {
-                                               let chan_update = self.get_channel_update_for_unicast(&channel).map(|u| u.encode_with_len()).unwrap(); // Cannot add/recv HTLCs before we have a short_id so unwrap is safe
-                                               timed_out_htlcs.push((source, payment_hash,  HTLCFailReason::Reason {
-                                                       failure_code: 0x1000 | 14, // expiry_too_soon, or at least it is now
-                                                       data: chan_update,
+                                               let (failure_code, data) = self.get_htlc_inbound_temp_fail_err_and_data(0x1000|14 /* expiry_too_soon */, &channel);
+                                               timed_out_htlcs.push((source, payment_hash, HTLCFailReason::Reason {
+                                                       failure_code, data,
                                                }));
                                        }
                                        if let Some(funding_locked) = funding_locked_opt {
                                                send_funding_locked!(short_to_id, pending_msg_events, channel, funding_locked);
                                                if channel.is_usable() {
                                                        log_trace!(self.logger, "Sending funding_locked with private initial channel_update for our counterparty on channel {}", log_bytes!(channel.channel_id()));
-                                                       pending_msg_events.push(events::MessageSendEvent::SendChannelUpdate {
-                                                               node_id: channel.get_counterparty_node_id(),
-                                                               msg: self.get_channel_update_for_unicast(channel).unwrap(),
-                                                       });
+                                                       if let Ok(msg) = self.get_channel_update_for_unicast(channel) {
+                                                               pending_msg_events.push(events::MessageSendEvent::SendChannelUpdate {
+                                                                       node_id: channel.get_counterparty_node_id(),
+                                                                       msg,
+                                                               });
+                                                       }
                                                } else {
                                                        log_trace!(self.logger, "Sending funding_locked WITHOUT channel_update for {}", log_bytes!(channel.channel_id()));
                                                }
@@ -5931,6 +5757,7 @@ impl<Signer: Sign, M: Deref , T: Deref , K: Deref , F: Deref , L: Deref >
                                        &events::MessageSendEvent::SendChannelRangeQuery { .. } => false,
                                        &events::MessageSendEvent::SendShortIdsQuery { .. } => false,
                                        &events::MessageSendEvent::SendReplyChannelRange { .. } => false,
+                                       &events::MessageSendEvent::SendGossipTimestampFilter { .. } => false,
                                }
                        });
                }
@@ -5996,6 +5823,23 @@ impl<Signer: Sign, M: Deref , T: Deref , K: Deref , F: Deref , L: Deref >
                                }
                        }
                } else {
+                       {
+                               // First check if we can advance the channel type and try again.
+                               let mut channel_state = self.channel_state.lock().unwrap();
+                               if let Some(chan) = channel_state.by_id.get_mut(&msg.channel_id) {
+                                       if chan.get_counterparty_node_id() != *counterparty_node_id {
+                                               return;
+                                       }
+                                       if let Ok(msg) = chan.maybe_handle_error_without_close(self.genesis_hash) {
+                                               channel_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
+                                                       node_id: *counterparty_node_id,
+                                                       msg,
+                                               });
+                                               return;
+                                       }
+                               }
+                       }
+
                        // Untrusted messages from peer, we throw away the error if id points to a non-existent channel
                        let _ = self.force_close_channel_with_peer(&msg.channel_id, Some(counterparty_node_id), Some(&msg.data));
                }
@@ -6087,11 +5931,14 @@ impl_writeable_tlv_based!(ChannelCounterparty, {
        (4, features, required),
        (6, unspendable_punishment_reserve, required),
        (8, forwarding_info, option),
+       (9, outbound_htlc_minimum_msat, option),
+       (11, outbound_htlc_maximum_msat, option),
 });
 
 impl_writeable_tlv_based!(ChannelDetails, {
        (1, inbound_scid_alias, option),
        (2, channel_id, required),
+       (3, channel_type, option),
        (4, counterparty, required),
        (6, funding_txo, option),
        (8, short_channel_id, option),
@@ -6100,6 +5947,9 @@ impl_writeable_tlv_based!(ChannelDetails, {
        (14, user_channel_id, required),
        (16, balance_msat, required),
        (18, outbound_capacity_msat, required),
+       // Note that by the time we get past the required read above, outbound_capacity_msat will be
+       // filled in, so we can safely unwrap it here.
+       (19, next_outbound_htlc_limit_msat, (default_value, outbound_capacity_msat.0.unwrap())),
        (20, inbound_capacity_msat, required),
        (22, confirmations_required, option),
        (24, force_close_spend_delay, option),
@@ -6107,6 +5957,8 @@ impl_writeable_tlv_based!(ChannelDetails, {
        (28, is_funding_locked, required),
        (30, is_usable, required),
        (32, is_public, required),
+       (33, inbound_htlc_minimum_msat, option),
+       (35, inbound_htlc_maximum_msat, option),
 });
 
 impl_writeable_tlv_based!(PhantomRouteHints, {
@@ -6223,20 +6075,21 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, {
 impl Writeable for ClaimableHTLC {
        fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
                let payment_data = match &self.onion_payload {
-                       OnionPayload::Invoice(data) => Some(data.clone()),
+                       OnionPayload::Invoice { _legacy_hop_data } => Some(_legacy_hop_data),
                        _ => None,
                };
                let keysend_preimage = match self.onion_payload {
-                       OnionPayload::Invoice(_) => None,
+                       OnionPayload::Invoice { .. } => None,
                        OnionPayload::Spontaneous(preimage) => Some(preimage.clone()),
                };
-               write_tlv_fields!
-               (writer,
-                {
-                  (0, self.prev_hop, required), (2, self.value, required),
-                  (4, payment_data, option), (6, self.cltv_expiry, required),
-                        (8, keysend_preimage, option),
-                });
+               write_tlv_fields!(writer, {
+                       (0, self.prev_hop, required),
+                       (1, self.total_msat, required),
+                       (2, self.value, required),
+                       (4, payment_data, option),
+                       (6, self.cltv_expiry, required),
+                       (8, keysend_preimage, option),
+               });
                Ok(())
        }
 }
@@ -6247,32 +6100,41 @@ impl Readable for ClaimableHTLC {
                let mut value = 0;
                let mut payment_data: Option<msgs::FinalOnionHopData> = None;
                let mut cltv_expiry = 0;
+               let mut total_msat = None;
                let mut keysend_preimage: Option<PaymentPreimage> = None;
-               read_tlv_fields!
-               (reader,
-                {
-                  (0, prev_hop, required), (2, value, required),
-                  (4, payment_data, option), (6, cltv_expiry, required),
-                        (8, keysend_preimage, option)
-                });
+               read_tlv_fields!(reader, {
+                       (0, prev_hop, required),
+                       (1, total_msat, option),
+                       (2, value, required),
+                       (4, payment_data, option),
+                       (6, cltv_expiry, required),
+                       (8, keysend_preimage, option)
+               });
                let onion_payload = match keysend_preimage {
                        Some(p) => {
                                if payment_data.is_some() {
                                        return Err(DecodeError::InvalidValue)
                                }
+                               if total_msat.is_none() {
+                                       total_msat = Some(value);
+                               }
                                OnionPayload::Spontaneous(p)
                        },
                        None => {
                                if payment_data.is_none() {
                                        return Err(DecodeError::InvalidValue)
                                }
-                               OnionPayload::Invoice(payment_data.unwrap())
+                               if total_msat.is_none() {
+                                       total_msat = Some(payment_data.as_ref().unwrap().total_msat);
+                               }
+                               OnionPayload::Invoice { _legacy_hop_data: payment_data.unwrap() }
                        },
                };
                Ok(Self {
                        prev_hop: prev_hop.0.unwrap(),
                        timer_ticks: 0,
                        value,
+                       total_msat: total_msat.unwrap(),
                        onion_payload,
                        cltv_expiry,
                })
@@ -7346,8 +7208,8 @@ mod tests {
 
                let payer_pubkey = nodes[0].node.get_our_node_id();
                let payee_pubkey = nodes[1].node.get_our_node_id();
-               nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: InitFeatures::known() });
-               nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() });
+               nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
+               nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
 
                let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known());
                let route_params = RouteParameters {
@@ -7390,8 +7252,8 @@ mod tests {
 
                let payer_pubkey = nodes[0].node.get_our_node_id();
                let payee_pubkey = nodes[1].node.get_our_node_id();
-               nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: InitFeatures::known() });
-               nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() });
+               nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
+               nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
 
                let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known());
                let route_params = RouteParameters {
@@ -7473,15 +7335,15 @@ mod tests {
                // payment verification fails as expected.
                let mut bad_payment_hash = payment_hash.clone();
                bad_payment_hash.0[0] += 1;
-               match inbound_payment::verify(bad_payment_hash, payment_data.clone(), nodes[0].node.highest_seen_timestamp.load(Ordering::Acquire) as u64, &nodes[0].node.inbound_payment_key, &nodes[0].logger) {
+               match inbound_payment::verify(bad_payment_hash, &payment_data, nodes[0].node.highest_seen_timestamp.load(Ordering::Acquire) as u64, &nodes[0].node.inbound_payment_key, &nodes[0].logger) {
                        Ok(_) => panic!("Unexpected ok"),
                        Err(()) => {
-                               nodes[0].logger.assert_log_contains("lightning::ln::channelmanager::inbound_payment".to_string(), "Failing HTLC with user-generated payment_hash".to_string(), 1);
+                               nodes[0].logger.assert_log_contains("lightning::ln::inbound_payment".to_string(), "Failing HTLC with user-generated payment_hash".to_string(), 1);
                        }
                }
 
                // Check that using the original payment hash succeeds.
-               assert!(inbound_payment::verify(payment_hash, payment_data, nodes[0].node.highest_seen_timestamp.load(Ordering::Acquire) as u64, &nodes[0].node.inbound_payment_key, &nodes[0].logger).is_ok());
+               assert!(inbound_payment::verify(payment_hash, &payment_data, nodes[0].node.highest_seen_timestamp.load(Ordering::Acquire) as u64, &nodes[0].node.inbound_payment_key, &nodes[0].logger).is_ok());
        }
 }
 
@@ -7556,8 +7418,8 @@ pub mod bench {
                });
                let node_b_holder = NodeHolder { node: &node_b };
 
-               node_a.peer_connected(&node_b.get_our_node_id(), &Init { features: InitFeatures::known() });
-               node_b.peer_connected(&node_a.get_our_node_id(), &Init { features: InitFeatures::known() });
+               node_a.peer_connected(&node_b.get_our_node_id(), &Init { features: InitFeatures::known(), remote_network_address: None });
+               node_b.peer_connected(&node_a.get_our_node_id(), &Init { features: InitFeatures::known(), remote_network_address: None });
                node_a.create_channel(node_b.get_our_node_id(), 8_000_000, 100_000_000, 42, None).unwrap();
                node_b.handle_open_channel(&node_a.get_our_node_id(), InitFeatures::known(), &get_event_msg!(node_a_holder, MessageSendEvent::SendOpenChannel, node_b.get_our_node_id()));
                node_a.handle_accept_channel(&node_b.get_our_node_id(), InitFeatures::known(), &get_event_msg!(node_b_holder, MessageSendEvent::SendAcceptChannel, node_a.get_our_node_id()));