Browse Source

rename lnworker._pay to pay_invoice, call it directly from GUIs

patch-4
ThomasV 4 years ago
parent
commit
0c93394513
  1. 2
      electrum/commands.py
  2. 4
      electrum/gui/kivy/uix/screens.py
  3. 5
      electrum/gui/qt/main_window.py
  4. 10
      electrum/lnworker.py
  5. 4
      electrum/submarine_swaps.py
  6. 18
      electrum/tests/test_lnpeer.py

2
electrum/commands.py

@ -1011,7 +1011,7 @@ class Commands:
lnaddr = lnworker._check_invoice(invoice) lnaddr = lnworker._check_invoice(invoice)
payment_hash = lnaddr.paymenthash payment_hash = lnaddr.paymenthash
wallet.save_invoice(LNInvoice.from_bech32(invoice)) wallet.save_invoice(LNInvoice.from_bech32(invoice))
success, log = await lnworker._pay(invoice, attempts=attempts) success, log = await lnworker.pay_invoice(invoice, attempts=attempts)
return { return {
'payment_hash': payment_hash.hex(), 'payment_hash': payment_hash.hex(),
'success': success, 'success': success,

4
electrum/gui/kivy/uix/screens.py

@ -367,7 +367,9 @@ class SendScreen(CScreen, Logger):
def _do_pay_lightning(self, invoice: LNInvoice, pw) -> None: def _do_pay_lightning(self, invoice: LNInvoice, pw) -> None:
def pay_thread(): def pay_thread():
try: try:
self.app.wallet.lnworker.pay(invoice.invoice, attempts=10) coro = self.app.wallet.lnworker.pay_invoice(invoice.invoice, attempts=10)
fut = asyncio.run_coroutine_threadsafe(coro, self.app.network.asyncio_loop)
fut.result()
except Exception as e: except Exception as e:
self.app.show_error(repr(e)) self.app.show_error(repr(e))
self.save_invoice(invoice) self.save_invoice(invoice)

5
electrum/gui/qt/main_window.py

@ -1523,9 +1523,10 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
if not self.question(msg): if not self.question(msg):
return return
self.save_pending_invoice() self.save_pending_invoice()
attempts = LN_NUM_PAYMENT_ATTEMPTS
def task(): def task():
self.wallet.lnworker.pay(invoice, amount_msat=amount_msat, attempts=attempts) coro = self.wallet.lnworker.pay_invoice(invoice, amount_msat=amount_msat, attempts=LN_NUM_PAYMENT_ATTEMPTS)
fut = asyncio.run_coroutine_threadsafe(coro, self.network.asyncio_loop)
return fut.result()
self.wallet.thread.add(task) self.wallet.thread.add(task)
def on_request_status(self, wallet, key, status): def on_request_status(self, wallet, key, status):

10
electrum/lnworker.py

@ -930,21 +930,13 @@ class LNWallet(LNWorker):
return chan, funding_tx return chan, funding_tx
def pay(self, invoice: str, *, amount_msat: int = None, attempts: int = 1) -> Tuple[bool, List[HtlcLog]]:
"""
Can be called from other threads
"""
coro = self._pay(invoice, amount_msat=amount_msat, attempts=attempts)
fut = asyncio.run_coroutine_threadsafe(coro, self.network.asyncio_loop)
return fut.result()
def get_channel_by_short_id(self, short_channel_id: bytes) -> Optional[Channel]: def get_channel_by_short_id(self, short_channel_id: bytes) -> Optional[Channel]:
for chan in self.channels.values(): for chan in self.channels.values():
if chan.short_channel_id == short_channel_id: if chan.short_channel_id == short_channel_id:
return chan return chan
@log_exceptions @log_exceptions
async def _pay( async def pay_invoice(
self, invoice: str, *, self, invoice: str, *,
amount_msat: int = None, amount_msat: int = None,
attempts: int = 1, attempts: int = 1,

4
electrum/submarine_swaps.py

@ -418,9 +418,9 @@ class SwapManager(Logger):
# initiate payment. # initiate payment.
if fee_invoice: if fee_invoice:
self.prepayments[prepay_hash] = preimage_hash self.prepayments[prepay_hash] = preimage_hash
asyncio.ensure_future(self.lnworker._pay(fee_invoice, attempts=10)) asyncio.ensure_future(self.lnworker.pay_invoice(fee_invoice, attempts=10))
# initiate payment. # initiate payment.
success, log = await self.lnworker._pay(invoice, attempts=10) success, log = await self.lnworker.pay_invoice(invoice, attempts=10)
return success return success
async def get_pairs(self) -> None: async def get_pairs(self) -> None:

18
electrum/tests/test_lnpeer.py

@ -178,7 +178,7 @@ class MockLNWallet(Logger, NetworkRetryManager[LNPeerAddr]):
create_routes_from_invoice = LNWallet.create_routes_from_invoice create_routes_from_invoice = LNWallet.create_routes_from_invoice
_check_invoice = staticmethod(LNWallet._check_invoice) _check_invoice = staticmethod(LNWallet._check_invoice)
pay_to_route = LNWallet.pay_to_route pay_to_route = LNWallet.pay_to_route
_pay = LNWallet._pay pay_invoice = LNWallet.pay_invoice
force_close_channel = LNWallet.force_close_channel force_close_channel = LNWallet.force_close_channel
try_force_closing = LNWallet.try_force_closing try_force_closing = LNWallet.try_force_closing
get_first_timestamp = lambda self: 0 get_first_timestamp = lambda self: 0
@ -422,7 +422,7 @@ class TestPeer(ElectrumTestCase):
p1, p2, w1, w2, _q1, _q2 = self.prepare_peers(alice_channel, bob_channel) p1, p2, w1, w2, _q1, _q2 = self.prepare_peers(alice_channel, bob_channel)
pay_req = run(self.prepare_invoice(w2)) pay_req = run(self.prepare_invoice(w2))
async def pay(): async def pay():
result, log = await w1._pay(pay_req) result, log = await w1.pay_invoice(pay_req)
self.assertEqual(result, True) self.assertEqual(result, True)
gath.cancel() gath.cancel()
gath = asyncio.gather(pay(), p1._message_loop(), p2._message_loop(), p1.htlc_switch(), p2.htlc_switch()) gath = asyncio.gather(pay(), p1._message_loop(), p2._message_loop(), p1.htlc_switch(), p2.htlc_switch())
@ -454,7 +454,7 @@ class TestPeer(ElectrumTestCase):
alice_channel, bob_channel = create_test_channels() alice_channel, bob_channel = create_test_channels()
p1, p2, w1, w2, _q1, _q2 = self.prepare_peers(alice_channel, bob_channel) p1, p2, w1, w2, _q1, _q2 = self.prepare_peers(alice_channel, bob_channel)
async def pay(pay_req): async def pay(pay_req):
result, log = await w1._pay(pay_req) result, log = await w1.pay_invoice(pay_req)
self.assertTrue(result) self.assertTrue(result)
raise PaymentDone() raise PaymentDone()
async def f(): async def f():
@ -547,7 +547,7 @@ class TestPeer(ElectrumTestCase):
max_htlcs_in_flight = asyncio.Semaphore(5) max_htlcs_in_flight = asyncio.Semaphore(5)
async def single_payment(pay_req): async def single_payment(pay_req):
async with max_htlcs_in_flight: async with max_htlcs_in_flight:
await w1._pay(pay_req) await w1.pay_invoice(pay_req)
async def many_payments(): async def many_payments():
async with TaskGroup() as group: async with TaskGroup() as group:
pay_reqs_tasks = [await group.spawn(self.prepare_invoice(w2, amount_msat=payment_value_msat)) pay_reqs_tasks = [await group.spawn(self.prepare_invoice(w2, amount_msat=payment_value_msat))
@ -572,7 +572,7 @@ class TestPeer(ElectrumTestCase):
graph = self.prepare_chans_and_peers_in_square() graph = self.prepare_chans_and_peers_in_square()
peers = graph.all_peers() peers = graph.all_peers()
async def pay(pay_req): async def pay(pay_req):
result, log = await graph.w_a._pay(pay_req) result, log = await graph.w_a.pay_invoice(pay_req)
self.assertTrue(result) self.assertTrue(result)
raise PaymentDone() raise PaymentDone()
async def f(): async def f():
@ -595,15 +595,15 @@ class TestPeer(ElectrumTestCase):
path = [PathEdge(node_id=graph.w_c.node_keypair.pubkey, short_channel_id=graph.chan_ab.short_channel_id), path = [PathEdge(node_id=graph.w_c.node_keypair.pubkey, short_channel_id=graph.chan_ab.short_channel_id),
PathEdge(node_id=graph.w_d.node_keypair.pubkey, short_channel_id=graph.chan_bd.short_channel_id)] PathEdge(node_id=graph.w_d.node_keypair.pubkey, short_channel_id=graph.chan_bd.short_channel_id)]
with self.assertRaises(LNPathInconsistent): with self.assertRaises(LNPathInconsistent):
await graph.w_a._pay(pay_req, full_path=path) await graph.w_a.pay_invoice(pay_req, full_path=path)
with self.subTest(msg="bad path: last node id differs from invoice pubkey"): with self.subTest(msg="bad path: last node id differs from invoice pubkey"):
path = [PathEdge(node_id=graph.w_b.node_keypair.pubkey, short_channel_id=graph.chan_ab.short_channel_id)] path = [PathEdge(node_id=graph.w_b.node_keypair.pubkey, short_channel_id=graph.chan_ab.short_channel_id)]
with self.assertRaises(LNPathInconsistent): with self.assertRaises(LNPathInconsistent):
await graph.w_a._pay(pay_req, full_path=path) await graph.w_a.pay_invoice(pay_req, full_path=path)
with self.subTest(msg="good path"): with self.subTest(msg="good path"):
path = [PathEdge(node_id=graph.w_b.node_keypair.pubkey, short_channel_id=graph.chan_ab.short_channel_id), path = [PathEdge(node_id=graph.w_b.node_keypair.pubkey, short_channel_id=graph.chan_ab.short_channel_id),
PathEdge(node_id=graph.w_d.node_keypair.pubkey, short_channel_id=graph.chan_bd.short_channel_id)] PathEdge(node_id=graph.w_d.node_keypair.pubkey, short_channel_id=graph.chan_bd.short_channel_id)]
result, log = await graph.w_a._pay(pay_req, full_path=path) result, log = await graph.w_a.pay_invoice(pay_req, full_path=path)
self.assertTrue(result) self.assertTrue(result)
self.assertEqual( self.assertEqual(
[edge.short_channel_id for edge in path], [edge.short_channel_id for edge in path],
@ -627,7 +627,7 @@ class TestPeer(ElectrumTestCase):
graph.w_c.network.config.set_key('test_fail_htlcs_with_temp_node_failure', True) graph.w_c.network.config.set_key('test_fail_htlcs_with_temp_node_failure', True)
peers = graph.all_peers() peers = graph.all_peers()
async def pay(pay_req): async def pay(pay_req):
result, log = await graph.w_a._pay(pay_req) result, log = await graph.w_a.pay_invoice(pay_req)
self.assertFalse(result) self.assertFalse(result)
self.assertEqual(OnionFailureCode.TEMPORARY_NODE_FAILURE, log[0].failure_msg.code) self.assertEqual(OnionFailureCode.TEMPORARY_NODE_FAILURE, log[0].failure_msg.code)
raise PaymentDone() raise PaymentDone()

Loading…
Cancel
Save