X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmanager.rs;h=f2b3bf15d39608f93d08774c43306cc31f102ac5;hb=960dd658db6e66edd5255a5a4bddcbeb89a1e238;hp=05d4351509eb5d6442841656f83c4d0210c02151;hpb=8701b1bbe3a1e92cdb1e9dc56b6472574d6a9d93;p=rust-lightning diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 05d43515..f2b3bf15 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -42,7 +42,8 @@ use crate::events; use crate::events::{Event, EventHandler, EventsProvider, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination, PaymentFailureReason}; // Since this struct is returned in `list_channels` methods, expose it here in case users want to // construct one themselves. -use crate::ln::{inbound_payment, ChannelId, PaymentHash, PaymentPreimage, PaymentSecret}; +use crate::ln::inbound_payment; +use crate::ln::types::{ChannelId, PaymentHash, PaymentPreimage, PaymentSecret}; use crate::ln::channel::{self, Channel, ChannelPhase, ChannelContext, ChannelError, ChannelUpdateStatus, ShutdownResult, UnfundedChannelContext, UpdateFulfillCommitFetch, OutboundV1Channel, InboundV1Channel, WithChannelContext}; pub use crate::ln::channel::{InboundHTLCDetails, InboundHTLCStateDetails, OutboundHTLCDetails, OutboundHTLCStateDetails}; use crate::ln::features::{Bolt12InvoiceFeatures, ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures}; @@ -64,10 +65,10 @@ use crate::offers::invoice_request::{DerivedPayerId, InvoiceRequestBuilder}; use crate::offers::offer::{Offer, OfferBuilder}; use crate::offers::parse::Bolt12SemanticError; use crate::offers::refund::{Refund, RefundBuilder}; -use crate::onion_message::messenger::{Destination, MessageRouter, PendingOnionMessage, new_pending_onion_message}; +use crate::onion_message::messenger::{new_pending_onion_message, Destination, MessageRouter, PendingOnionMessage, Responder, ResponseInstruction}; use crate::onion_message::offers::{OffersMessage, OffersMessageHandler}; use crate::sign::{EntropySource, NodeSigner, Recipient, SignerProvider}; -use crate::sign::ecdsa::WriteableEcdsaChannelSigner; +use crate::sign::ecdsa::EcdsaChannelSigner; use crate::util::config::{UserConfig, ChannelConfig, ChannelConfigUpdate}; use crate::util::wakers::{Future, Notifier}; use crate::util::scid_utils::fake_scid; @@ -75,6 +76,7 @@ use crate::util::string::UntrustedString; use crate::util::ser::{BigSize, FixedLengthReader, Readable, ReadableArgs, MaybeReadable, Writeable, Writer, VecWriter}; use crate::util::logger::{Level, Logger, WithContext}; use crate::util::errors::APIError; + #[cfg(not(c_bindings))] use { crate::offers::offer::DerivedMetadata, @@ -357,11 +359,6 @@ enum OnionPayload { /// 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: Option, - /// The context of the payment included by the recipient in a blinded path, or `None` if a - /// blinded path was not used. - /// - /// Used in part to determine the [`events::PaymentPurpose`]. - payment_context: Option, }, /// Contains the payer-provided preimage. Spontaneous(PaymentPreimage), @@ -1064,8 +1061,8 @@ pub trait AChannelManager { type NodeSigner: NodeSigner + ?Sized; /// A type that may be dereferenced to [`Self::NodeSigner`]. type NS: Deref; - /// A type implementing [`WriteableEcdsaChannelSigner`]. - type Signer: WriteableEcdsaChannelSigner + Sized; + /// A type implementing [`EcdsaChannelSigner`]. + type Signer: EcdsaChannelSigner + Sized; /// A type implementing [`SignerProvider`] for [`Self::Signer`]. type SignerProvider: SignerProvider + ?Sized; /// A type that may be dereferenced to [`Self::SignerProvider`]. @@ -1392,7 +1389,7 @@ where /// /// ``` /// # use bitcoin::secp256k1::PublicKey; -/// # use lightning::ln::ChannelId; +/// # use lightning::ln::types::ChannelId; /// # use lightning::ln::channelmanager::AChannelManager; /// # use lightning::events::{Event, EventsProvider}; /// # @@ -1495,7 +1492,7 @@ where /// /// ``` /// # use lightning::events::{Event, EventsProvider}; -/// # use lightning::ln::PaymentHash; +/// # use lightning::ln::types::PaymentHash; /// # use lightning::ln::channelmanager::{AChannelManager, PaymentId, RecentPaymentDetails, RecipientOnionFields, Retry}; /// # use lightning::routing::router::RouteParameters; /// # @@ -1554,11 +1551,12 @@ where /// # fn example(channel_manager: T) -> Result<(), Bolt12SemanticError> { /// # let channel_manager = channel_manager.get_cm(); /// let offer = channel_manager -/// .create_offer_builder("coffee".to_string())? +/// .create_offer_builder()? /// # ; /// # // Needed for compiling for c_bindings /// # let builder: lightning::offers::offer::OfferBuilder<_, _> = offer.into(); /// # let offer = builder +/// .description("coffee".to_string()) /// .amount_msats(10_000_000) /// .build()?; /// let bech32_offer = offer.to_string(); @@ -1657,13 +1655,13 @@ where /// let payment_id = PaymentId([42; 32]); /// let refund = channel_manager /// .create_refund_builder( -/// "coffee".to_string(), amount_msats, absolute_expiry, payment_id, retry, -/// max_total_routing_fee_msat +/// amount_msats, absolute_expiry, payment_id, retry, max_total_routing_fee_msat /// )? /// # ; /// # // Needed for compiling for c_bindings /// # let builder: lightning::offers::refund::RefundBuilder<_> = refund.into(); /// # let refund = builder +/// .description("coffee".to_string()) /// .payer_note("refund for order 1234".to_string()) /// .build()?; /// let bech32_refund = refund.to_string(); @@ -2692,7 +2690,7 @@ macro_rules! handle_error { let counterparty_node_id = shutdown_res.counterparty_node_id; let channel_id = shutdown_res.channel_id; let logger = WithContext::from( - &$self.logger, Some(counterparty_node_id), Some(channel_id), + &$self.logger, Some(counterparty_node_id), Some(channel_id), None ); log_error!(logger, "Force-closing channel: {}", err.err); @@ -2763,7 +2761,7 @@ macro_rules! convert_chan_phase_err { (false, MsgHandleErrInternal::from_chan_no_close(ChannelError::Ignore(msg), *$channel_id)) }, ChannelError::Close(msg) => { - let logger = WithChannelContext::from(&$self.logger, &$channel.context); + let logger = WithChannelContext::from(&$self.logger, &$channel.context, None); log_error!(logger, "Closing channel {} due to close-required error: {}", $channel_id, msg); update_maps_on_chan_removal!($self, $channel.context); let reason = ClosureReason::ProcessingError { err: msg.clone() }; @@ -2898,7 +2896,7 @@ macro_rules! emit_channel_ready_event { macro_rules! handle_monitor_update_completion { ($self: ident, $peer_state_lock: expr, $peer_state: expr, $per_peer_state_lock: expr, $chan: expr) => { { - let logger = WithChannelContext::from(&$self.logger, &$chan.context); + let logger = WithChannelContext::from(&$self.logger, &$chan.context, None); let mut updates = $chan.monitor_updating_restored(&&logger, &$self.node_signer, $self.chain_hash, &$self.default_configuration, $self.best_block.read().unwrap().height); @@ -2997,7 +2995,7 @@ macro_rules! handle_monitor_update_completion { macro_rules! handle_new_monitor_update { ($self: ident, $update_res: expr, $chan: expr, _internal, $completed: expr) => { { debug_assert!($self.background_events_processed_since_startup.load(Ordering::Acquire)); - let logger = WithChannelContext::from(&$self.logger, &$chan.context); + let logger = WithChannelContext::from(&$self.logger, &$chan.context, None); match $update_res { ChannelMonitorUpdateStatus::UnrecoverableError => { let err_str = "ChannelMonitor[Update] persistence failed unrecoverably. This indicates we cannot continue normal operation and must shut down."; @@ -3578,7 +3576,7 @@ where } let logger = WithContext::from( - &self.logger, Some(shutdown_res.counterparty_node_id), Some(shutdown_res.channel_id), + &self.logger, Some(shutdown_res.counterparty_node_id), Some(shutdown_res.channel_id), None ); log_debug!(logger, "Finishing closure of channel due to {} with {} HTLCs to fail", @@ -3654,7 +3652,7 @@ where } else { ClosureReason::HolderForceClosed }; - let logger = WithContext::from(&self.logger, Some(*peer_node_id), Some(*channel_id)); + let logger = WithContext::from(&self.logger, Some(*peer_node_id), Some(*channel_id), None); if let hash_map::Entry::Occupied(chan_phase_entry) = peer_state.channel_by_id.entry(channel_id.clone()) { log_error!(logger, "Force-closing channel {}", channel_id); let mut chan_phase = remove_channel_phase!(self, chan_phase_entry); @@ -3888,7 +3886,7 @@ where } log_info!( - WithContext::from(&self.logger, Some(*counterparty_node_id), Some(msg.channel_id)), + WithContext::from(&self.logger, Some(*counterparty_node_id), Some(msg.channel_id), Some(msg.payment_hash)), "Failed to accept/forward incoming HTLC: {}", err_msg ); // If `msg.blinding_point` is set, we must always fail with malformed. @@ -3950,7 +3948,7 @@ where macro_rules! return_err { ($msg: expr, $err_code: expr, $data: expr) => { { - let logger = WithContext::from(&self.logger, Some(*counterparty_node_id), Some(msg.channel_id)); + let logger = WithContext::from(&self.logger, Some(*counterparty_node_id), Some(msg.channel_id), Some(msg.payment_hash)); log_info!(logger, "Failed to accept/forward incoming HTLC: {}", $msg); if msg.blinding_point.is_some() { return PendingHTLCStatus::Fail(HTLCFailureMsg::Malformed( @@ -4019,7 +4017,7 @@ where if chan.context.get_short_channel_id().is_none() { return Err(LightningError{err: "Channel not yet established".to_owned(), action: msgs::ErrorAction::IgnoreError}); } - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); log_trace!(logger, "Attempting to generate broadcast channel update for channel {}", &chan.context.channel_id()); self.get_channel_update_for_unicast(chan) } @@ -4036,7 +4034,7 @@ where /// [`channel_update`]: msgs::ChannelUpdate /// [`internal_closing_signed`]: Self::internal_closing_signed fn get_channel_update_for_unicast(&self, chan: &Channel) -> Result { - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); log_trace!(logger, "Attempting to generate channel update for channel {}", chan.context.channel_id()); let short_channel_id = match chan.context.get_short_channel_id().or(chan.context.latest_inbound_scid_alias()) { None => return Err(LightningError{err: "Channel not yet established".to_owned(), action: msgs::ErrorAction::IgnoreError}), @@ -4047,7 +4045,7 @@ where } fn get_channel_update_for_onion(&self, short_channel_id: u64, chan: &Channel) -> Result { - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); log_trace!(logger, "Generating channel update for channel {}", chan.context.channel_id()); let were_node_one = self.our_network_pubkey.serialize()[..] < chan.context.get_counterparty_node_id().serialize()[..]; @@ -4086,8 +4084,8 @@ where pub(crate) fn test_send_payment_along_path(&self, path: &Path, payment_hash: &PaymentHash, recipient_onion: RecipientOnionFields, total_value: u64, cur_height: u32, payment_id: PaymentId, keysend_preimage: &Option, session_priv_bytes: [u8; 32]) -> Result<(), APIError> { let _lck = self.total_consistency_lock.read().unwrap(); self.send_payment_along_path(SendAlongPathArgs { - path, payment_hash, recipient_onion, total_value, cur_height, payment_id, keysend_preimage, - session_priv_bytes + path, payment_hash, recipient_onion: &recipient_onion, total_value, + cur_height, payment_id, keysend_preimage, session_priv_bytes }) } @@ -4105,7 +4103,7 @@ where &self.secp_ctx, &path, &session_priv, total_value, recipient_onion, cur_height, payment_hash, keysend_preimage, prng_seed ).map_err(|e| { - let logger = WithContext::from(&self.logger, Some(path.hops.first().unwrap().pubkey), None); + let logger = WithContext::from(&self.logger, Some(path.hops.first().unwrap().pubkey), None, Some(*payment_hash)); log_error!(logger, "Failed to build an onion for path for payment hash {}", payment_hash); e })?; @@ -4113,14 +4111,14 @@ where 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) { None => { - let logger = WithContext::from(&self.logger, Some(path.hops.first().unwrap().pubkey), None); + let logger = WithContext::from(&self.logger, Some(path.hops.first().unwrap().pubkey), None, Some(*payment_hash)); log_error!(logger, "Failed to find first-hop for payment hash {}", payment_hash); return Err(APIError::ChannelUnavailable{err: "No channel available with first hop!".to_owned()}) }, Some((cp_id, chan_id)) => (cp_id.clone(), chan_id.clone()), }; - let logger = WithContext::from(&self.logger, Some(counterparty_node_id), Some(id)); + let logger = WithContext::from(&self.logger, Some(counterparty_node_id), Some(id), Some(*payment_hash)); log_trace!(logger, "Attempting to send payment with payment hash {} along path with next hop {}", payment_hash, path.hops.first().unwrap().short_channel_id); @@ -4137,7 +4135,7 @@ where return Err(APIError::ChannelUnavailable{err: "Peer for first hop currently disconnected".to_owned()}); } let funding_txo = chan.context.get_funding_txo().unwrap(); - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, Some(*payment_hash)); let send_res = chan.send_htlc_and_commit(htlc_msat, payment_hash.clone(), htlc_cltv, HTLCSource::OutboundRoute { path: path.clone(), @@ -4485,7 +4483,7 @@ where /// Handles the generation of a funding transaction, optionally (for tests) with a function /// which checks the correctness of the funding transaction given the associated channel. - fn funding_transaction_generated_intern, &Transaction) -> Result>( + fn funding_transaction_generated_intern, &Transaction) -> Result>( &self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey, funding_transaction: Transaction, is_batch_funding: bool, mut find_funding_output: FundingOutput, ) -> Result<(), APIError> { @@ -4498,26 +4496,38 @@ where let funding_txo; let (mut chan, msg_opt) = match peer_state.channel_by_id.remove(temporary_channel_id) { Some(ChannelPhase::UnfundedOutboundV1(mut chan)) => { - funding_txo = find_funding_output(&chan, &funding_transaction)?; - - let logger = WithChannelContext::from(&self.logger, &chan.context); - let funding_res = chan.get_funding_created(funding_transaction, funding_txo, is_batch_funding, &&logger) - .map_err(|(mut chan, e)| if let ChannelError::Close(msg) = e { - let channel_id = chan.context.channel_id(); + macro_rules! close_chan { ($err: expr, $api_err: expr, $chan: expr) => { { + let counterparty; + let err = if let ChannelError::Close(msg) = $err { + let channel_id = $chan.context.channel_id(); + counterparty = chan.context.get_counterparty_node_id(); let reason = ClosureReason::ProcessingError { err: msg.clone() }; - let shutdown_res = chan.context.force_shutdown(false, reason); - (chan, MsgHandleErrInternal::from_finish_shutdown(msg, channel_id, shutdown_res, None)) - } else { unreachable!(); }); + let shutdown_res = $chan.context.force_shutdown(false, reason); + MsgHandleErrInternal::from_finish_shutdown(msg, channel_id, shutdown_res, None) + } else { unreachable!(); }; + + mem::drop(peer_state_lock); + mem::drop(per_peer_state); + let _: Result<(), _> = handle_error!(self, Err(err), counterparty); + Err($api_err) + } } } + match find_funding_output(&chan, &funding_transaction) { + Ok(found_funding_txo) => funding_txo = found_funding_txo, + Err(err) => { + let chan_err = ChannelError::Close(err.to_owned()); + let api_err = APIError::APIMisuseError { err: err.to_owned() }; + return close_chan!(chan_err, api_err, chan); + }, + } + + let logger = WithChannelContext::from(&self.logger, &chan.context, None); + let funding_res = chan.get_funding_created(funding_transaction, funding_txo, is_batch_funding, &&logger); match funding_res { Ok(funding_msg) => (chan, funding_msg), - Err((chan, err)) => { - mem::drop(peer_state_lock); - mem::drop(per_peer_state); - let _: Result<(), _> = handle_error!(self, Err(err), chan.context.get_counterparty_node_id()); - return Err(APIError::ChannelUnavailable { - err: "Signer refused to sign the initial commitment transaction".to_owned() - }); - }, + Err((mut chan, chan_err)) => { + let api_err = APIError::ChannelUnavailable { err: "Signer refused to sign the initial commitment transaction".to_owned() }; + return close_chan!(chan_err, api_err, chan); + } } }, Some(phase) => { @@ -4682,17 +4692,13 @@ where for (idx, outp) in tx.output.iter().enumerate() { if outp.script_pubkey == expected_spk && outp.value == chan.context.get_value_satoshis() { if output_index.is_some() { - return Err(APIError::APIMisuseError { - err: "Multiple outputs matched the expected script and value".to_owned() - }); + return Err("Multiple outputs matched the expected script and value"); } output_index = Some(idx as u16); } } if output_index.is_none() { - return Err(APIError::APIMisuseError { - err: "No output matched the script_pubkey and value in the FundingGenerationReady event".to_owned() - }); + return Err("No output matched the script_pubkey and value in the FundingGenerationReady event"); } let outpoint = OutPoint { txid: tx.txid(), index: output_index.unwrap() }; if let Some(funding_batch_state) = funding_batch_state.as_mut() { @@ -4723,11 +4729,20 @@ where for (channel_id, counterparty_node_id) in channels_to_remove { per_peer_state.get(&counterparty_node_id) .map(|peer_state_mutex| peer_state_mutex.lock().unwrap()) - .and_then(|mut peer_state| peer_state.channel_by_id.remove(&channel_id)) - .map(|mut chan| { + .and_then(|mut peer_state| peer_state.channel_by_id.remove(&channel_id).map(|chan| (chan, peer_state))) + .map(|(mut chan, mut peer_state)| { update_maps_on_chan_removal!(self, &chan.context()); let closure_reason = ClosureReason::ProcessingError { err: e.clone() }; shutdown_results.push(chan.context_mut().force_shutdown(false, closure_reason)); + peer_state.pending_msg_events.push(events::MessageSendEvent::HandleError { + node_id: counterparty_node_id, + action: msgs::ErrorAction::SendErrorMessage { + msg: msgs::ErrorMessage { + channel_id, + data: "Failed to fund channel".to_owned(), + } + }, + }); }); } } @@ -4894,7 +4909,7 @@ where None => { let error = format!("Channel with id {} not found for the passed counterparty node_id {}", next_hop_channel_id, next_node_id); - let logger = WithContext::from(&self.logger, Some(next_node_id), Some(*next_hop_channel_id)); + let logger = WithContext::from(&self.logger, Some(next_node_id), Some(*next_hop_channel_id), None); log_error!(logger, "{} when attempting to forward intercepted HTLC", error); return Err(APIError::ChannelUnavailable { err: error @@ -5027,7 +5042,7 @@ where // Process the HTLC on the incoming channel. match self.do_funded_channel_callback(incoming_scid, |chan: &mut Channel| { - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, Some(update_add_htlc.payment_hash)); chan.can_accept_incoming_htlc( update_add_htlc, &self.fee_estimator, &logger, ) @@ -5140,7 +5155,7 @@ where }) => { macro_rules! failure_handler { ($msg: expr, $err_code: expr, $err_data: expr, $phantom_ss: expr, $next_hop_unknown: expr) => { - let logger = WithContext::from(&self.logger, forwarding_counterparty, Some(prev_channel_id)); + let logger = WithContext::from(&self.logger, forwarding_counterparty, Some(prev_channel_id), Some(payment_hash)); log_info!(logger, "Failed to accept/forward incoming HTLC: {}", $msg); let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData { @@ -5251,7 +5266,7 @@ where let mut peer_state_lock = peer_state_mutex_opt.unwrap().lock().unwrap(); let peer_state = &mut *peer_state_lock; if let Some(ChannelPhase::Funded(ref mut chan)) = peer_state.channel_by_id.get_mut(&forward_chan_id) { - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); for forward_info in pending_forwards.drain(..) { let queue_fail_htlc_res = match forward_info { HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo { @@ -5263,6 +5278,7 @@ where }, skimmed_fee_msat, .. }, }) => { + let logger = WithChannelContext::from(&self.logger, &chan.context, Some(payment_hash)); log_trace!(logger, "Adding HTLC from short id {} with payment_hash {} to channel with short id {} after delay", prev_short_channel_id, &payment_hash, short_chan_id); let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id: prev_short_channel_id, @@ -5346,7 +5362,7 @@ where } }) => { let blinded_failure = routing.blinded_failure(); - let (cltv_expiry, onion_payload, payment_data, phantom_shared_secret, mut onion_fields) = match routing { + let (cltv_expiry, onion_payload, payment_data, payment_context, phantom_shared_secret, mut onion_fields) = match routing { PendingHTLCRouting::Receive { payment_data, payment_metadata, payment_context, incoming_cltv_expiry, phantom_shared_secret, custom_tlvs, @@ -5355,8 +5371,8 @@ where let _legacy_hop_data = Some(payment_data.clone()); let onion_fields = RecipientOnionFields { payment_secret: Some(payment_data.payment_secret), payment_metadata, custom_tlvs }; - (incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data, payment_context }, - Some(payment_data), phantom_shared_secret, onion_fields) + (incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data }, + Some(payment_data), payment_context, phantom_shared_secret, onion_fields) }, PendingHTLCRouting::ReceiveKeysend { payment_data, payment_preimage, payment_metadata, @@ -5368,7 +5384,7 @@ where custom_tlvs, }; (incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage), - payment_data, None, onion_fields) + payment_data, None, None, onion_fields) }, _ => { panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive"); @@ -5530,7 +5546,7 @@ where match payment_secrets.entry(payment_hash) { hash_map::Entry::Vacant(_) => { match claimable_htlc.onion_payload { - OnionPayload::Invoice { ref payment_context, .. } => { + OnionPayload::Invoice { .. } => { let payment_data = payment_data.unwrap(); let (payment_preimage, min_final_cltv_expiry_delta) = match inbound_payment::verify(payment_hash, &payment_data, self.highest_seen_timestamp.load(Ordering::Acquire) as u64, &self.inbound_payment_key, &self.logger) { Ok(result) => result, @@ -5548,9 +5564,9 @@ where } } let purpose = events::PaymentPurpose::from_parts( - payment_preimage.clone(), + payment_preimage, payment_data.payment_secret, - payment_context.clone(), + payment_context, ); check_total_value!(purpose); }, @@ -5561,13 +5577,10 @@ where } }, hash_map::Entry::Occupied(inbound_payment) => { - let payment_context = match claimable_htlc.onion_payload { - OnionPayload::Spontaneous(_) => { - log_trace!(self.logger, "Failing new keysend HTLC with payment_hash {} because we already have an inbound payment with the same payment hash", &payment_hash); - fail_htlc!(claimable_htlc, payment_hash); - }, - OnionPayload::Invoice { ref payment_context, .. } => payment_context, - }; + if let OnionPayload::Spontaneous(_) = claimable_htlc.onion_payload { + log_trace!(self.logger, "Failing new keysend HTLC with payment_hash {} because we already have an inbound payment with the same payment hash", &payment_hash); + fail_htlc!(claimable_htlc, payment_hash); + } 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.", &payment_hash); @@ -5580,7 +5593,7 @@ where let purpose = events::PaymentPurpose::from_parts( inbound_payment.get().payment_preimage, payment_data.payment_secret, - payment_context.clone(), + payment_context, ); let payment_claimable_generated = check_total_value!(purpose); if payment_claimable_generated { @@ -5698,7 +5711,7 @@ where fn update_channel_fee(&self, chan_id: &ChannelId, chan: &mut Channel, new_feerate: u32) -> NotifyOption { if !chan.context.is_outbound() { return NotifyOption::SkipPersistNoEvents; } - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); // If the feerate has decreased by less than half, don't bother if new_feerate <= chan.context.get_feerate_sat_per_1000_weight() && new_feerate * 2 > chan.context.get_feerate_sat_per_1000_weight() { @@ -5791,7 +5804,7 @@ where | { context.maybe_expire_prev_config(); if unfunded_context.should_expire_unfunded_channel() { - let logger = WithChannelContext::from(&self.logger, context); + let logger = WithChannelContext::from(&self.logger, context, None); log_error!(logger, "Force-closing pending channel with ID {} for not establishing in a timely manner", chan_id); update_maps_on_chan_removal!(self, &context); @@ -5878,7 +5891,7 @@ where chan.context.maybe_expire_prev_config(); if chan.should_disconnect_peer_awaiting_response() { - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); log_debug!(logger, "Disconnecting peer {} due to not making any progress on channel {}", counterparty_node_id, chan_id); pending_msg_events.push(MessageSendEvent::HandleError { @@ -5917,7 +5930,7 @@ where for (chan_id, req) in peer_state.inbound_channel_request_by_id.iter_mut() { if { req.ticks_remaining -= 1 ; req.ticks_remaining } <= 0 { - let logger = WithContext::from(&self.logger, Some(counterparty_node_id), Some(*chan_id)); + let logger = WithContext::from(&self.logger, Some(counterparty_node_id), Some(*chan_id), None); log_error!(logger, "Force-closing unaccepted inbound channel {} for not accepting in a timely manner", &chan_id); peer_state.pending_msg_events.push( events::MessageSendEvent::HandleError { @@ -6203,7 +6216,7 @@ where ref phantom_shared_secret, outpoint: _, ref blinded_failure, ref channel_id, .. }) => { log_trace!( - WithContext::from(&self.logger, None, Some(*channel_id)), + WithContext::from(&self.logger, None, Some(*channel_id), Some(*payment_hash)), "Failing {}HTLC with payment_hash {} backwards from us: {:?}", if blinded_failure.is_some() { "blinded " } else { "" }, &payment_hash, onion_error ); @@ -6397,7 +6410,7 @@ where if let msgs::ErrorAction::IgnoreError = err.err.action { // We got a temporary failure updating monitor, but will claim the // HTLC when the monitor updating is restored (or on chain). - let logger = WithContext::from(&self.logger, None, Some(prev_hop_chan_id)); + let logger = WithContext::from(&self.logger, None, Some(prev_hop_chan_id), Some(payment_hash)); log_error!(logger, "Temporary failure claiming HTLC, treating as success: {}", err.err.err); } else { errs.push((pk, err)); } } @@ -6456,7 +6469,7 @@ where if let hash_map::Entry::Occupied(mut chan_phase_entry) = peer_state.channel_by_id.entry(chan_id) { if let ChannelPhase::Funded(chan) = chan_phase_entry.get_mut() { let counterparty_node_id = chan.context.get_counterparty_node_id(); - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); let fulfill_res = chan.get_update_fulfill_htlc_and_commit(prev_hop.htlc_id, payment_preimage, &&logger); match fulfill_res { @@ -6549,7 +6562,7 @@ where // with a preimage we *must* somehow manage to propagate it to the upstream // channel, or we must have an ability to receive the same event and try // again on restart. - log_error!(WithContext::from(&self.logger, None, Some(prev_hop.channel_id)), + log_error!(WithContext::from(&self.logger, None, Some(prev_hop.channel_id), None), "Critical error: failed to update channel monitor with preimage {:?}: {:?}", payment_preimage, update_res); } @@ -6772,7 +6785,7 @@ where funding_broadcastable: Option, channel_ready: Option, announcement_sigs: Option) -> (Option<(u64, OutPoint, ChannelId, u128, Vec<(PendingHTLCInfo, u64)>)>, Option<(u64, Vec)>) { - let logger = WithChannelContext::from(&self.logger, &channel.context); + let logger = WithChannelContext::from(&self.logger, &channel.context, None); log_trace!(logger, "Handling channel resumption for channel {} with {} RAA, {} commitment update, {} pending forwards, {} pending update_add_htlcs, {}broadcasting funding, {} channel ready, {} announcement", &channel.context.channel_id(), if raa.is_some() { "an" } else { "no" }, @@ -6883,7 +6896,7 @@ where pending.retain(|upd| upd.update_id > highest_applied_update_id); pending.len() } else { 0 }; - let logger = WithChannelContext::from(&self.logger, &channel.context); + let logger = WithChannelContext::from(&self.logger, &channel.context, None); log_trace!(logger, "ChannelMonitor updated to {}. Current highest is {}. {} pending in-flight updates.", highest_applied_update_id, channel.context.get_latest_monitor_update_id(), remaining_in_flight); @@ -6937,7 +6950,7 @@ where fn do_accept_inbound_channel(&self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey, accept_0conf: bool, user_channel_id: u128) -> Result<(), APIError> { - let logger = WithContext::from(&self.logger, Some(*counterparty_node_id), Some(*temporary_channel_id)); + let logger = WithContext::from(&self.logger, Some(*counterparty_node_id), Some(*temporary_channel_id), None); let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self); let peers_without_funded_channels = @@ -7273,7 +7286,7 @@ where let (mut chan, funding_msg_opt, monitor) = match peer_state.channel_by_id.remove(&msg.temporary_channel_id) { Some(ChannelPhase::UnfundedInboundV1(inbound_chan)) => { - let logger = WithChannelContext::from(&self.logger, &inbound_chan.context); + let logger = WithChannelContext::from(&self.logger, &inbound_chan.context, None); match inbound_chan.funding_created(msg, best_block, &self.signer_provider, &&logger) { Ok(res) => res, Err((inbound_chan, err)) => { @@ -7345,7 +7358,7 @@ where } Ok(()) } else { - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); log_error!(logger, "Persisting initial ChannelMonitor failed, implying the funding outpoint was duplicated"); fail_chan!("Duplicate funding outpoint"); } @@ -7373,7 +7386,8 @@ where let logger = WithContext::from( &self.logger, Some(chan.context.get_counterparty_node_id()), - Some(chan.context.channel_id()) + Some(chan.context.channel_id()), + None ); let res = chan.funding_signed(&msg, best_block, &self.signer_provider, &&logger); @@ -7429,7 +7443,7 @@ where match peer_state.channel_by_id.entry(msg.channel_id) { hash_map::Entry::Occupied(mut chan_phase_entry) => { if let ChannelPhase::Funded(chan) = chan_phase_entry.get_mut() { - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); let announcement_sigs_opt = try_chan_phase_entry!(self, chan.channel_ready(&msg, &self.node_signer, self.chain_hash, &self.default_configuration, &self.best_block.read().unwrap(), &&logger), chan_phase_entry); if let Some(announcement_sigs) = announcement_sigs_opt { @@ -7487,7 +7501,7 @@ where match phase { ChannelPhase::Funded(chan) => { if !chan.received_shutdown() { - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); log_info!(logger, "Received a shutdown message from our counterparty for channel {}{}.", msg.channel_id, if chan.sent_shutdown() { " after we initiated shutdown" } else { "" }); @@ -7515,7 +7529,7 @@ where }, ChannelPhase::UnfundedInboundV1(_) | ChannelPhase::UnfundedOutboundV1(_) => { let context = phase.context_mut(); - let logger = WithChannelContext::from(&self.logger, context); + let logger = WithChannelContext::from(&self.logger, context, None); log_error!(logger, "Immediately closing unfunded channel {} as peer asked to cooperatively shut it down (which is unnecessary)", &msg.channel_id); let mut chan = remove_channel_phase!(self, chan_phase_entry); finish_shutdown = Some(chan.context_mut().force_shutdown(false, ClosureReason::CounterpartyCoopClosedUnfundedChannel)); @@ -7584,7 +7598,7 @@ where }; if let Some(broadcast_tx) = tx { let channel_id = chan_option.as_ref().map(|channel| channel.context().channel_id()); - log_info!(WithContext::from(&self.logger, Some(*counterparty_node_id), channel_id), "Broadcasting {}", log_tx!(broadcast_tx)); + log_info!(WithContext::from(&self.logger, Some(*counterparty_node_id), channel_id, None), "Broadcasting {}", log_tx!(broadcast_tx)); self.tx_broadcaster.broadcast_transactions(&[&broadcast_tx]); } if let Some(ChannelPhase::Funded(chan)) = chan_option { @@ -7635,7 +7649,7 @@ where ), Err(e) => PendingHTLCStatus::Fail(e) }; - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, Some(msg.payment_hash)); // If the update_add is completely bogus, the call will Err and we will close, // but if we've sent a shutdown and they haven't acknowledged it yet, we just // want to reject the new HTLC and fail it backwards instead of forwarding. @@ -7673,7 +7687,7 @@ where } } } - try_chan_phase_entry!(self, chan.update_add_htlc(&msg, pending_forward_info), chan_phase_entry); + try_chan_phase_entry!(self, chan.update_add_htlc(&msg, pending_forward_info, &self.fee_estimator), chan_phase_entry); } else { return try_chan_phase_entry!(self, Err(ChannelError::Close( "Got an update_add_htlc message for an unfunded channel!".into())), chan_phase_entry); @@ -7701,7 +7715,7 @@ where if let ChannelPhase::Funded(chan) = chan_phase_entry.get_mut() { let res = try_chan_phase_entry!(self, chan.update_fulfill_htlc(&msg), chan_phase_entry); if let HTLCSource::PreviousHopData(prev_hop) = &res.0 { - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); log_trace!(logger, "Holding the next revoke_and_ack from {} until the preimage is durably persisted in the inbound edge's ChannelMonitor", msg.channel_id); @@ -7800,7 +7814,7 @@ where match peer_state.channel_by_id.entry(msg.channel_id) { hash_map::Entry::Occupied(mut chan_phase_entry) => { if let ChannelPhase::Funded(chan) = chan_phase_entry.get_mut() { - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); let funding_txo = chan.context.get_funding_txo(); let monitor_update_opt = try_chan_phase_entry!(self, chan.commitment_signed(&msg, &&logger), chan_phase_entry); if let Some(monitor_update) = monitor_update_opt { @@ -7878,7 +7892,7 @@ where prev_short_channel_id, prev_funding_outpoint, prev_channel_id, prev_htlc_id, prev_user_channel_id, forward_info }); }, hash_map::Entry::Occupied(_) => { - let logger = WithContext::from(&self.logger, None, Some(prev_channel_id)); + let logger = WithContext::from(&self.logger, None, Some(prev_channel_id), Some(forward_info.payment_hash)); log_info!(logger, "Failed to forward incoming HTLC: detected duplicate intercepted payment over short channel id {}", scid); let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData { short_channel_id: prev_short_channel_id, @@ -7988,7 +8002,7 @@ where match peer_state.channel_by_id.entry(msg.channel_id) { hash_map::Entry::Occupied(mut chan_phase_entry) => { if let ChannelPhase::Funded(chan) = chan_phase_entry.get_mut() { - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); let funding_txo_opt = chan.context.get_funding_txo(); let mon_update_blocked = if let Some(funding_txo) = funding_txo_opt { self.raa_monitor_updates_held( @@ -8028,7 +8042,7 @@ where match peer_state.channel_by_id.entry(msg.channel_id) { hash_map::Entry::Occupied(mut chan_phase_entry) => { if let ChannelPhase::Funded(chan) = chan_phase_entry.get_mut() { - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); try_chan_phase_entry!(self, chan.update_fee(&self.fee_estimator, &msg, &&logger), chan_phase_entry); } else { return try_chan_phase_entry!(self, Err(ChannelError::Close( @@ -8108,7 +8122,7 @@ where if were_node_one == msg_from_node_one { return Ok(NotifyOption::SkipPersistNoEvents); } else { - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); log_debug!(logger, "Received channel_update {:?} for channel {}.", msg, chan_id); let did_change = try_chan_phase_entry!(self, chan.channel_update(&msg), chan_phase_entry); // If nothing changed after applying their update, we don't need to bother @@ -8139,7 +8153,7 @@ where msg.channel_id ) })?; - let logger = WithContext::from(&self.logger, Some(*counterparty_node_id), Some(msg.channel_id)); + let logger = WithContext::from(&self.logger, Some(*counterparty_node_id), Some(msg.channel_id), None); let mut peer_state_lock = peer_state_mutex.lock().unwrap(); let peer_state = &mut *peer_state_lock; match peer_state.channel_by_id.entry(msg.channel_id) { @@ -8237,7 +8251,7 @@ where for monitor_event in monitor_events.drain(..) { match monitor_event { MonitorEvent::HTLCEvent(htlc_update) => { - let logger = WithContext::from(&self.logger, counterparty_node_id, Some(channel_id)); + let logger = WithContext::from(&self.logger, counterparty_node_id, Some(channel_id), Some(htlc_update.payment_hash)); if let Some(preimage) = htlc_update.payment_preimage { log_trace!(logger, "Claiming HTLC with preimage {} from our monitor", preimage); self.claim_funds_internal(htlc_update.source, preimage, @@ -8337,7 +8351,7 @@ where let counterparty_node_id = chan.context.get_counterparty_node_id(); let funding_txo = chan.context.get_funding_txo(); let (monitor_opt, holding_cell_failed_htlcs) = - chan.maybe_free_holding_cell_htlcs(&self.fee_estimator, &&WithChannelContext::from(&self.logger, &chan.context)); + chan.maybe_free_holding_cell_htlcs(&self.fee_estimator, &&WithChannelContext::from(&self.logger, &chan.context, None)); if !holding_cell_failed_htlcs.is_empty() { failed_htlcs.push((holding_cell_failed_htlcs, *channel_id, counterparty_node_id)); } @@ -8444,7 +8458,7 @@ where peer_state.channel_by_id.retain(|channel_id, phase| { match phase { ChannelPhase::Funded(chan) => { - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); match chan.maybe_propose_closing_signed(&self.fee_estimator, &&logger) { Ok((msg_opt, tx_opt, shutdown_result_opt)) => { if let Some(msg) = msg_opt { @@ -8549,13 +8563,9 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => { /// /// Errors if the parameterized [`Router`] is unable to create a blinded path for the offer. /// - /// 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( - &$self, description: String - ) -> Result<$builder, Bolt12SemanticError> { + pub fn create_offer_builder(&$self) -> Result<$builder, Bolt12SemanticError> { let node_id = $self.get_our_node_id(); let expanded_key = &$self.inbound_payment_key; let entropy = &*$self.entropy_source; @@ -8563,7 +8573,7 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => { let path = $self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?; let builder = OfferBuilder::deriving_signing_pubkey( - description, node_id, expanded_key, entropy, secp_ctx + node_id, expanded_key, entropy, secp_ctx ) .chain_hash($self.chain_hash) .path(path); @@ -8615,15 +8625,13 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => { /// - `amount_msats` is invalid, or /// - the parameterized [`Router`] is unable to create a blinded path for the refund. /// - /// 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 /// [Avoiding Duplicate Payments]: #avoiding-duplicate-payments pub fn create_refund_builder( - &$self, description: String, amount_msats: u64, absolute_expiry: Duration, - payment_id: PaymentId, retry_strategy: Retry, max_total_routing_fee_msat: Option + &$self, amount_msats: u64, absolute_expiry: Duration, payment_id: PaymentId, + retry_strategy: Retry, max_total_routing_fee_msat: Option ) -> Result<$builder, Bolt12SemanticError> { let node_id = $self.get_our_node_id(); let expanded_key = &$self.inbound_payment_key; @@ -8632,7 +8640,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => { let path = $self.create_blinded_path().map_err(|_| Bolt12SemanticError::MissingPaths)?; let builder = RefundBuilder::deriving_payer_id( - description, node_id, expanded_key, entropy, secp_ctx, amount_msats, payment_id + node_id, expanded_key, entropy, secp_ctx, amount_msats, payment_id )? .chain_hash($self.chain_hash) .absolute_expiry(absolute_expiry) @@ -8765,14 +8773,7 @@ where .map_err(|_| Bolt12SemanticError::DuplicatePaymentId)?; let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap(); - if offer.paths().is_empty() { - let message = new_pending_onion_message( - OffersMessage::InvoiceRequest(invoice_request), - Destination::Node(offer.signing_pubkey()), - Some(reply_path), - ); - pending_offers_messages.push(message); - } else { + if !offer.paths().is_empty() { // Send as many invoice requests as there are paths in the offer (with an upper bound). // Using only one path could result in a failure if the path no longer exists. But only // one invoice for a given payment id will be paid, even if more than one is received. @@ -8785,6 +8786,16 @@ where ); pending_offers_messages.push(message); } + } else if let Some(signing_pubkey) = offer.signing_pubkey() { + let message = new_pending_onion_message( + OffersMessage::InvoiceRequest(invoice_request), + Destination::Node(signing_pubkey), + Some(reply_path), + ); + pending_offers_messages.push(message); + } else { + debug_assert!(false); + return Err(Bolt12SemanticError::MissingSigningPubkey); } Ok(()) @@ -9125,7 +9136,7 @@ where mut completed_blocker: Option) { let logger = WithContext::from( - &self.logger, Some(counterparty_node_id), Some(channel_id), + &self.logger, Some(counterparty_node_id), Some(channel_id), None ); loop { let per_peer_state = self.per_peer_state.read().unwrap(); @@ -9335,7 +9346,7 @@ where *best_block = BestBlock::new(header.prev_blockhash, new_height) } - self.do_chain_event(Some(new_height), |channel| channel.best_block_updated(new_height, header.time, self.chain_hash, &self.node_signer, &self.default_configuration, &&WithChannelContext::from(&self.logger, &channel.context))); + self.do_chain_event(Some(new_height), |channel| channel.best_block_updated(new_height, header.time, self.chain_hash, &self.node_signer, &self.default_configuration, &&WithChannelContext::from(&self.logger, &channel.context, None))); } } @@ -9361,13 +9372,13 @@ where let _persistence_guard = PersistenceNotifierGuard::optionally_notify_skipping_background_events( self, || -> NotifyOption { NotifyOption::DoPersist }); - self.do_chain_event(Some(height), |channel| channel.transactions_confirmed(&block_hash, height, txdata, self.chain_hash, &self.node_signer, &self.default_configuration, &&WithChannelContext::from(&self.logger, &channel.context)) + self.do_chain_event(Some(height), |channel| channel.transactions_confirmed(&block_hash, height, txdata, self.chain_hash, &self.node_signer, &self.default_configuration, &&WithChannelContext::from(&self.logger, &channel.context, None)) .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.chain_hash, &self.node_signer, &self.default_configuration, &&WithChannelContext::from(&self.logger, &channel.context))); + self.do_chain_event(Some(last_best_block_height), |channel| channel.best_block_updated(last_best_block_height, timestamp as u32, self.chain_hash, &self.node_signer, &self.default_configuration, &&WithChannelContext::from(&self.logger, &channel.context, None))); } } @@ -9384,7 +9395,7 @@ where self, || -> NotifyOption { NotifyOption::DoPersist }); *self.best_block.write().unwrap() = BestBlock::new(block_hash, height); - self.do_chain_event(Some(height), |channel| channel.best_block_updated(height, header.time, self.chain_hash, &self.node_signer, &self.default_configuration, &&WithChannelContext::from(&self.logger, &channel.context))); + self.do_chain_event(Some(height), |channel| channel.best_block_updated(height, header.time, self.chain_hash, &self.node_signer, &self.default_configuration, &&WithChannelContext::from(&self.logger, &channel.context, None))); macro_rules! max_time { ($timestamp: expr) => { @@ -9433,7 +9444,7 @@ where self.do_chain_event(None, |channel| { if let Some(funding_txo) = channel.context.get_funding_txo() { if funding_txo.txid == *txid { - channel.funding_transaction_unconfirmed(&&WithChannelContext::from(&self.logger, &channel.context)).map(|()| (None, Vec::new(), None)) + channel.funding_transaction_unconfirmed(&&WithChannelContext::from(&self.logger, &channel.context, None)).map(|()| (None, Vec::new(), None)) } else { Ok((None, Vec::new(), None)) } } else { Ok((None, Vec::new(), None)) } }); @@ -9484,7 +9495,7 @@ where timed_out_htlcs.push((source, payment_hash, HTLCFailReason::reason(failure_code, data), HTLCDestination::NextHopChannel { node_id: Some(channel.context.get_counterparty_node_id()), channel_id: channel.context.channel_id() })); } - let logger = WithChannelContext::from(&self.logger, &channel.context); + let logger = WithChannelContext::from(&self.logger, &channel.context, None); if let Some(channel_ready) = channel_ready_opt { send_channel_ready!(self, pending_msg_events, channel, channel_ready); if channel.context.is_usable() { @@ -9609,7 +9620,7 @@ where HTLCFailReason::from_failure_code(0x2000 | 2), HTLCDestination::InvalidForward { requested_forward_scid })); let logger = WithContext::from( - &self.logger, None, Some(htlc.prev_channel_id) + &self.logger, None, Some(htlc.prev_channel_id), Some(htlc.forward_info.payment_hash) ); log_trace!(logger, "Timing out intercepted HTLC with requested forward scid {}", requested_forward_scid); false @@ -9925,7 +9936,7 @@ where let mut per_peer_state = self.per_peer_state.write().unwrap(); let remove_peer = { log_debug!( - WithContext::from(&self.logger, Some(*counterparty_node_id), None), + WithContext::from(&self.logger, Some(*counterparty_node_id), None, None), "Marking channels with {} disconnected and generating channel_updates.", log_pubkey!(counterparty_node_id) ); @@ -9936,7 +9947,7 @@ where peer_state.channel_by_id.retain(|_, phase| { let context = match phase { ChannelPhase::Funded(chan) => { - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); if chan.remove_uncommitted_htlcs_and_mark_paused(&&logger).is_ok() { // We only retain funded channels that are not shutdown. return true; @@ -10038,7 +10049,7 @@ where } fn peer_connected(&self, counterparty_node_id: &PublicKey, init_msg: &msgs::Init, inbound: bool) -> Result<(), ()> { - let logger = WithContext::from(&self.logger, Some(*counterparty_node_id), None); + let logger = WithContext::from(&self.logger, Some(*counterparty_node_id), None, None); if !init_msg.features.supports_static_remote_key() { log_debug!(logger, "Peer {} does not support static remote key, disconnecting", log_pubkey!(counterparty_node_id)); return Err(()); @@ -10103,7 +10114,7 @@ where for (_, phase) in peer_state.channel_by_id.iter_mut() { match phase { ChannelPhase::Funded(chan) => { - let logger = WithChannelContext::from(&self.logger, &chan.context); + let logger = WithChannelContext::from(&self.logger, &chan.context, None); pending_msg_events.push(events::MessageSendEvent::SendChannelReestablish { node_id: chan.context.get_counterparty_node_id(), msg: chan.get_channel_reestablish(&&logger), @@ -10337,23 +10348,27 @@ where R::Target: Router, L::Target: Logger, { - fn handle_message(&self, message: OffersMessage) -> Option { + fn handle_message(&self, message: OffersMessage, responder: Option) -> ResponseInstruction { let secp_ctx = &self.secp_ctx; let expanded_key = &self.inbound_payment_key; match message { OffersMessage::InvoiceRequest(invoice_request) => { + let responder = match responder { + Some(responder) => responder, + None => return ResponseInstruction::NoResponse, + }; let amount_msats = match InvoiceBuilder::::amount_msats( &invoice_request ) { Ok(amount_msats) => amount_msats, - Err(error) => return Some(OffersMessage::InvoiceError(error.into())), + Err(error) => return responder.respond(OffersMessage::InvoiceError(error.into())), }; let invoice_request = match invoice_request.verify(expanded_key, secp_ctx) { Ok(invoice_request) => invoice_request, Err(()) => { let error = Bolt12SemanticError::InvalidMetadata; - return Some(OffersMessage::InvoiceError(error.into())); + return responder.respond(OffersMessage::InvoiceError(error.into())); }, }; @@ -10364,7 +10379,7 @@ where Ok((payment_hash, payment_secret)) => (payment_hash, payment_secret), Err(()) => { let error = Bolt12SemanticError::InvalidAmount; - return Some(OffersMessage::InvoiceError(error.into())); + return responder.respond(OffersMessage::InvoiceError(error.into())); }, }; @@ -10378,7 +10393,7 @@ where Ok(payment_paths) => payment_paths, Err(()) => { let error = Bolt12SemanticError::MissingPaths; - return Some(OffersMessage::InvoiceError(error.into())); + return responder.respond(OffersMessage::InvoiceError(error.into())); }, }; @@ -10423,8 +10438,8 @@ where }; match response { - Ok(invoice) => Some(OffersMessage::Invoice(invoice)), - Err(error) => Some(OffersMessage::InvoiceError(error.into())), + Ok(invoice) => return responder.respond(OffersMessage::Invoice(invoice)), + Err(error) => return responder.respond(OffersMessage::InvoiceError(error.into())), } }, OffersMessage::Invoice(invoice) => { @@ -10444,14 +10459,21 @@ where } }); - match response { - Ok(()) => None, - Err(e) => Some(OffersMessage::InvoiceError(e)), + match (responder, response) { + (Some(responder), Err(e)) => responder.respond(OffersMessage::InvoiceError(e)), + (None, Err(_)) => { + log_trace!( + self.logger, + "A response was generated, but there is no reply_path specified for sending the response." + ); + return ResponseInstruction::NoResponse; + } + _ => return ResponseInstruction::NoResponse, } }, OffersMessage::InvoiceError(invoice_error) => { log_trace!(self.logger, "Received invoice_error: {}", invoice_error); - None + return ResponseInstruction::NoResponse; }, } } @@ -10815,11 +10837,11 @@ impl_writeable_tlv_based!(HTLCPreviousHopData, { impl Writeable for ClaimableHTLC { fn write(&self, writer: &mut W) -> Result<(), io::Error> { - let (payment_data, keysend_preimage, payment_context) = match &self.onion_payload { - OnionPayload::Invoice { _legacy_hop_data, payment_context } => { - (_legacy_hop_data.as_ref(), None, payment_context.as_ref()) + let (payment_data, keysend_preimage) = match &self.onion_payload { + OnionPayload::Invoice { _legacy_hop_data } => { + (_legacy_hop_data.as_ref(), None) }, - OnionPayload::Spontaneous(preimage) => (None, Some(preimage), None), + OnionPayload::Spontaneous(preimage) => (None, Some(preimage)), }; write_tlv_fields!(writer, { (0, self.prev_hop, required), @@ -10831,7 +10853,6 @@ impl Writeable for ClaimableHTLC { (6, self.cltv_expiry, required), (8, keysend_preimage, option), (10, self.counterparty_skimmed_fee_msat, option), - (11, payment_context, option), }); Ok(()) } @@ -10849,7 +10870,6 @@ impl Readable for ClaimableHTLC { (6, cltv_expiry, required), (8, keysend_preimage, option), (10, counterparty_skimmed_fee_msat, option), - (11, payment_context, option), }); let payment_data: Option = payment_data_opt; let value = value_ser.0.unwrap(); @@ -10870,7 +10890,7 @@ impl Readable for ClaimableHTLC { } total_msat = Some(payment_data.as_ref().unwrap().total_msat); } - OnionPayload::Invoice { _legacy_hop_data: payment_data, payment_context } + OnionPayload::Invoice { _legacy_hop_data: payment_data } }, }; Ok(Self { @@ -11495,7 +11515,7 @@ where let mut channel: Channel = Channel::read(reader, ( &args.entropy_source, &args.signer_provider, best_block_height, &provided_channel_type_features(&args.default_config) ))?; - let logger = WithChannelContext::from(&args.logger, &channel.context); + let logger = WithChannelContext::from(&args.logger, &channel.context, None); let funding_txo = channel.context.get_funding_txo().ok_or(DecodeError::InvalidValue)?; funding_txo_to_channel_id.insert(funding_txo, channel.context.channel_id()); funding_txo_set.insert(funding_txo.clone()); @@ -11554,6 +11574,7 @@ where // claim update ChannelMonitor updates were persisted prior to persising // the ChannelMonitor update for the forward leg, so attempting to fail the // backwards leg of the HTLC will simply be rejected. + let logger = WithChannelContext::from(&args.logger, &channel.context, Some(*payment_hash)); log_info!(logger, "Failing HTLC with hash {} as it is missing in the ChannelMonitor for channel {} but was present in the (stale) ChannelManager", &channel.context.channel_id(), &payment_hash); @@ -11608,7 +11629,7 @@ where for (funding_txo, monitor) in args.channel_monitors.iter() { if !funding_txo_set.contains(funding_txo) { - let logger = WithChannelMonitor::from(&args.logger, monitor); + let logger = WithChannelMonitor::from(&args.logger, monitor, None); let channel_id = monitor.channel_id(); log_info!(logger, "Queueing monitor update to ensure missing channel {} is force closed", &channel_id); @@ -11831,7 +11852,7 @@ where let peer_state = &mut *peer_state_lock; for phase in peer_state.channel_by_id.values() { if let ChannelPhase::Funded(chan) = phase { - let logger = WithChannelContext::from(&args.logger, &chan.context); + let logger = WithChannelContext::from(&args.logger, &chan.context, None); // Channels that were persisted have to be funded, otherwise they should have been // discarded. @@ -11870,7 +11891,7 @@ where if let Some(in_flight_upds) = in_flight_monitor_updates { for ((counterparty_id, funding_txo), mut chan_in_flight_updates) in in_flight_upds { let channel_id = funding_txo_to_channel_id.get(&funding_txo).copied(); - let logger = WithContext::from(&args.logger, Some(counterparty_id), channel_id); + let logger = WithContext::from(&args.logger, Some(counterparty_id), channel_id, None); if let Some(monitor) = args.channel_monitors.get(&funding_txo) { // Now that we've removed all the in-flight monitor updates for channels that are // still open, we need to replay any monitor updates that are for closed channels, @@ -11915,8 +11936,8 @@ where for (_, monitor) in args.channel_monitors.iter() { let counterparty_opt = outpoint_to_peer.get(&monitor.get_funding_txo().0); if counterparty_opt.is_none() { - let logger = WithChannelMonitor::from(&args.logger, monitor); for (htlc_source, (htlc, _)) in monitor.get_pending_or_resolved_outbound_htlcs() { + let logger = WithChannelMonitor::from(&args.logger, monitor, Some(htlc.payment_hash)); if let HTLCSource::OutboundRoute { payment_id, session_priv, path, .. } = htlc_source { if path.hops.is_empty() { log_error!(logger, "Got an empty path for a pending payment"); @@ -11957,6 +11978,7 @@ where } } for (htlc_source, (htlc, preimage_opt)) in monitor.get_all_current_outbound_htlcs() { + let logger = WithChannelMonitor::from(&args.logger, monitor, Some(htlc.payment_hash)); match htlc_source { HTLCSource::PreviousHopData(prev_hop_data) => { let pending_forward_matches_htlc = |info: &PendingAddHTLCInfo| { @@ -12108,7 +12130,7 @@ where return Err(DecodeError::InvalidValue); } let purpose = match &htlcs[0].onion_payload { - OnionPayload::Invoice { _legacy_hop_data, payment_context: _ } => { + OnionPayload::Invoice { _legacy_hop_data } => { if let Some(hop_data) = _legacy_hop_data { events::PaymentPurpose::Bolt11InvoicePayment { payment_preimage: match pending_inbound_payments.get(&payment_hash) { @@ -12154,7 +12176,7 @@ where let peer_state = &mut *peer_state_lock; for (chan_id, phase) in peer_state.channel_by_id.iter_mut() { if let ChannelPhase::Funded(chan) = phase { - let logger = WithChannelContext::from(&args.logger, &chan.context); + let logger = WithChannelContext::from(&args.logger, &chan.context, None); if chan.context.outbound_scid_alias() == 0 { let mut outbound_scid_alias; loop { @@ -12224,7 +12246,7 @@ where let mut peer_state_lock = peer_state_mutex.lock().unwrap(); let peer_state = &mut *peer_state_lock; if let Some(ChannelPhase::Funded(channel)) = peer_state.channel_by_id.get_mut(&previous_channel_id) { - let logger = WithChannelContext::from(&args.logger, &channel.context); + let logger = WithChannelContext::from(&args.logger, &channel.context, Some(payment_hash)); channel.claim_htlc_while_disconnected_dropping_mon_update(claimable_htlc.prev_hop.htlc_id, payment_preimage, &&logger); } } @@ -12247,7 +12269,7 @@ where for (node_id, monitor_update_blocked_actions) in monitor_update_blocked_actions_per_peer.unwrap() { if let Some(peer_state) = per_peer_state.get(&node_id) { for (channel_id, actions) in monitor_update_blocked_actions.iter() { - let logger = WithContext::from(&args.logger, Some(node_id), Some(*channel_id)); + let logger = WithContext::from(&args.logger, Some(node_id), Some(*channel_id), None); for action in actions.iter() { if let MonitorUpdateCompletionAction::EmitEventAndFreeOtherChannel { downstream_counterparty_and_funding_outpoint: @@ -12275,7 +12297,7 @@ where } peer_state.lock().unwrap().monitor_update_blocked_actions = monitor_update_blocked_actions; } else { - log_error!(WithContext::from(&args.logger, Some(node_id), None), "Got blocked actions without a per-peer-state for {}", node_id); + log_error!(WithContext::from(&args.logger, Some(node_id), None, None), "Got blocked actions without a per-peer-state for {}", node_id); return Err(DecodeError::InvalidValue); } } @@ -12365,8 +12387,7 @@ mod tests { use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey}; use core::sync::atomic::Ordering; use crate::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, ClosureReason}; - use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret}; - use crate::ln::ChannelId; + use crate::ln::types::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret}; use crate::ln::channelmanager::{create_recv_pending_htlc_info, HTLCForwardInfo, inbound_payment, PaymentId, PaymentSendFailure, RecipientOnionFields, InterceptId}; use crate::ln::functional_test_utils::*; use crate::ln::msgs::{self, ErrorAction};