URI: 
       tmove channel_state into HTLCStateMachine - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit d740475e7aabd4c4762ab7b07bc8d43d289df5fb
   DIR parent 3caccbebcd9249f442d9dc1196a65555ed56dee3
  HTML Author: Janus <ysangkok@gmail.com>
       Date:   Mon, 16 Jul 2018 16:51:32 +0200
       
       move channel_state into HTLCStateMachine
       
       Diffstat:
         M electrum/gui/qt/channels_list.py    |       3 +--
         M electrum/lnbase.py                  |      20 ++++++++++++--------
         M electrum/lnhtlc.py                  |       2 ++
         M electrum/lnworker.py                |      19 ++++++++++---------
         M electrum/tests/test_lnrouter.py     |       2 +-
       
       5 files changed, 26 insertions(+), 20 deletions(-)
       ---
   DIR diff --git a/electrum/gui/qt/channels_list.py b/electrum/gui/qt/channels_list.py
       t@@ -20,12 +20,11 @@ class ChannelsList(MyTreeWidget):
                self.status = QLabel('')
        
            def format_fields(self, chan):
       -        status = self.parent.wallet.lnworker.channel_state[chan.channel_id]
                return [
                    bh2u(chan.node_id),
                    self.parent.format_amount(chan.local_state.amount_msat//1000),
                    self.parent.format_amount(chan.remote_state.amount_msat//1000),
       -            status
       +            chan.state
                ]
        
            def create_menu(self, position):
   DIR diff --git a/electrum/lnbase.py b/electrum/lnbase.py
       t@@ -292,7 +292,6 @@ class Peer(PrintError):
                self.privkey = lnworker.privkey
                self.network = lnworker.network
                self.channel_db = lnworker.network.channel_db
       -        self.channel_state = lnworker.channel_state
                self.read_buffer = b''
                self.ping_time = 0
                self.initialized = asyncio.Future()
       t@@ -305,10 +304,13 @@ class Peer(PrintError):
                self.announcement_signatures = defaultdict(asyncio.Queue)
                self.update_fail_htlc = defaultdict(asyncio.Queue)
                self.localfeatures = (0x08 if request_initial_sync else 0)
       -        self.channels = lnworker.channels_for_peer(pubkey)
                self.invoices = lnworker.invoices
                self.attempted_route = {}
        
       +    @property
       +    def channels(self):
       +        return self.lnworker.channels_for_peer(self.pubkey)
       +
            def diagnostic_name(self):
                return 'lnbase:' + str(self.host)
        
       t@@ -630,13 +632,14 @@ class Peer(PrintError):
                assert success, success
                m.remote_state = m.remote_state._replace(ctn=0)
                m.local_state = m.local_state._replace(ctn=0, current_commitment_signature=remote_sig)
       +        m.state = 'OPENING'
                return m
        
            @aiosafe
            async def reestablish_channel(self, chan):
                await self.initialized
                chan_id = chan.channel_id
       -        self.channel_state[chan_id] = 'REESTABLISHING'
       +        chan.state = 'REESTABLISHING'
                self.network.trigger_callback('channel', chan)
                self.send_message(gen_msg("channel_reestablish",
                    channel_id=chan_id,
       t@@ -644,7 +647,7 @@ class Peer(PrintError):
                    next_remote_revocation_number=chan.remote_state.ctn
                ))
                await self.channel_reestablished[chan_id]
       -        self.channel_state[chan_id] = 'OPENING'
       +        chan.state = 'OPENING'
                if chan.local_state.funding_locked_received and chan.short_channel_id:
                    self.mark_open(chan)
                self.network.trigger_callback('channel', chan)
       t@@ -684,6 +687,7 @@ class Peer(PrintError):
                channel_id = payload['channel_id']
                chan = self.channels.get(channel_id)
                if not chan:
       +            print(self.channels)
                    raise Exception("Got unknown funding_locked", channel_id)
                if not chan.local_state.funding_locked_received:
                    our_next_point = chan.remote_state.next_per_commitment_point
       t@@ -750,10 +754,10 @@ class Peer(PrintError):
                print("SENT CHANNEL ANNOUNCEMENT")
        
            def mark_open(self, chan):
       -        if self.channel_state[chan.channel_id] == "OPEN":
       +        if chan.state == "OPEN":
                    return
                assert chan.local_state.funding_locked_received
       -        self.channel_state[chan.channel_id] = "OPEN"
       +        chan.state = "OPEN"
                self.network.trigger_callback('channel', chan)
                # add channel to database
                sorted_keys = list(sorted([self.pubkey, self.lnworker.pubkey]))
       t@@ -827,7 +831,7 @@ class Peer(PrintError):
        
            @aiosafe
            async def pay(self, path, chan, amount_msat, payment_hash, pubkey_in_invoice, min_final_cltv_expiry):
       -        assert self.channel_state[chan.channel_id] == "OPEN"
       +        assert chan.state == "OPEN"
                assert amount_msat > 0, "amount_msat is not greater zero"
                height = self.network.get_local_height()
                route = self.network.path_finder.create_route_from_path(path, self.lnworker.pubkey)
       t@@ -929,7 +933,7 @@ class Peer(PrintError):
                htlc_id = int.from_bytes(htlc["id"], 'big')
                assert htlc_id == chan.remote_state.next_htlc_id, (htlc_id, chan.remote_state.next_htlc_id)
        
       -        assert self.channel_state[channel_id] == "OPEN"
       +        assert chan.state == "OPEN"
        
                cltv_expiry = int.from_bytes(htlc["cltv_expiry"], 'big')
                # TODO verify sanity of their cltv expiry
   DIR diff --git a/electrum/lnhtlc.py b/electrum/lnhtlc.py
       t@@ -139,6 +139,8 @@ class HTLCStateMachine(PrintError):
                self.local_commitment = self.pending_local_commitment
                self.remote_commitment = self.pending_remote_commitment
        
       +        self.state = 'DISCONNECTED'
       +
            def add_htlc(self, htlc):
                """
                AddHTLC adds an HTLC to the state machine's local update log. This method
   DIR diff --git a/electrum/lnworker.py b/electrum/lnworker.py
       t@@ -40,7 +40,6 @@ class LNWorker(PrintError):
                self.peers = {}
                self.channels = {x.channel_id: x for x in map(HTLCStateMachine, wallet.storage.get("channels", []))}
                self.invoices = wallet.storage.get('lightning_invoices', {})
       -        self.channel_state = {chan.channel_id: "DISCONNECTED" for chan in self.channels.values()}
                for chan_id, chan in self.channels.items():
                    self.network.lnwatcher.watch_channel(chan, self.on_channel_utxos)
                peer_list = self.config.get('lightning_peers', node_list)
       t@@ -71,8 +70,6 @@ class LNWorker(PrintError):
        
            def save_channel(self, openchannel):
                assert type(openchannel) is HTLCStateMachine
       -        if openchannel.channel_id not in self.channel_state:
       -            self.channel_state[openchannel.channel_id] = "OPENING"
                self.channels[openchannel.channel_id] = openchannel
                if openchannel.remote_state.next_per_commitment_point == openchannel.remote_state.current_per_commitment_point:
                    raise Exception("Tried to save channel with next_point == current_point, this should not happen")
       t@@ -87,7 +84,7 @@ class LNWorker(PrintError):
        
                If the Funding TX has not been mined, return None
                """
       -        assert self.channel_state[chan.channel_id] in ["OPEN", "OPENING"]
       +        assert chan.state in ["OPEN", "OPENING"]
                peer = self.peers[chan.node_id]
                conf = self.wallet.get_tx_height(chan.funding_outpoint.txid)[1]
                if conf >= chan.constraints.funding_txn_minimum_depth:
       t@@ -104,26 +101,30 @@ class LNWorker(PrintError):
            def on_channel_utxos(self, chan, utxos):
                outpoints = [Outpoint(x["tx_hash"], x["tx_pos"]) for x in utxos]
                if chan.funding_outpoint not in outpoints:
       -            self.channel_state[chan.channel_id] = "CLOSED"
       +            chan.state = "CLOSED"
                    # FIXME is this properly GC-ed? (or too soon?)
                    LNChanCloseHandler(self.network, self.wallet, chan)
       -        elif self.channel_state[chan.channel_id] == 'DISCONNECTED':
       +        elif chan.state == 'DISCONNECTED':
       +            if chan.node_id not in self.peers:
       +                self.print_error("received channel_utxos for channel which does not have peer (errored?)")
       +                return
                    peer = self.peers[chan.node_id]
                    coro = peer.reestablish_channel(chan)
                    asyncio.run_coroutine_threadsafe(coro, self.network.asyncio_loop)
        
            def on_network_update(self, event, *args):
                for chan in self.channels.values():
       -            peer = self.peers[chan.node_id]
       -            if self.channel_state[chan.channel_id] == "OPENING":
       +            if chan.state == "OPENING":
                        res = self.save_short_chan_id(chan)
                        if not res:
                            self.print_error("network update but funding tx is still not at sufficient depth")
                            continue
                        # this results in the channel being marked OPEN
       +                peer = self.peers[chan.node_id]
                        peer.funding_locked(chan)
       -            elif self.channel_state[chan.channel_id] == "OPEN":
       +            elif chan.state == "OPEN":
                        conf = self.wallet.get_tx_height(chan.funding_outpoint.txid)[1]
       +                peer = self.peers[chan.node_id]
                        peer.on_network_update(chan, conf)
        
            async def _open_channel_coroutine(self, node_id, local_amount_sat, push_sat, password):
   DIR diff --git a/electrum/tests/test_lnrouter.py b/electrum/tests/test_lnrouter.py
       t@@ -31,9 +31,9 @@ class Test_LNRouter(unittest.TestCase):
                    path_finder = lnrouter.LNPathFinder(fake_network.channel_db)
                    privkey = bitcoin.sha256('privkeyseed')
                    network = fake_network
       -            channel_state = {}
                    channels = []
                    invoices = {}
       +            channels_for_peer = lambda x: []
                p = Peer(fake_ln_worker, '', 0, 'a')
                p.on_channel_announcement({'node_id_1': b'b', 'node_id_2': b'c', 'short_channel_id': bfh('0000000000000001')})
                p.on_channel_announcement({'node_id_1': b'b', 'node_id_2': b'e', 'short_channel_id': bfh('0000000000000002')})