@@ -66,6 +66,10 @@ def now() -> float:
6666PAYMENT_PATHS_MAX = 3
6767
6868
69+ class NoOnionMessagePeers (Exception ): pass
70+ class NoRouteBlindingChannelPeers (Exception ): pass
71+
72+
6973class NoRouteFound (Exception ):
7074 def __init__ (self , * args , peer_address : 'LNPeerAddr' = None ):
7175 Exception .__init__ (self , * args )
@@ -413,23 +417,25 @@ def get_blinded_paths_to_me(
413417) -> Tuple [Sequence [dict ], Sequence [dict ]]:
414418 """construct a list of blinded paths.
415419 current logic:
416- - uses channels peers if not onion_message
417- - uses current onion_message capable channel peers if exist and if onion_message
418- - otherwise, uses current onion_message capable peers if onion_message
419- - reply_path introduction points are direct peers only (TODO: longer paths)"""
420+ - uses active channel peers if my_channels not provided
421+ - if onion_message, filters channels for onion_message feature
422+ - if not onion_message, filters channels for route_blinding feature
423+ - if onion_message and no suitable channel peers, tries onion_message capable peers
424+ - raises if no blinded path could be generated
425+ - reply_path introduction points are direct peers only (TODO: longer paths)
426+ """
420427 # TODO: build longer paths and/or add dummy hops to increase privacy
421428 if not my_channels :
422- my_active_channels = [chan for chan in lnwallet .channels .values () if chan .is_active ()]
423- my_channels = my_active_channels
429+ my_channels = [chan for chan in lnwallet .channels .values () if chan .is_active ()]
424430
425- if onion_message :
426- my_channels = [chan for chan in my_channels if lnwallet .lnpeermgr .get_peer_by_pubkey (chan .node_id ) and
427- lnwallet .lnpeermgr .get_peer_by_pubkey (chan .node_id ).their_features .supports (LnFeatures . OPTION_ONION_MESSAGE_OPT )]
431+ required_features = LnFeatures . OPTION_ONION_MESSAGE_OPT if onion_message else LnFeatures . OPTION_ROUTE_BLINDING_OPT
432+ my_channels = [chan for chan in my_channels if lnwallet .lnpeermgr .get_peer_by_pubkey (chan .node_id ) and
433+ lnwallet .lnpeermgr .get_peer_by_pubkey (chan .node_id ).their_features .supports (required_features )]
428434
429435 result = []
430436 payinfos = []
431437 mynodeid = lnwallet .node_keypair .pubkey
432- if len ( my_channels ) :
438+ if my_channels :
433439 rchans = random_shuffled_copy (my_channels )
434440 for chan in rchans [:max_paths ]:
435441 hop_extras = None
@@ -448,16 +454,22 @@ def get_blinded_paths_to_me(
448454 channels = [chan ] if not onion_message else None ,
449455 )
450456 result .append (blinded_path )
451- elif onion_message :
452- # we can use peers even without channels for onion messages
453- my_onionmsg_peers = [peer for peer in lnwallet .lnpeermgr .peers .values () if
454- peer .their_features .supports (LnFeatures .OPTION_ONION_MESSAGE_OPT )]
455- if len (my_onionmsg_peers ):
457+
458+ if not result :
459+ if not onion_message :
460+ raise NoRouteBlindingChannelPeers ('no OPTION_ROUTE_BLINDING capable channel peers' )
461+ else :
462+ # fall back to peers without channels for onion messages
463+ my_onionmsg_peers = [peer for peer in lnwallet .lnpeermgr .peers .values () if
464+ peer .their_features .supports (LnFeatures .OPTION_ONION_MESSAGE_OPT )]
465+ if not my_onionmsg_peers :
466+ raise NoOnionMessagePeers ('no ONION_MESSAGE capable peers' )
456467 rpeers = random_shuffled_copy (my_onionmsg_peers )
457468 for peer in rpeers [:max_paths ]:
458469 blinded_path = create_blinded_path (os .urandom (32 ), [peer .pubkey , mynodeid ], final_recipient_data )
459470 result .append (blinded_path )
460471
472+ assert result
461473 return result , payinfos
462474
463475
@@ -709,9 +721,6 @@ def _send_pending_message(self, key: bytes) -> None:
709721 # unless explicitly set in payload, generate reply_path here
710722 path_id = self ._path_id_from_payload_and_key (payload , key )
711723 reply_paths = get_blinded_reply_paths (self .lnwallet , path_id , max_paths = 1 )
712- if not reply_paths :
713- raise Exception (f'Could not create a reply_path for { key = } . No active peers?' )
714-
715724 final_payload ['reply_path' ] = {'path' : reply_paths }
716725
717726 # NOTE: we could also try alternate paths to introduction point (the non-blinded part of the route)
0 commit comments