X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmanager.rs;h=4ac575ff6f4c13270c0a27604c5860453d40ba3a;hb=61629bc00ef7d64b56b3dad18d40d29c8037e068;hp=f3913c5167c8ebc70d0b1cfadb20568908555133;hpb=b1cd5a74348ad305ce9cacd30749322651811635;p=rust-lightning diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index f3913c51..4ac575ff 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -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 { - 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(keys: &ExpandedKey, min_value_msat: Option, invoice_expiry_delta_secs: u32, keys_manager: &K, highest_seen_timestamp: u64) -> Result<(PaymentHash, PaymentSecret), ()> - where K::Target: KeysInterface - { - 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::::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, payment_hash: PaymentHash, invoice_expiry_delta_secs: u32, highest_seen_timestamp: u64) -> Result { - let metadata_bytes = construct_metadata_bytes(min_value_msat, Method::UserPaymentHash, invoice_expiry_delta_secs, highest_seen_timestamp)?; - - let mut hmac = HmacEngine::::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, 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(payment_hash: PaymentHash, payment_data: msgs::FinalOnionHopData, highest_seen_timestamp: u64, keys: &ExpandedKey, logger: &L) -> Result, ()> - 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::::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 { - 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 { - let mut hmac = HmacEngine::::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: // @@ -441,6 +172,7 @@ struct ClaimableHTLC { cltv_expiry: u32, value: u64, onion_payload: OnionPayload, + timer_ticks: u8, } /// A payment identifier used to uniquely identify a payment to LDK. @@ -496,6 +228,7 @@ impl core::hash::Hash for HTLCSource { } } } +#[cfg(not(feature = "grind_signatures"))] #[cfg(test)] impl HTLCSource { pub fn dummy() -> Self { @@ -886,6 +619,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 = ChannelManager, Arc, Arc, Arc, Arc>; /// SimpleRefChannelManager is a type alias for a ChannelManager reference, and is the reference @@ -896,6 +631,8 @@ pub type SimpleArcChannelManager = ChannelManager = ChannelManager; /// Manager which keeps track of a number of channels and sends messages to the appropriate @@ -1148,6 +885,9 @@ const CHECK_CLTV_EXPIRY_SANITY_2: u32 = MIN_CLTV_EXPIRY_DELTA as u32 - LATENCY_G /// pending HTLCs in flight. pub(crate) const PAYMENT_EXPIRY_BLOCKS: u32 = 3; +/// The number of ticks of [`ChannelManager::timer_tick_occurred`] until expiry of incomplete MPPs +pub(crate) const MPP_TIMEOUT_TICKS: u8 = 3; + /// Information needed for constructing an invoice route hint for this channel. #[derive(Clone, Debug, PartialEq)] pub struct CounterpartyForwardingInfo { @@ -1182,6 +922,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, + /// 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, + /// The largest value HTLC (in msat) the remote peer currently will accept, for this channel. + pub outbound_htlc_maximum_msat: Option, } /// Details of a channel, as returned by ChannelManager::list_channels and ChannelManager::list_usable_channels @@ -1200,6 +946,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, + /// 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, /// The position of the funding transaction in the chain. None if the funding transaction has /// not yet been confirmed and the channel fully opened. /// @@ -1214,6 +964,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, /// The value, in satoshis, of this channel as appears in the funding output @@ -1252,6 +1005,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). @@ -1299,12 +1059,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, + /// The largest value HTLC (in msat) we currently will accept, for this channel. + pub inbound_htlc_maximum_msat: Option, } 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 { self.inbound_scid_alias.or(self.short_channel_id) } @@ -1909,8 +1677,7 @@ impl 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 { @@ -1920,15 +1687,27 @@ impl 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(), @@ -1936,6 +1715,8 @@ impl 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() }); } } @@ -2406,15 +2187,19 @@ impl 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 @@ -2464,21 +2249,22 @@ impl 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[..]); } } } @@ -2514,6 +2300,10 @@ impl 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) -> Result { + 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 { @@ -3052,7 +2842,7 @@ impl 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; @@ -3203,9 +2993,9 @@ impl 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; }, @@ -3326,6 +3116,7 @@ impl ChannelMana phantom_shared_secret, }, value: amt_to_forward, + timer_ticks: 0, cltv_expiry, onion_payload, }; @@ -3620,6 +3411,7 @@ impl ChannelMana let new_feerate = self.fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal); let mut handle_errors = Vec::new(); + let mut timed_out_mpp_htlcs = Vec::new(); { let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_state_lock; @@ -3668,6 +3460,32 @@ impl ChannelMana true }); + + channel_state.claimable_htlcs.retain(|payment_hash, htlcs| { + if htlcs.is_empty() { + // This should be unreachable + debug_assert!(false); + return false; + } + if let OnionPayload::Invoice(ref final_hop_data) = 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) { + return true; + } else if htlcs.into_iter().any(|htlc| { + htlc.timer_ticks += 1; + return htlc.timer_ticks >= MPP_TIMEOUT_TICKS + }) { + timed_out_mpp_htlcs.extend(htlcs.into_iter().map(|htlc| (htlc.prev_hop.clone(), payment_hash.clone()))); + return false; + } + } + true + }); + } + + for htlc_source in timed_out_mpp_htlcs.drain(..) { + self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), HTLCSource::PreviousHopData(htlc_source.0), &htlc_source.1, HTLCFailReason::Reason { failure_code: 23, data: Vec::new() }); } for (err, counterparty_node_id) in handle_errors.drain(..) { @@ -3701,6 +3519,51 @@ impl 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) -> (u16, Vec) { + // 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) -> (u16, Vec) { + 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. @@ -3711,11 +3574,7 @@ impl 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()) }; @@ -4191,7 +4050,10 @@ impl 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, }); @@ -4228,10 +4090,12 @@ impl 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 { @@ -4251,8 +4115,13 @@ impl 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(); @@ -4264,7 +4133,7 @@ impl 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(_) => { @@ -4305,7 +4174,7 @@ impl 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(); @@ -4315,6 +4184,7 @@ impl 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(), } ); } @@ -4466,10 +4336,12 @@ impl 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(()) }, @@ -4600,28 +4472,8 @@ impl 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, &[]) }; @@ -4943,10 +4795,12 @@ impl 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!( @@ -5505,6 +5359,12 @@ where let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier); self.do_chain_event(Some(height), |channel| channel.transactions_confirmed(&block_hash, height, txdata, self.genesis_hash.clone(), self.get_our_node_id(), &self.logger) .map(|(a, b)| (a, Vec::new(), b))); + + let last_best_block_height = self.best_block.read().unwrap().height(); + if height < last_best_block_height { + let timestamp = self.highest_seen_timestamp.load(Ordering::Acquire); + self.do_chain_event(Some(last_best_block_height), |channel| channel.best_block_updated(last_best_block_height, timestamp as u32, self.genesis_hash.clone(), self.get_our_node_id(), &self.logger)); + } } fn best_block_updated(&self, header: &BlockHeader, height: u32) { @@ -5611,20 +5471,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())); } @@ -5893,6 +5754,7 @@ impl &events::MessageSendEvent::SendChannelRangeQuery { .. } => false, &events::MessageSendEvent::SendShortIdsQuery { .. } => false, &events::MessageSendEvent::SendReplyChannelRange { .. } => false, + &events::MessageSendEvent::SendGossipTimestampFilter { .. } => false, } }); } @@ -5958,6 +5820,23 @@ impl } } } 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)); } @@ -6049,11 +5928,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), @@ -6062,6 +5944,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), @@ -6069,6 +5954,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, { @@ -6233,6 +6120,7 @@ impl Readable for ClaimableHTLC { }; Ok(Self { prev_hop: prev_hop.0.unwrap(), + timer_ticks: 0, value, onion_payload, cltv_expiry, @@ -7307,8 +7195,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 { @@ -7351,8 +7239,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 { @@ -7437,7 +7325,7 @@ mod tests { 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) { 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); } } @@ -7517,8 +7405,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()));