diff --git a/electrum/commands.py b/electrum/commands.py index 3542e6b67..1d002ec89 100644 --- a/electrum/commands.py +++ b/electrum/commands.py @@ -1077,8 +1077,7 @@ class Commands: @command('wn') async def enable_htlc_settle(self, b: bool, wallet: Abstract_Wallet = None): - e = wallet.lnworker.enable_htlc_settle - e.set() if b else e.clear() + wallet.lnworker.enable_htlc_settle = b @command('n') async def clear_ln_blacklist(self): diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py index d392e6a45..42a07ea19 100644 --- a/electrum/lnpeer.py +++ b/electrum/lnpeer.py @@ -1828,7 +1828,7 @@ class Peer(Logger): error_reason = e else: try: - preimage, fw_info, error_bytes = await self.process_unfulfilled_htlc( + preimage, fw_info, error_bytes = self.process_unfulfilled_htlc( chan=chan, htlc=htlc, forwarding_info=forwarding_info, @@ -1840,7 +1840,8 @@ class Peer(Logger): unfulfilled[htlc_id] = local_ctn, remote_ctn, onion_packet_hex, fw_info elif preimage or error_reason or error_bytes: if preimage: - await self.lnworker.enable_htlc_settle.wait() + if not self.lnworker.enable_htlc_settle: + continue self.fulfill_htlc(chan, htlc.htlc_id, preimage) elif error_bytes: self.fail_htlc( @@ -1880,7 +1881,7 @@ class Peer(Logger): await group.spawn(htlc_switch_iteration()) await group.spawn(self.got_disconnected.wait()) - async def process_unfulfilled_htlc( + def process_unfulfilled_htlc( self, *, chan: Channel, htlc: UpdateAddHtlc, @@ -1919,7 +1920,8 @@ class Peer(Logger): is_trampoline=True) else: # trampoline- HTLC we are supposed to forward, but haven't forwarded yet - await self.lnworker.enable_htlc_forwarding.wait() + if not self.lnworker.enable_htlc_forwarding: + return None, None, None self.maybe_forward_trampoline( chan=chan, htlc=htlc, @@ -1936,7 +1938,8 @@ class Peer(Logger): elif not forwarding_info: # HTLC we are supposed to forward, but haven't forwarded yet - await self.lnworker.enable_htlc_forwarding.wait() + if not self.lnworker.enable_htlc_forwarding: + return None, None, None next_chan_id, next_htlc_id = self.maybe_forward_htlc( htlc=htlc, processed_onion=processed_onion) diff --git a/electrum/lnworker.py b/electrum/lnworker.py index 933e5ae68..a7c58c5b1 100644 --- a/electrum/lnworker.py +++ b/electrum/lnworker.py @@ -602,10 +602,8 @@ class LNWallet(LNWorker): self.sweep_address = wallet.get_new_sweep_address_for_channel() self.logs = defaultdict(list) # type: Dict[str, List[HtlcLog]] # key is RHASH # (not persisted) # used in tests - self.enable_htlc_settle = asyncio.Event() - self.enable_htlc_settle.set() - self.enable_htlc_forwarding = asyncio.Event() - self.enable_htlc_forwarding.set() + self.enable_htlc_settle = True + self.enable_htlc_forwarding = True # note: accessing channels (besides simple lookup) needs self.lock! self._channels = {} # type: Dict[bytes, Channel] diff --git a/electrum/tests/test_lnpeer.py b/electrum/tests/test_lnpeer.py index 724a386bf..cfe54323c 100644 --- a/electrum/tests/test_lnpeer.py +++ b/electrum/tests/test_lnpeer.py @@ -140,10 +140,8 @@ class MockLNWallet(Logger, NetworkRetryManager[LNPeerAddr]): chan.lnworker = self self._peers = {} # bytes -> Peer # used in tests - self.enable_htlc_settle = asyncio.Event() - self.enable_htlc_settle.set() - self.enable_htlc_forwarding = asyncio.Event() - self.enable_htlc_forwarding.set() + self.enable_htlc_settle = True + self.enable_htlc_forwarding = True self.received_mpp_htlcs = dict() self.sent_htlcs = defaultdict(asyncio.Queue) self.sent_htlcs_routes = dict() @@ -790,7 +788,7 @@ class TestPeer(TestCaseForTestnet): if mpp_invoice: graph.w_d.features |= LnFeatures.BASIC_MPP_OPT if not bob_forwarding: - graph.w_b.enable_htlc_forwarding.clear() + graph.w_b.enable_htlc_forwarding = False if alice_uses_trampoline: if graph.w_a.network.channel_db: graph.w_a.network.channel_db.stop() @@ -803,7 +801,7 @@ class TestPeer(TestCaseForTestnet): result, log = await graph.w_a.pay_invoice(pay_req, attempts=attempts) if not bob_forwarding: # reset to previous state, sleep 2s so that the second htlc can time out - graph.w_b.enable_htlc_forwarding.set() + graph.w_b.enable_htlc_forwarding = True await asyncio.sleep(2) if result: self.assertEqual(PR_PAID, graph.w_d.get_payment_status(lnaddr.paymenthash)) @@ -855,7 +853,7 @@ class TestPeer(TestCaseForTestnet): graph.w_d.TIMEOUT_SHUTDOWN_FAIL_PENDING_HTLCS = 3 async def pay(): graph.w_d.features |= LnFeatures.BASIC_MPP_OPT - graph.w_b.enable_htlc_forwarding.clear() # Bob will hold forwarded HTLCs + graph.w_b.enable_htlc_forwarding = False # Bob will hold forwarded HTLCs assert graph.w_a.network.channel_db is not None lnaddr, pay_req = await self.prepare_invoice(graph.w_d, include_routing_hints=True, amount_msat=amount_to_pay) try: @@ -892,7 +890,7 @@ class TestPeer(TestCaseForTestnet): w2.network.config.set_key('dynamic_fees', False) w1.network.config.set_key('fee_per_kb', 5000) w2.network.config.set_key('fee_per_kb', 1000) - w2.enable_htlc_settle.clear() + w2.enable_htlc_settle = False lnaddr, pay_req = run(self.prepare_invoice(w2)) async def pay(): await asyncio.wait_for(p1.initialized, 1) @@ -911,7 +909,7 @@ class TestPeer(TestCaseForTestnet): gath.cancel() async def set_settle(): await asyncio.sleep(0.1) - w2.enable_htlc_settle.set() + w2.enable_htlc_settle = True gath = asyncio.gather(pay(), set_settle(), p1._message_loop(), p2._message_loop(), p1.htlc_switch(), p2.htlc_switch()) async def f(): await gath