commit 2af178a5864891fa003aa037b35a6c813c658096
parent 4e3b2b547994605bb6e0630009334a534ae2e7f1
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:
6 files changed, 36 insertions(+), 27 deletions(-)
diff --git a/electrum/commands.py b/electrum/commands.py
@@ -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
@@ -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,
@@ -830,6 +843,7 @@ class Commands:
'cltv_expiry':htlc.cltv_expiry
}
out.append(item)
+ out.sort(key=operator.itemgetter('timestamp'))
return out
@command('wn')
diff --git a/electrum/gui/qt/channel_details.py b/electrum/gui/qt/channel_details.py
@@ -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
diff --git a/electrum/gui/qt/request_list.py b/electrum/gui/qt/request_list.py
@@ -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
@@ -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)
@@ -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
diff --git a/electrum/lnbase.py b/electrum/lnbase.py
@@ -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)],
@@ -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']
diff --git a/electrum/lnworker.py b/electrum/lnworker.py
@@ -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()
@@ -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)
@@ -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
@@ -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)
diff --git a/electrum/tests/test_lnbase.py b/electrum/tests/test_lnbase.py
@@ -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
@@ -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