URI: 
       tStore boolean is_received in lightning invoices. Sort lightning history with timestamp. Minor fixes - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 2af178a5864891fa003aa037b35a6c813c658096
   DIR parent 4e3b2b547994605bb6e0630009334a534ae2e7f1
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Wed, 30 Jan 2019 09:26:27 +0100
       
       Store boolean is_received in lightning invoices. Sort lightning history with timestamp. Minor fixes
       
       Diffstat:
         M electrum/commands.py                |      22 ++++++++++++++++++----
         M electrum/gui/qt/channel_details.py  |      12 ++++--------
         M electrum/gui/qt/request_list.py     |       8 ++++----
         M electrum/lnbase.py                  |       2 --
         M electrum/lnworker.py                |      15 ++++++++-------
         M electrum/tests/test_lnbase.py       |       4 ++--
       
       6 files changed, 36 insertions(+), 27 deletions(-)
       ---
   DIR diff --git a/electrum/commands.py b/electrum/commands.py
       t@@ -30,12 +30,13 @@ import argparse
        import json
        import ast
        import base64
       +import operator
        from functools import wraps
        from decimal import Decimal
        from typing import Optional, TYPE_CHECKING
        
        from .import util, ecc
       -from .util import bfh, bh2u, format_satoshis, json_decode, json_encode, is_hash256_str, is_hex_str, to_bytes
       +from .util import bfh, bh2u, format_satoshis, json_decode, json_encode, is_hash256_str, is_hex_str, to_bytes, timestamp_to_datetime
        from . import bitcoin
        from .bitcoin import is_address,  hash_160, COIN, TYPE_ADDRESS
        from .bip32 import BIP32Node
       t@@ -811,16 +812,28 @@ class Commands:
            def lightning_invoices(self):
                from .util import pr_tooltips
                out = []
       -        for payment_hash, (preimage, pay_req, direction, pay_timestamp) in self.lnworker.invoices.items():
       -            status = pr_tooltips[self.lnworker.get_invoice_status(payment_hash)]
       -            out.append({'payment_hash':payment_hash, 'invoice':pay_req, 'preimage':preimage, 'status':status, 'direction':direction})
       +        for payment_hash, (preimage, invoice, is_received, timestamp) in self.lnworker.invoices.items():
       +            status = self.lnworker.get_invoice_status(payment_hash)
       +            item = {
       +                'date':timestamp_to_datetime(timestamp),
       +                'direction': 'received' if is_received else 'sent',
       +                'payment_hash':payment_hash,
       +                'invoice':invoice,
       +                'preimage':preimage,
       +                'status':pr_tooltips[status]
       +            }
       +            out.append(item)
                return out
        
            @command('w')
            def lightning_history(self):
                out = []
                for chan_id, htlc, direction, status in self.lnworker.get_payments().values():
       +            payment_hash = bh2u(htlc.payment_hash)
       +            timestamp = self.lnworker.invoices[payment_hash][3] if payment_hash in self.lnworker.invoices else None
                    item = {
       +                'timestamp':timestamp or 0,
       +                'date':timestamp_to_datetime(timestamp),
                        'direction': 'sent' if direction == SENT else 'received',
                        'status':status,
                        'amout_msat':htlc.amount_msat,
       t@@ -830,6 +843,7 @@ class Commands:
                        'cltv_expiry':htlc.cltv_expiry
                    }
                    out.append(item)
       +        out.sort(key=operator.itemgetter('timestamp'))
                return out
        
            @command('wn')
   DIR diff --git a/electrum/gui/qt/channel_details.py b/electrum/gui/qt/channel_details.py
       t@@ -72,22 +72,18 @@ class ChannelDetailsDialog(QtWidgets.QDialog):
                for pay_hash, item in htlcs.items():
                    chan_id, i, direction, status = item
                    if pay_hash in invoices:
       -                preimage, invoice, direction, timestamp = invoices[pay_hash]
       +                invoice = invoices[pay_hash][1]
                        lnaddr = lndecode(invoice)
                    if status == 'inflight':
                        it = self.make_inflight(lnaddr, i, direction)
       -                self.folders['inflight'].appendRow(it)
       -                mapping[i.payment_hash] = num
       -                num += 1
                    elif status == 'settled':
                        it = self.make_htlc_item(i, direction)
                        # if we made the invoice and still have it, we can show more info
                        if pay_hash in invoices:
                            self.append_lnaddr(it, lndecode(invoice))
       -                self.folders['settled'].appendRow(it)
       -                mapping[i.payment_hash] = num
       -                num += 1
       -
       +            self.folders[status].appendRow(it)
       +            mapping[i.payment_hash] = num
       +            num += 1
                    self.keyname_rows[keyname] = mapping
                return model
        
   DIR diff --git a/electrum/gui/qt/request_list.py b/electrum/gui/qt/request_list.py
       t@@ -96,7 +96,7 @@ class RequestList(MyTreeView):
                        return
                    req = self.parent.get_request_URI(key)
                elif request_type == REQUEST_TYPE_LN:
       -            preimage, req, direction, pay_timestamp = self.wallet.lnworker.invoices.get(key, (None, None, None))
       +            preimage, req, is_received, pay_timestamp = self.wallet.lnworker.invoices.get(key, (None, None, None))
                    if req is None:
                        self.update()
                        return
       t@@ -146,8 +146,8 @@ class RequestList(MyTreeView):
                self.filter()
                # lightning
                lnworker = self.wallet.lnworker
       -        for key, (preimage_hex, invoice, direction, pay_timestamp) in lnworker.invoices.items():
       -            if direction == SENT:
       +        for key, (preimage_hex, invoice, is_received, pay_timestamp) in lnworker.invoices.items():
       +            if not is_received:
                        continue
                    status = lnworker.get_invoice_status(key)
                    lnaddr = lndecode(invoice, expected_hrp=constants.net.SEGWIT_HRP)
       t@@ -184,7 +184,7 @@ class RequestList(MyTreeView):
                if request_type == REQUEST_TYPE_BITCOIN:
                    req = self.wallet.receive_requests.get(addr)
                elif request_type == REQUEST_TYPE_LN:
       -            preimage, req, direction, pay_timestamp = self.wallet.lnworker.invoices.get(addr)
       +            req = self.wallet.lnworker.invoices[addr][1]
                if req is None:
                    self.update()
                    return
   DIR diff --git a/electrum/lnbase.py b/electrum/lnbase.py
       t@@ -420,7 +420,6 @@ class Peer(PrintError):
            @log_exceptions
            async def channel_establishment_flow(self, password: Optional[str], funding_sat: int,
                                                 push_msat: int, temp_channel_id: bytes) -> Channel:
       -        #assert push_msat == 0, "push_msat not supported currently"
                wallet = self.lnworker.wallet
                # dry run creating funding tx to see if we even have enough funds
                funding_tx_test = wallet.mktx([TxOutput(bitcoin.TYPE_ADDRESS, wallet.dummy_address(), funding_sat)],
       t@@ -549,7 +548,6 @@ class Peer(PrintError):
                    raise Exception('wrong chain_hash')
                funding_sat = int.from_bytes(payload['funding_satoshis'], 'big')
                push_msat = int.from_bytes(payload['push_msat'], 'big')
       -        #assert push_msat == 0, "push_msat not supported currently"
                feerate = int.from_bytes(payload['feerate_per_kw'], 'big')
        
                temp_chan_id = payload['temporary_channel_id']
   DIR diff --git a/electrum/lnworker.py b/electrum/lnworker.py
       t@@ -67,7 +67,8 @@ class LNWorker(PrintError):
        
            def __init__(self, wallet: 'Abstract_Wallet'):
                self.wallet = wallet
       -        self.invoices = self.wallet.storage.get('lightning_invoices', {})  # type: Dict[str, Tuple[str,str]]  # RHASH -> (preimage, invoice, direction, pay_timestamp)
       +        # type: Dict[str, Tuple[str,str,bool,int]]  # RHASH -> (preimage, invoice, is_received, timestamp)
       +        self.invoices = self.wallet.storage.get('lightning_invoices', {})
                self.sweep_address = wallet.get_receiving_address()
                self.lock = threading.RLock()
                self.ln_keystore = self._read_ln_keystore()
       t@@ -125,11 +126,11 @@ class LNWorker(PrintError):
                key = bh2u(htlc.payment_hash)
                if key not in self.invoices:
                    return
       -        preimage, invoice, direction, timestamp = self.invoices.get(key)
       +        preimage, invoice, is_received, timestamp = self.invoices.get(key)
                if direction == SENT:
       -            preimage = _preimage
       +            preimage = bh2u(_preimage)
                now = time.time()
       -        self.invoices[key] = preimage, invoice, direction, now
       +        self.invoices[key] = preimage, invoice, is_received, now
                self.wallet.storage.put('lightning_invoices', self.invoices)
                self.wallet.storage.write()
                self.network.trigger_callback('ln_payment_completed', now, direction, htlc, preimage, chan_id)
       t@@ -137,7 +138,7 @@ class LNWorker(PrintError):
            def get_invoice_status(self, payment_hash):
                if payment_hash not in self.invoices:
                    return PR_UNKNOWN
       -        preimage, _addr, direction, timestamp = self.invoices.get(payment_hash)
       +        preimage, _addr, is_received, timestamp = self.invoices.get(payment_hash)
                if timestamp is None:
                    return PR_UNPAID
                return PR_PAID
       t@@ -508,13 +509,13 @@ class LNWorker(PrintError):
            def save_invoice(self, preimage, invoice, direction):
                lnaddr = lndecode(invoice, expected_hrp=constants.net.SEGWIT_HRP)
                key = bh2u(lnaddr.paymenthash)
       -        self.invoices[key] = preimage, invoice, direction, None
       +        self.invoices[key] = preimage, invoice, direction==RECEIVED, None
                self.wallet.storage.put('lightning_invoices', self.invoices)
                self.wallet.storage.write()
        
            def get_invoice(self, payment_hash: bytes) -> Tuple[bytes, LnAddr]:
                try:
       -            preimage_hex, pay_req, direction,timestamp = self.invoices[bh2u(payment_hash)]
       +            preimage_hex, pay_req, is_received, timestamp = self.invoices[bh2u(payment_hash)]
                    preimage = bfh(preimage_hex)
                    assert sha256(preimage) == payment_hash
                    return preimage, lndecode(pay_req, expected_hrp=constants.net.SEGWIT_HRP)
   DIR diff --git a/electrum/tests/test_lnbase.py b/electrum/tests/test_lnbase.py
       t@@ -16,7 +16,7 @@ from electrum.util import bh2u
        from electrum.lnbase import Peer, decode_msg, gen_msg
        from electrum.lnutil import LNPeerAddr, Keypair, privkey_to_pubkey
        from electrum.lnutil import LightningPeerConnectionClosed, RemoteMisbehaving
       -from electrum.lnutil import PaymentFailure, RECEIVED
       +from electrum.lnutil import PaymentFailure
        from electrum.lnrouter import ChannelDB, LNPathFinder
        from electrum.lnworker import LNWorker
        
       t@@ -189,7 +189,7 @@ class TestPeer(unittest.TestCase):
                                  ('d', 'coffee')
                                 ])
                pay_req = lnencode(addr, w2.node_keypair.privkey)
       -        w2.invoices[bh2u(RHASH)] = (bh2u(payment_preimage), pay_req, RECEIVED, None)
       +        w2.invoices[bh2u(RHASH)] = (bh2u(payment_preimage), pay_req, True, None)
                return pay_req
        
            @staticmethod