Skip to content

Commit f13c512

Browse files
committed
onion_message: generalize get_blinded_reply_paths to get_blinded_paths_to_me
1 parent 8a437a9 commit f13c512

File tree

1 file changed

+44
-18
lines changed

1 file changed

+44
-18
lines changed

electrum/onion_message.py

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ def now():
5959

6060

6161
REQUEST_REPLY_PATHS_MAX = 3
62+
PAYMENT_PATHS_MAX = 3
6263

6364

6465
class NoRouteFound(Exception):
@@ -364,33 +365,53 @@ def get_blinded_reply_paths(
364365
max_paths: int = REQUEST_REPLY_PATHS_MAX,
365366
preferred_node_id: bytes = None
366367
) -> Sequence[dict]:
367-
"""construct a list of blinded reply_paths.
368+
"""construct a list of blinded reply-paths for onion message.
369+
"""
370+
mydata = {'path_id': {'data': path_id}} # same path_id used in every reply path
371+
return get_blinded_paths_to_me(lnwallet, mydata, max_paths=max_paths,
372+
preferred_node_id=preferred_node_id, onion_message=True)
373+
374+
375+
def get_blinded_paths_to_me(
376+
lnwallet: 'LNWallet',
377+
final_recipient_data: dict = {},
378+
*,
379+
max_paths: int = PAYMENT_PATHS_MAX,
380+
preferred_node_id: bytes = None,
381+
onion_message: bool = False
382+
) -> Sequence[dict]:
383+
"""construct a list of blinded paths.
368384
current logic:
369-
- uses current onion_message capable channel peers if exist
370-
- otherwise, uses current onion_message capable peers
385+
- uses channels peers if not onion_message
386+
- uses current onion_message capable channel peers if exist and if onion_message
387+
- otherwise, uses current onion_message capable peers if onion_message
371388
- prefers preferred_node_id if given
372-
- reply_path introduction points are direct peers only (TODO: longer reply paths)"""
389+
- reply_path introduction points are direct peers only (TODO: longer paths)"""
373390
# TODO: build longer paths and/or add dummy hops to increase privacy
374391
my_active_channels = [chan for chan in lnwallet.channels.values() if chan.is_active()]
375-
my_onionmsg_channels = [chan for chan in my_active_channels if lnwallet.peers.get(chan.node_id) and
376-
lnwallet.peers.get(chan.node_id).their_features.supports(LnFeatures.OPTION_ONION_MESSAGE_OPT)]
377-
my_onionmsg_peers = [peer for peer in lnwallet.peers.values() if peer.their_features.supports(LnFeatures.OPTION_ONION_MESSAGE_OPT)]
392+
my_channels = my_active_channels
393+
if onion_message:
394+
my_channels = [chan for chan in my_active_channels if lnwallet.peers.get(chan.node_id) and
395+
lnwallet.peers.get(chan.node_id).their_features.supports(LnFeatures.OPTION_ONION_MESSAGE_OPT)]
378396

379397
result = []
380398
mynodeid = lnwallet.node_keypair.pubkey
381-
mydata = {'path_id': {'data': path_id}} # same path_id used in every reply path
382-
if len(my_onionmsg_channels):
399+
if len(my_channels):
383400
# randomize list, but prefer preferred_node_id
384-
rchans = sorted(my_onionmsg_channels, key=lambda x: random() if x.node_id != preferred_node_id else 0)
401+
rchans = sorted(my_channels, key=lambda x: random() if x.node_id != preferred_node_id else 0)
385402
for chan in rchans[:max_paths]:
386-
blinded_path = create_blinded_path(os.urandom(32), [chan.node_id, mynodeid], mydata)
387-
result.append(blinded_path)
388-
elif len(my_onionmsg_peers):
389-
# randomize list, but prefer preferred_node_id
390-
rpeers = sorted(my_onionmsg_peers, key=lambda x: random() if x.pubkey != preferred_node_id else 0)
391-
for peer in rpeers[:max_paths]:
392-
blinded_path = create_blinded_path(os.urandom(32), [peer.pubkey, mynodeid], mydata)
403+
blinded_path = create_blinded_path(os.urandom(32), [chan.node_id, mynodeid], final_recipient_data)
393404
result.append(blinded_path)
405+
elif onion_message:
406+
# we can use peers even without channels for onion messages
407+
my_onionmsg_peers = [peer for peer in lnwallet.peers.values() if
408+
peer.their_features.supports(LnFeatures.OPTION_ONION_MESSAGE_OPT)]
409+
if len(my_onionmsg_peers):
410+
# randomize list, but prefer preferred_node_id
411+
rpeers = sorted(my_onionmsg_peers, key=lambda x: random() if x.pubkey != preferred_node_id else 0)
412+
for peer in rpeers[:max_paths]:
413+
blinded_path = create_blinded_path(os.urandom(32), [peer.pubkey, mynodeid], final_recipient_data)
414+
result.append(blinded_path)
394415

395416
return result
396417

@@ -645,10 +666,15 @@ def on_onion_message_received_unsolicited(self, recipient_data: dict, payload: d
645666
# e.g. via a decorator, something like
646667
# @onion_message_request_handler(payload_key='invoice_request') for BOLT12 invoice requests.
647668

648-
if 'message' not in payload:
669+
if 'message' not in payload and 'invoice_request' not in payload:
649670
self.logger.error('Unsupported onion message payload')
650671
return
651672

673+
if 'invoice_request' in payload:
674+
self.lnwallet.on_bolt12_invoice_request(recipient_data, payload)
675+
return
676+
677+
# log 'message' payload
652678
if 'text' not in payload['message'] or not isinstance(payload['message']['text'], bytes):
653679
self.logger.error('Malformed \'message\' payload')
654680
return

0 commit comments

Comments
 (0)