electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 3c0df28c98a275e9eafac409d383dc383c1c5065
parent 0acd0c23d32f43bb91c29cf7e8d1288d40d8cc74
Author: ThomasV <thomasv@electrum.org>
Date:   Sun, 19 May 2019 11:55:55 +0200

do not include 'force_closing' in channel states, because it is not part of the peer protocol

Diffstat:
Melectrum/lnchannel.py | 18+++++++++---------
Melectrum/lnpeer.py | 2+-
Melectrum/lnworker.py | 16+++++++---------
Melectrum/tests/test_lnpeer.py | 2+-
4 files changed, 18 insertions(+), 20 deletions(-)

diff --git a/electrum/lnchannel.py b/electrum/lnchannel.py @@ -145,6 +145,7 @@ class Channel(Logger): self.short_channel_id = bfh(state["short_channel_id"]) if type(state["short_channel_id"]) not in (bytes, type(None)) else state["short_channel_id"] self.short_channel_id_predicted = self.short_channel_id self.onion_keys = str_bytes_dict_from_save(state.get('onion_keys', {})) + self.force_closed = state.get('force_closed') # FIXME this is a tx serialised in the custom electrum partial tx format. # we should not persist txns in this format. we should persist htlcs, and be able to derive @@ -162,11 +163,7 @@ class Channel(Logger): self._is_funding_txo_spent = None # "don't know" self._state = None - if state.get('force_closed', False): - self.set_state('FORCE_CLOSING') - else: - self.set_state('DISCONNECTED') - + self.set_state('DISCONNECTED') self.lnwatcher = None self.local_commitment = None @@ -203,18 +200,21 @@ class Channel(Logger): self.config[LOCAL] = self.config[LOCAL]._replace(ctn=0, current_commitment_signature=remote_sig) self.set_state('OPENING') + def set_force_closed(self): + self.force_closed = True + def set_state(self, state: str): - if self._state == 'FORCE_CLOSING': - assert state == 'FORCE_CLOSING', 'new state was not FORCE_CLOSING: ' + state self._state = state def get_state(self): return self._state def is_closed(self): - return self.get_state() in ['CLOSED', 'FORCE_CLOSING'] + return self.force_closed or self.get_state() in ['CLOSED', 'CLOSING'] def _check_can_pay(self, amount_msat: int) -> None: + if self.is_closed(): + raise PaymentFailure('Channel closed') if self.get_state() != 'OPEN': raise PaymentFailure('Channel not open') if self.available_to_spend(LOCAL) < amount_msat: @@ -672,7 +672,7 @@ class Channel(Logger): "remote_commitment_to_be_revoked": str(self.remote_commitment_to_be_revoked), "log": self.hm.to_save(), "onion_keys": str_bytes_dict_to_save(self.onion_keys), - "force_closed": self.get_state() == 'FORCE_CLOSING', + "force_closed": self.force_closed, } return to_save diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py @@ -1342,7 +1342,7 @@ class Peer(Logger): while True: our_sig, closing_tx = chan.make_closing_tx(scriptpubkey, payload['scriptpubkey'], fee_sat=our_fee) self.send_message('closing_signed', channel_id=chan.channel_id, fee_satoshis=our_fee, signature=our_sig) - cs_payload = await asyncio.wait_for(self.closing_signed[chan.channel_id].get(), 1) + cs_payload = await asyncio.wait_for(self.closing_signed[chan.channel_id].get(), 10) their_fee = int.from_bytes(cs_payload['fee_satoshis'], 'big') their_sig = cs_payload['signature'] if our_fee == their_fee: diff --git a/electrum/lnworker.py b/electrum/lnworker.py @@ -334,8 +334,7 @@ class LNWallet(LNWorker): def peer_closed(self, peer): for chan in self.channels_for_peer(peer.pubkey).values(): - if chan.get_state() != 'FORCE_CLOSING': - chan.set_state('DISCONNECTED') + chan.set_state('DISCONNECTED') self.network.trigger_callback('channel', chan) self.peers.pop(peer.pubkey) @@ -485,7 +484,7 @@ class LNWallet(LNWorker): chan = self.channel_by_txo(funding_outpoint) if not chan: return - self.logger.info(f'on_channel_open {funding_outpoint}') + self.logger.debug(f'on_channel_open {funding_outpoint}') self.channel_timestamps[bh2u(chan.channel_id)] = funding_txid, funding_height.height, funding_height.timestamp, None, None, None self.storage.put('lightning_channel_timestamps', self.channel_timestamps) chan.set_funding_txo_spentness(False) @@ -497,13 +496,12 @@ class LNWallet(LNWorker): chan = self.channel_by_txo(funding_outpoint) if not chan: return - self.logger.info(f'on_channel_closed {funding_outpoint}') + self.logger.debug(f'on_channel_closed {funding_outpoint}') self.channel_timestamps[bh2u(chan.channel_id)] = funding_txid, funding_height.height, funding_height.timestamp, closing_txid, closing_height.height, closing_height.timestamp self.storage.put('lightning_channel_timestamps', self.channel_timestamps) chan.set_funding_txo_spentness(True) - if chan.get_state() != 'FORCE_CLOSING': - chan.set_state("CLOSED") - self.on_channels_updated() + chan.set_state('CLOSED') + self.on_channels_updated() self.network.trigger_callback('channel', chan) # remove from channel_db if chan.short_channel_id is not None: @@ -588,7 +586,7 @@ class LNWallet(LNWorker): await peer.bitcoin_fee_update(chan) conf = lnwatcher.get_tx_height(chan.funding_outpoint.txid).conf peer.on_network_update(chan, conf) - elif chan.get_state() == 'FORCE_CLOSING': + elif chan.force_closed and chan.get_state() != 'CLOSED': txid = chan.force_close_tx().txid() height = lnwatcher.get_tx_height(txid).height self.logger.info(f"force closing tx {txid}, height {height}") @@ -871,7 +869,7 @@ class LNWallet(LNWorker): async def force_close_channel(self, chan_id): chan = self.channels[chan_id] tx = chan.force_close_tx() - chan.set_state('FORCE_CLOSING') + chan.set_force_closed() self.save_channel(chan) self.on_channels_updated() await self.network.broadcast_transaction(tx) diff --git a/electrum/tests/test_lnpeer.py b/electrum/tests/test_lnpeer.py @@ -262,7 +262,7 @@ class TestPeer(SequentialTestCase): # route finding should fail when channel is closed async def f(): await asyncio.gather(w1._pay_to_route(route, addr, pay_req), p1._message_loop(), p2._message_loop()) - with self.assertRaises(AssertionError): + with self.assertRaises(PaymentFailure): run(f()) def run(coro):