X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmanager.rs;h=9f86095d647e522d876628768b7f3b4ac6bd08f1;hb=c126f0b1870552d03b011afd4104a22fb523007a;hp=e71d7124aaafcfb16492006d7ad19bfc8ee90f58;hpb=a841e6b9e1599b6dd7b67ca7f6dc2b85645e64b3;p=rust-lightning diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index e71d7124..9f86095d 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -63,7 +63,7 @@ use crate::offers::merkle::SignError; use crate::offers::offer::{DerivedMetadata, Offer, OfferBuilder}; use crate::offers::parse::Bolt12SemanticError; use crate::offers::refund::{Refund, RefundBuilder}; -use crate::onion_message::{Destination, OffersMessage, OffersMessageHandler, PendingOnionMessage}; +use crate::onion_message::{Destination, OffersMessage, OffersMessageHandler, PendingOnionMessage, new_pending_onion_message}; use crate::sign::{EntropySource, KeysManager, NodeSigner, Recipient, SignerProvider, WriteableEcdsaChannelSigner}; use crate::util::config::{UserConfig, ChannelConfig, ChannelConfigUpdate}; use crate::util::wakers::{Future, Notifier}; @@ -827,7 +827,8 @@ struct PendingInboundPayment { /// or, respectively, [`Router`] for its router, but this type alias chooses the concrete types /// of [`KeysManager`] and [`DefaultRouter`]. /// -/// This is not exported to bindings users as Arcs don't make sense in bindings +/// This is not exported to bindings users as type aliases aren't supported in most languages. +#[cfg(not(c_bindings))] pub type SimpleArcChannelManager = ChannelManager< Arc, Arc, @@ -855,7 +856,8 @@ pub type SimpleArcChannelManager = ChannelManager< /// or, respectively, [`Router`] for its router, but this type alias chooses the concrete types /// of [`KeysManager`] and [`DefaultRouter`]. /// -/// This is not exported to bindings users as Arcs don't make sense in bindings +/// This is not exported to bindings users as type aliases aren't supported in most languages. +#[cfg(not(c_bindings))] pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, M, T, F, L> = ChannelManager< &'a M, @@ -2681,11 +2683,11 @@ where /// will be accepted on the given channel, and after additional timeout/the closing of all /// pending HTLCs, the channel will be closed on chain. /// - /// * If we are the channel initiator, we will pay between our [`Background`] and - /// [`ChannelConfig::force_close_avoidance_max_fee_satoshis`] plus our [`Normal`] fee - /// estimate. + /// * If we are the channel initiator, we will pay between our [`ChannelCloseMinimum`] and + /// [`ChannelConfig::force_close_avoidance_max_fee_satoshis`] plus our [`NonAnchorChannelFee`] + /// fee estimate. /// * If our counterparty is the channel initiator, we will require a channel closing - /// transaction feerate of at least our [`Background`] feerate or the feerate which + /// transaction feerate of at least our [`ChannelCloseMinimum`] feerate or the feerate which /// would appear on a force-closure transaction, whichever is lower. We will allow our /// counterparty to pay as much fee as they'd like, however. /// @@ -2697,8 +2699,8 @@ where /// channel. /// /// [`ChannelConfig::force_close_avoidance_max_fee_satoshis`]: crate::util::config::ChannelConfig::force_close_avoidance_max_fee_satoshis - /// [`Background`]: crate::chain::chaininterface::ConfirmationTarget::Background - /// [`Normal`]: crate::chain::chaininterface::ConfirmationTarget::Normal + /// [`ChannelCloseMinimum`]: crate::chain::chaininterface::ConfirmationTarget::ChannelCloseMinimum + /// [`NonAnchorChannelFee`]: crate::chain::chaininterface::ConfirmationTarget::NonAnchorChannelFee /// [`SendShutdown`]: crate::events::MessageSendEvent::SendShutdown pub fn close_channel(&self, channel_id: &ChannelId, counterparty_node_id: &PublicKey) -> Result<(), APIError> { self.close_channel_internal(channel_id, counterparty_node_id, None, None) @@ -2712,8 +2714,8 @@ where /// the channel being closed or not: /// * If we are the channel initiator, we will pay at least this feerate on the closing /// transaction. The upper-bound is set by - /// [`ChannelConfig::force_close_avoidance_max_fee_satoshis`] plus our [`Normal`] fee - /// estimate (or `target_feerate_sat_per_1000_weight`, if it is greater). + /// [`ChannelConfig::force_close_avoidance_max_fee_satoshis`] plus our [`NonAnchorChannelFee`] + /// fee estimate (or `target_feerate_sat_per_1000_weight`, if it is greater). /// * If our counterparty is the channel initiator, we will refuse to accept a channel closure /// transaction feerate below `target_feerate_sat_per_1000_weight` (or the feerate which /// will appear on a force-closure transaction, whichever is lower). @@ -2731,8 +2733,7 @@ where /// channel. /// /// [`ChannelConfig::force_close_avoidance_max_fee_satoshis`]: crate::util::config::ChannelConfig::force_close_avoidance_max_fee_satoshis - /// [`Background`]: crate::chain::chaininterface::ConfirmationTarget::Background - /// [`Normal`]: crate::chain::chaininterface::ConfirmationTarget::Normal + /// [`NonAnchorChannelFee`]: crate::chain::chaininterface::ConfirmationTarget::NonAnchorChannelFee /// [`SendShutdown`]: crate::events::MessageSendEvent::SendShutdown pub fn close_channel_with_feerate_and_script(&self, channel_id: &ChannelId, counterparty_node_id: &PublicKey, target_feerate_sats_per_1000_weight: Option, shutdown_script: Option) -> Result<(), APIError> { self.close_channel_internal(channel_id, counterparty_node_id, target_feerate_sats_per_1000_weight, shutdown_script) @@ -3419,12 +3420,10 @@ where let prng_seed = self.entropy_source.get_secure_random_bytes(); let session_priv = SecretKey::from_slice(&session_priv_bytes[..]).expect("RNG is busted"); - let onion_keys = onion_utils::construct_onion_keys(&self.secp_ctx, &path, &session_priv) - .map_err(|_| APIError::InvalidRoute{err: "Pubkey along hop was maliciously selected".to_owned()})?; - let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(path, total_value, recipient_onion, cur_height, keysend_preimage)?; - - let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, prng_seed, payment_hash) - .map_err(|_| APIError::InvalidRoute { err: "Route size too large considering onion data".to_owned()})?; + let (onion_packet, htlc_msat, htlc_cltv) = onion_utils::create_payment_onion( + &self.secp_ctx, &path, &session_priv, total_value, recipient_onion, cur_height, + payment_hash, keysend_preimage, prng_seed + )?; let err: Result<(), _> = loop { let (counterparty_node_id, id) = match self.short_to_chan_info.read().unwrap().get(&path.hops.first().unwrap().short_channel_id) { @@ -4817,8 +4816,8 @@ where PersistenceNotifierGuard::optionally_notify(self, || { let mut should_persist = NotifyOption::SkipPersistNoEvents; - let normal_feerate = self.fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Normal); - let min_mempool_feerate = self.fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::MempoolMinimum); + let non_anchor_feerate = self.fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::NonAnchorChannelFee); + let anchor_feerate = self.fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::AnchorChannelFee); let per_peer_state = self.per_peer_state.read().unwrap(); for (_cp_id, peer_state_mutex) in per_peer_state.iter() { @@ -4828,9 +4827,9 @@ where |(chan_id, phase)| if let ChannelPhase::Funded(chan) = phase { Some((chan_id, chan)) } else { None } ) { let new_feerate = if chan.context.get_channel_type().supports_anchors_zero_fee_htlc_tx() { - min_mempool_feerate + anchor_feerate } else { - normal_feerate + non_anchor_feerate }; let chan_needs_persist = self.update_channel_fee(chan_id, chan, new_feerate); if chan_needs_persist == NotifyOption::DoPersist { should_persist = NotifyOption::DoPersist; } @@ -4866,8 +4865,8 @@ where PersistenceNotifierGuard::optionally_notify(self, || { let mut should_persist = NotifyOption::SkipPersistNoEvents; - let normal_feerate = self.fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Normal); - let min_mempool_feerate = self.fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::MempoolMinimum); + let non_anchor_feerate = self.fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::NonAnchorChannelFee); + let anchor_feerate = self.fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::AnchorChannelFee); let mut handle_errors: Vec<(Result<(), _>, _)> = Vec::new(); let mut timed_out_mpp_htlcs = Vec::new(); @@ -4914,9 +4913,9 @@ where match phase { ChannelPhase::Funded(chan) => { let new_feerate = if chan.context.get_channel_type().supports_anchors_zero_fee_htlc_tx() { - min_mempool_feerate + anchor_feerate } else { - normal_feerate + non_anchor_feerate }; let chan_needs_persist = self.update_channel_fee(chan_id, chan, new_feerate); if chan_needs_persist == NotifyOption::DoPersist { should_persist = NotifyOption::DoPersist; } @@ -7330,6 +7329,8 @@ where /// Requires a direct connection to the introduction node in the responding [`InvoiceRequest`]'s /// reply path. /// + /// This is not exported to bindings users as builder patterns don't map outside of move semantics. + /// /// [`Offer`]: crate::offers::offer::Offer /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest pub fn create_offer_builder( @@ -7363,6 +7364,9 @@ where /// invoice. If abandoned, or an invoice isn't received before expiration, the payment will fail /// with an [`Event::InvoiceRequestFailed`]. /// + /// If `max_total_routing_fee_msat` is not specified, The default from + /// [`RouteParameters::from_payment_params_and_value`] is applied. + /// /// # Privacy /// /// Uses a one-hop [`BlindedPath`] for the refund with [`ChannelManager::get_our_node_id`] as @@ -7380,6 +7384,8 @@ where /// Errors if a duplicate `payment_id` is provided given the caveats in the aforementioned link /// or if `amount_msats` is invalid. /// + /// This is not exported to bindings users as builder patterns don't map outside of move semantics. + /// /// [`Refund`]: crate::offers::refund::Refund /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice /// [`Bolt12Invoice::payment_paths`]: crate::offers::invoice::Bolt12Invoice::payment_paths @@ -7422,6 +7428,9 @@ where /// - `amount_msats` if overpaying what is required for the given `quantity` is desired, and /// - `payer_note` for [`InvoiceRequest::payer_note`]. /// + /// If `max_total_routing_fee_msat` is not specified, The default from + /// [`RouteParameters::from_payment_params_and_value`] is applied. + /// /// # Payment /// /// The provided `payment_id` is used to ensure that only one invoice is paid for the request @@ -7494,11 +7503,11 @@ where let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap(); if offer.paths().is_empty() { - let message = PendingOnionMessage { - contents: OffersMessage::InvoiceRequest(invoice_request), - destination: Destination::Node(offer.signing_pubkey()), - reply_path: Some(reply_path), - }; + let message = new_pending_onion_message( + OffersMessage::InvoiceRequest(invoice_request), + Destination::Node(offer.signing_pubkey()), + Some(reply_path), + ); pending_offers_messages.push(message); } else { // Send as many invoice requests as there are paths in the offer (with an upper bound). @@ -7506,11 +7515,11 @@ where // one invoice for a given payment id will be paid, even if more than one is received. const REQUEST_LIMIT: usize = 10; for path in offer.paths().into_iter().take(REQUEST_LIMIT) { - let message = PendingOnionMessage { - contents: OffersMessage::InvoiceRequest(invoice_request.clone()), - destination: Destination::BlindedPath(path.clone()), - reply_path: Some(reply_path.clone()), - }; + let message = new_pending_onion_message( + OffersMessage::InvoiceRequest(invoice_request.clone()), + Destination::BlindedPath(path.clone()), + Some(reply_path.clone()), + ); pending_offers_messages.push(message); } } @@ -7528,7 +7537,9 @@ where /// # Limitations /// /// Requires a direct connection to an introduction node in [`Refund::paths`] or to - /// [`Refund::payer_id`], if empty. + /// [`Refund::payer_id`], if empty. This request is best effort; an invoice will be sent to each + /// node meeting the aforementioned criteria, but there's no guarantee that they will be + /// received and no retries will be made. /// /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice pub fn request_refund_payment(&self, refund: &Refund) -> Result<(), Bolt12SemanticError> { @@ -7561,19 +7572,19 @@ where let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap(); if refund.paths().is_empty() { - let message = PendingOnionMessage { - contents: OffersMessage::Invoice(invoice), - destination: Destination::Node(refund.payer_id()), - reply_path: Some(reply_path), - }; + let message = new_pending_onion_message( + OffersMessage::Invoice(invoice), + Destination::Node(refund.payer_id()), + Some(reply_path), + ); pending_offers_messages.push(message); } else { for path in refund.paths() { - let message = PendingOnionMessage { - contents: OffersMessage::Invoice(invoice.clone()), - destination: Destination::BlindedPath(path.clone()), - reply_path: Some(reply_path.clone()), - }; + let message = new_pending_onion_message( + OffersMessage::Invoice(invoice.clone()), + Destination::BlindedPath(path.clone()), + Some(reply_path.clone()), + ); pending_offers_messages.push(message); } } @@ -8960,10 +8971,10 @@ where match invoice.sign(|invoice| self.node_signer.sign_bolt12_invoice(invoice)) { Ok(invoice) => Ok(OffersMessage::Invoice(invoice)), Err(SignError::Signing(())) => Err(OffersMessage::InvoiceError( - InvoiceError::from_str("Failed signing invoice") + InvoiceError::from_string("Failed signing invoice".to_string()) )), Err(SignError::Verification(_)) => Err(OffersMessage::InvoiceError( - InvoiceError::from_str("Failed invoice signature verification") + InvoiceError::from_string("Failed invoice signature verification".to_string()) )), }); match response { @@ -8979,7 +8990,7 @@ where OffersMessage::Invoice(invoice) => { match invoice.verify(expanded_key, secp_ctx) { Err(()) => { - Some(OffersMessage::InvoiceError(InvoiceError::from_str("Unrecognized invoice"))) + Some(OffersMessage::InvoiceError(InvoiceError::from_string("Unrecognized invoice".to_owned()))) }, Ok(_) if invoice.invoice_features().requires_unknown_bits_from(&self.bolt12_invoice_features()) => { Some(OffersMessage::InvoiceError(Bolt12SemanticError::UnknownRequiredFeatures.into())) @@ -8987,7 +8998,7 @@ where Ok(payment_id) => { if let Err(e) = self.send_payment_for_bolt12_invoice(&invoice, payment_id) { log_trace!(self.logger, "Failed paying invoice: {:?}", e); - Some(OffersMessage::InvoiceError(InvoiceError::from_str(&format!("{:?}", e)))) + Some(OffersMessage::InvoiceError(InvoiceError::from_string(format!("{:?}", e)))) } else { None }