Skip to content

Commit d78d640

Browse files
committed
Introduce NodeIdMessageRouter and NullMessageRouter
To make the purpose of each `MessageRouter` implementation unambiguous, this commit sets a direction where the type of `MessageRouter` used deterministically defines the kind of blinded paths created. As a step toward this goal, two new default routers are introduced: - `NodeIdMessageRouter` – creates full-length blinded paths using the peer's node ID. - `NullMessageRouter` – intentionally creates no blinded paths.
1 parent d6099c3 commit d78d640

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

lightning/src/onion_message/messenger.rs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,120 @@ where
735735
}
736736
}
737737

738+
/// This message router is similar to [`DefaultMessageRouter`], but it always creates
739+
/// full-length blinded paths, using the peer's [`NodeId`].
740+
///
741+
/// This message router can only route to a directly connected [`Destination`].
742+
///
743+
/// # Privacy
744+
///
745+
/// Creating [`BlindedMessagePath`]s may affect privacy since, if a suitable path cannot be found,
746+
/// it will create a one-hop path using the recipient as the introduction node if it is an announced
747+
/// node. Otherwise, there is no way to find a path to the introduction node in order to send a
748+
/// message, and thus an `Err` is returned.
749+
pub struct NodeIdMessageRouter<G: Deref<Target = NetworkGraph<L>>, L: Deref, ES: Deref>
750+
where
751+
L::Target: Logger,
752+
ES::Target: EntropySource,
753+
{
754+
network_graph: G,
755+
entropy_source: ES,
756+
}
757+
758+
impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, ES: Deref> NodeIdMessageRouter<G, L, ES>
759+
where
760+
L::Target: Logger,
761+
ES::Target: EntropySource,
762+
{
763+
/// Creates a [`NodeIdMessageRouter`] using the given [`NetworkGraph`].
764+
pub fn new(network_graph: G, entropy_source: ES) -> Self {
765+
Self { network_graph, entropy_source }
766+
}
767+
}
768+
769+
impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, ES: Deref> MessageRouter
770+
for NodeIdMessageRouter<G, L, ES>
771+
where
772+
L::Target: Logger,
773+
ES::Target: EntropySource,
774+
{
775+
fn find_path(
776+
&self, sender: PublicKey, peers: Vec<PublicKey>, destination: Destination,
777+
) -> Result<OnionMessagePath, ()> {
778+
DefaultMessageRouter::<G, L, ES>::find_path(&self.network_graph, sender, peers, destination)
779+
}
780+
781+
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
782+
&self, recipient: PublicKey, local_node_receive_key: ReceiveAuthKey,
783+
context: MessageContext, peers: Vec<MessageForwardNode>, secp_ctx: &Secp256k1<T>,
784+
) -> Result<Vec<BlindedMessagePath>, ()> {
785+
DefaultMessageRouter::create_blinded_paths_from_iter(
786+
&self.network_graph,
787+
recipient,
788+
local_node_receive_key,
789+
context,
790+
peers.into_iter(),
791+
&self.entropy_source,
792+
secp_ctx,
793+
false,
794+
)
795+
}
796+
797+
fn create_compact_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
798+
&self, recipient: PublicKey, local_node_receive_key: ReceiveAuthKey,
799+
context: MessageContext, peers: Vec<MessageForwardNode>, secp_ctx: &Secp256k1<T>,
800+
) -> Result<Vec<BlindedMessagePath>, ()> {
801+
DefaultMessageRouter::create_blinded_paths_from_iter(
802+
&self.network_graph,
803+
recipient,
804+
local_node_receive_key,
805+
context,
806+
peers.into_iter(),
807+
&self.entropy_source,
808+
secp_ctx,
809+
false,
810+
)
811+
}
812+
}
813+
814+
/// A special [`MessageRouter`] that performs no routing and does not create blinded paths.
815+
/// Its purpose is to enable the creation of [`Offer`]s and [`Refund`]s without blinded paths,
816+
/// where the user's `node_id` is used directly as the [`Destination`].
817+
///
818+
/// # Note
819+
/// [`NullMessageRouter`] **must not** be used as the type parameter for [`ChannelManager`],
820+
/// since [`ChannelManager`] requires a functioning [`MessageRouter`] to create blinded paths,
821+
/// which are necessary for constructing reply paths in onion message communication.
822+
/// However, [`NullMessageRouter`] *can* still be passed as an argument to [`ChannelManager`]
823+
/// methods that accept a router when blinded paths are not needed.
824+
///
825+
/// [`Offer`]: crate::offers::offer::Offer
826+
/// [`Refund`]: crate::offers::refund::Refund
827+
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
828+
pub struct NullMessageRouter {}
829+
830+
impl MessageRouter for NullMessageRouter {
831+
fn find_path(
832+
&self, _sender: PublicKey, _peers: Vec<PublicKey>, _destination: Destination,
833+
) -> Result<OnionMessagePath, ()> {
834+
Err(())
835+
}
836+
837+
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
838+
&self, _recipient: PublicKey, _local_node_receive_key: ReceiveAuthKey,
839+
_context: MessageContext, _peers: Vec<MessageForwardNode>, _secp_ctx: &Secp256k1<T>,
840+
) -> Result<Vec<BlindedMessagePath>, ()> {
841+
Ok(vec![])
842+
}
843+
844+
fn create_compact_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
845+
&self, _recipient: PublicKey, _local_node_receive_key: ReceiveAuthKey,
846+
_context: MessageContext, _peers: Vec<MessageForwardNode>, _secp_ctx: &Secp256k1<T>,
847+
) -> Result<Vec<BlindedMessagePath>, ()> {
848+
Ok(vec![])
849+
}
850+
}
851+
738852
/// A path for sending an [`OnionMessage`].
739853
#[derive(Clone)]
740854
pub struct OnionMessagePath {

0 commit comments

Comments
 (0)