use crate::ln::msgs::{self, OnionMessage, OnionMessageHandler, SocketAddress};
use crate::ln::onion_utils;
use crate::routing::gossip::{NetworkGraph, NodeId, ReadOnlyNetworkGraph};
+use super::async_payments::AsyncPaymentsMessageHandler;
+#[cfg(async_payments)]
+use super::async_payments::AsyncPaymentsMessage;
use super::packet::OnionMessageContents;
use super::packet::ParsedOnionMessageContents;
use super::offers::OffersMessageHandler;
type OffersMessageHandler: OffersMessageHandler + ?Sized;
/// A type that may be dereferenced to [`Self::OffersMessageHandler`]
type OMH: Deref<Target = Self::OffersMessageHandler>;
+ /// A type implementing [`AsyncPaymentsMessageHandler`]
+ type AsyncPaymentsMessageHandler: AsyncPaymentsMessageHandler + ?Sized;
+ /// A type that may be dereferenced to [`Self::AsyncPaymentsMessageHandler`]
+ type APH: Deref<Target = Self::AsyncPaymentsMessageHandler>;
/// A type implementing [`CustomOnionMessageHandler`]
type CustomOnionMessageHandler: CustomOnionMessageHandler + ?Sized;
/// A type that may be dereferenced to [`Self::CustomOnionMessageHandler`]
type CMH: Deref<Target = Self::CustomOnionMessageHandler>;
/// Returns a reference to the actual [`OnionMessenger`] object.
- fn get_om(&self) -> &OnionMessenger<Self::ES, Self::NS, Self::L, Self::NL, Self::MR, Self::OMH, Self::CMH>;
+ fn get_om(&self) -> &OnionMessenger<Self::ES, Self::NS, Self::L, Self::NL, Self::MR, Self::OMH, Self::APH, Self::CMH>;
}
-impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, CMH: Deref> AOnionMessenger
-for OnionMessenger<ES, NS, L, NL, MR, OMH, CMH> where
+impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, APH: Deref, CMH: Deref> AOnionMessenger
+for OnionMessenger<ES, NS, L, NL, MR, OMH, APH, CMH> where
ES::Target: EntropySource,
NS::Target: NodeSigner,
L::Target: Logger,
NL::Target: NodeIdLookUp,
MR::Target: MessageRouter,
OMH::Target: OffersMessageHandler,
+ APH:: Target: AsyncPaymentsMessageHandler,
CMH::Target: CustomOnionMessageHandler,
{
type EntropySource = ES::Target;
type MR = MR;
type OffersMessageHandler = OMH::Target;
type OMH = OMH;
+ type AsyncPaymentsMessageHandler = APH::Target;
+ type APH = APH;
type CustomOnionMessageHandler = CMH::Target;
type CMH = CMH;
- fn get_om(&self) -> &OnionMessenger<ES, NS, L, NL, MR, OMH, CMH> { self }
+ fn get_om(&self) -> &OnionMessenger<ES, NS, L, NL, MR, OMH, APH, CMH> { self }
}
/// A sender, receiver and forwarder of [`OnionMessage`]s.
/// # let message_router = Arc::new(FakeMessageRouter {});
/// # let custom_message_handler = IgnoringMessageHandler {};
/// # let offers_message_handler = IgnoringMessageHandler {};
+/// # let async_payments_message_handler = IgnoringMessageHandler {};
/// // Create the onion messenger. This must use the same `keys_manager` as is passed to your
/// // ChannelManager.
/// let onion_messenger = OnionMessenger::new(
/// &keys_manager, &keys_manager, logger, &node_id_lookup, message_router,
-/// &offers_message_handler, &custom_message_handler
+/// &offers_message_handler, &async_payments_message_handler, &custom_message_handler
/// );
/// # #[derive(Debug)]
///
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
-pub struct OnionMessenger<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, CMH: Deref>
-where
+pub struct OnionMessenger<
+ ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, APH: Deref, CMH: Deref
+> where
ES::Target: EntropySource,
NS::Target: NodeSigner,
L::Target: Logger,
NL::Target: NodeIdLookUp,
MR::Target: MessageRouter,
OMH::Target: OffersMessageHandler,
+ APH::Target: AsyncPaymentsMessageHandler,
CMH::Target: CustomOnionMessageHandler,
{
entropy_source: ES,
node_id_lookup: NL,
message_router: MR,
offers_handler: OMH,
+ #[allow(unused)]
+ async_payments_handler: APH,
custom_handler: CMH,
intercept_messages_for_offline_peers: bool,
pending_events: Mutex<PendingEvents>,
/// The `Responder` struct creates an appropriate [`ResponseInstruction`]
/// for responding to a message.
+#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Responder {
/// The path along which a response can be sent.
reply_path: BlindedPath,
path_id: Option<[u8; 32]>
}
+impl_writeable_tlv_based!(Responder, {
+ (0, reply_path, required),
+ (2, path_id, option),
+});
+
impl Responder {
/// Creates a new [`Responder`] instance with the provided reply path.
pub(super) fn new(reply_path: BlindedPath, path_id: Option<[u8; 32]>) -> Self {
}
fn create_blinded_paths_from_iter<
- I: Iterator<Item = ForwardNode>,
+ I: ExactSizeIterator<Item = ForwardNode>,
T: secp256k1::Signing + secp256k1::Verification
>(
&self, recipient: PublicKey, peers: I, secp_ctx: &Secp256k1<T>, compact_paths: bool
let is_recipient_announced =
network_graph.nodes().contains_key(&NodeId::from_pubkey(&recipient));
+ let has_one_peer = peers.len() == 1;
let mut peer_info = peers
- // Limit to peers with announced channels
+ // Limit to peers with announced channels unless the recipient is unannounced.
.filter_map(|peer|
network_graph
.node(&NodeId::from_pubkey(&peer.node_id))
- .filter(|info| info.channels.len() >= MIN_PEER_CHANNELS)
+ .filter(|info|
+ !is_recipient_announced || info.channels.len() >= MIN_PEER_CHANNELS
+ )
.map(|info| (peer, info.is_tor_only(), info.channels.len()))
+ // Allow messages directly with the only peer when unannounced.
+ .or_else(|| (!is_recipient_announced && has_one_peer)
+ .then(|| (peer, false, 0))
+ )
)
// Exclude Tor-only nodes when the recipient is announced.
.filter(|(_, is_tor_only, _)| !(*is_tor_only && is_recipient_announced))
}
}
-impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, CMH: Deref>
-OnionMessenger<ES, NS, L, NL, MR, OMH, CMH>
+impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, APH: Deref, CMH: Deref>
+OnionMessenger<ES, NS, L, NL, MR, OMH, APH, CMH>
where
ES::Target: EntropySource,
NS::Target: NodeSigner,
NL::Target: NodeIdLookUp,
MR::Target: MessageRouter,
OMH::Target: OffersMessageHandler,
+ APH::Target: AsyncPaymentsMessageHandler,
CMH::Target: CustomOnionMessageHandler,
{
/// Constructs a new `OnionMessenger` to send, forward, and delegate received onion messages to
/// their respective handlers.
pub fn new(
entropy_source: ES, node_signer: NS, logger: L, node_id_lookup: NL, message_router: MR,
- offers_handler: OMH, custom_handler: CMH
+ offers_handler: OMH, async_payments_handler: APH, custom_handler: CMH
) -> Self {
Self::new_inner(
entropy_source, node_signer, logger, node_id_lookup, message_router,
- offers_handler, custom_handler, false
+ offers_handler, async_payments_handler, custom_handler, false
)
}
/// peers.
pub fn new_with_offline_peer_interception(
entropy_source: ES, node_signer: NS, logger: L, node_id_lookup: NL,
- message_router: MR, offers_handler: OMH, custom_handler: CMH
+ message_router: MR, offers_handler: OMH, async_payments_handler: APH, custom_handler: CMH
) -> Self {
Self::new_inner(
entropy_source, node_signer, logger, node_id_lookup, message_router,
- offers_handler, custom_handler, true
+ offers_handler, async_payments_handler, custom_handler, true
)
}
fn new_inner(
entropy_source: ES, node_signer: NS, logger: L, node_id_lookup: NL,
- message_router: MR, offers_handler: OMH, custom_handler: CMH,
+ message_router: MR, offers_handler: OMH, async_payments_handler: APH, custom_handler: CMH,
intercept_messages_for_offline_peers: bool
) -> Self {
let mut secp_ctx = Secp256k1::new();
node_id_lookup,
message_router,
offers_handler,
+ async_payments_handler,
custom_handler,
intercept_messages_for_offline_peers,
pending_events: Mutex::new(PendingEvents {
false
}
-impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, CMH: Deref> EventsProvider
-for OnionMessenger<ES, NS, L, NL, MR, OMH, CMH>
+impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, APH: Deref, CMH: Deref> EventsProvider
+for OnionMessenger<ES, NS, L, NL, MR, OMH, APH, CMH>
where
ES::Target: EntropySource,
NS::Target: NodeSigner,
NL::Target: NodeIdLookUp,
MR::Target: MessageRouter,
OMH::Target: OffersMessageHandler,
+ APH::Target: AsyncPaymentsMessageHandler,
CMH::Target: CustomOnionMessageHandler,
{
fn process_pending_events<H: Deref>(&self, handler: H) where H::Target: EventHandler {
}
}
-impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, CMH: Deref> OnionMessageHandler
-for OnionMessenger<ES, NS, L, NL, MR, OMH, CMH>
+impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, APH: Deref, CMH: Deref> OnionMessageHandler
+for OnionMessenger<ES, NS, L, NL, MR, OMH, APH, CMH>
where
ES::Target: EntropySource,
NS::Target: NodeSigner,
NL::Target: NodeIdLookUp,
MR::Target: MessageRouter,
OMH::Target: OffersMessageHandler,
+ APH::Target: AsyncPaymentsMessageHandler,
CMH::Target: CustomOnionMessageHandler,
{
fn handle_onion_message(&self, peer_node_id: &PublicKey, msg: &OnionMessage) {
"Received an onion message with path_id {:02x?} and {} reply_path: {:?}",
path_id, if reply_path.is_some() { "a" } else { "no" }, message);
+ let responder = reply_path.map(
+ |reply_path| Responder::new(reply_path, path_id)
+ );
match message {
ParsedOnionMessageContents::Offers(msg) => {
- let responder = reply_path.map(
- |reply_path| Responder::new(reply_path, path_id)
- );
let response_instructions = self.offers_handler.handle_message(msg, responder);
let _ = self.handle_onion_message_response(response_instructions);
},
- ParsedOnionMessageContents::Custom(msg) => {
- let responder = reply_path.map(
- |reply_path| Responder::new(reply_path, path_id)
+ #[cfg(async_payments)]
+ ParsedOnionMessageContents::AsyncPayments(AsyncPaymentsMessage::HeldHtlcAvailable(msg)) => {
+ let response_instructions = self.async_payments_handler.held_htlc_available(
+ msg, responder
);
+ let _ = self.handle_onion_message_response(response_instructions);
+ },
+ #[cfg(async_payments)]
+ ParsedOnionMessageContents::AsyncPayments(AsyncPaymentsMessage::ReleaseHeldHtlc(msg)) => {
+ self.async_payments_handler.release_held_htlc(msg);
+ },
+ ParsedOnionMessageContents::Custom(msg) => {
let response_instructions = self.custom_handler.handle_custom_message(msg, responder);
let _ = self.handle_onion_message_response(response_instructions);
},
Arc<SimpleArcChannelManager<M, T, F, L>>,
Arc<DefaultMessageRouter<Arc<NetworkGraph<Arc<L>>>, Arc<L>, Arc<KeysManager>>>,
Arc<SimpleArcChannelManager<M, T, F, L>>,
+ Arc<SimpleArcChannelManager<M, T, F, L>>,
IgnoringMessageHandler
>;
&'i SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, M, T, F, L>,
&'j DefaultMessageRouter<&'g NetworkGraph<&'b L>, &'b L, &'a KeysManager>,
&'i SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, M, T, F, L>,
+ &'i SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, M, T, F, L>,
IgnoringMessageHandler
>;