Browse Source

Store boolean is_received in lightning invoices. Sort lightning history with timestamp. Minor fixes

dependabot/pip/contrib/deterministic-build/ecdsa-0.13.3
ThomasV 6 years ago
parent
commit
2af178a586
  1. 22
      electrum/commands.py
  2. 8
      electrum/gui/qt/channel_details.py
  3. 8
      electrum/gui/qt/request_list.py
  4. 2
      electrum/lnbase.py
  5. 15
      electrum/lnworker.py
  6. 4
      electrum/tests/test_lnbase.py

22
electrum/commands.py

@ -30,12 +30,13 @@ import argparse
import json import json
import ast import ast
import base64 import base64
import operator
from functools import wraps from functools import wraps
from decimal import Decimal from decimal import Decimal
from typing import Optional, TYPE_CHECKING from typing import Optional, TYPE_CHECKING
from .import util, ecc 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 . import bitcoin
from .bitcoin import is_address, hash_160, COIN, TYPE_ADDRESS from .bitcoin import is_address, hash_160, COIN, TYPE_ADDRESS
from .bip32 import BIP32Node from .bip32 import BIP32Node
@ -811,16 +812,28 @@ class Commands:
def lightning_invoices(self): def lightning_invoices(self):
from .util import pr_tooltips from .util import pr_tooltips
out = [] out = []
for payment_hash, (preimage, pay_req, direction, pay_timestamp) in self.lnworker.invoices.items(): for payment_hash, (preimage, invoice, is_received, timestamp) in self.lnworker.invoices.items():
status = pr_tooltips[self.lnworker.get_invoice_status(payment_hash)] status = self.lnworker.get_invoice_status(payment_hash)
out.append({'payment_hash':payment_hash, 'invoice':pay_req, 'preimage':preimage, 'status':status, 'direction':direction}) 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 return out
@command('w') @command('w')
def lightning_history(self): def lightning_history(self):
out = [] out = []
for chan_id, htlc, direction, status in self.lnworker.get_payments().values(): 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 = { item = {
'timestamp':timestamp or 0,
'date':timestamp_to_datetime(timestamp),
'direction': 'sent' if direction == SENT else 'received', 'direction': 'sent' if direction == SENT else 'received',
'status':status, 'status':status,
'amout_msat':htlc.amount_msat, 'amout_msat':htlc.amount_msat,
@ -830,6 +843,7 @@ class Commands:
'cltv_expiry':htlc.cltv_expiry 'cltv_expiry':htlc.cltv_expiry
} }
out.append(item) out.append(item)
out.sort(key=operator.itemgetter('timestamp'))
return out return out
@command('wn') @command('wn')

8
electrum/gui/qt/channel_details.py

@ -72,22 +72,18 @@ class ChannelDetailsDialog(QtWidgets.QDialog):
for pay_hash, item in htlcs.items(): for pay_hash, item in htlcs.items():
chan_id, i, direction, status = item chan_id, i, direction, status = item
if pay_hash in invoices: if pay_hash in invoices:
preimage, invoice, direction, timestamp = invoices[pay_hash] invoice = invoices[pay_hash][1]
lnaddr = lndecode(invoice) lnaddr = lndecode(invoice)
if status == 'inflight': if status == 'inflight':
it = self.make_inflight(lnaddr, i, direction) it = self.make_inflight(lnaddr, i, direction)
self.folders['inflight'].appendRow(it)
mapping[i.payment_hash] = num
num += 1
elif status == 'settled': elif status == 'settled':
it = self.make_htlc_item(i, direction) it = self.make_htlc_item(i, direction)
# if we made the invoice and still have it, we can show more info # if we made the invoice and still have it, we can show more info
if pay_hash in invoices: if pay_hash in invoices:
self.append_lnaddr(it, lndecode(invoice)) self.append_lnaddr(it, lndecode(invoice))
self.folders['settled'].appendRow(it) self.folders[status].appendRow(it)
mapping[i.payment_hash] = num mapping[i.payment_hash] = num
num += 1 num += 1
self.keyname_rows[keyname] = mapping self.keyname_rows[keyname] = mapping
return model return model

8
electrum/gui/qt/request_list.py

@ -96,7 +96,7 @@ class RequestList(MyTreeView):
return return
req = self.parent.get_request_URI(key) req = self.parent.get_request_URI(key)
elif request_type == REQUEST_TYPE_LN: 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: if req is None:
self.update() self.update()
return return
@ -146,8 +146,8 @@ class RequestList(MyTreeView):
self.filter() self.filter()
# lightning # lightning
lnworker = self.wallet.lnworker lnworker = self.wallet.lnworker
for key, (preimage_hex, invoice, direction, pay_timestamp) in lnworker.invoices.items(): for key, (preimage_hex, invoice, is_received, pay_timestamp) in lnworker.invoices.items():
if direction == SENT: if not is_received:
continue continue
status = lnworker.get_invoice_status(key) status = lnworker.get_invoice_status(key)
lnaddr = lndecode(invoice, expected_hrp=constants.net.SEGWIT_HRP) lnaddr = lndecode(invoice, expected_hrp=constants.net.SEGWIT_HRP)
@ -184,7 +184,7 @@ class RequestList(MyTreeView):
if request_type == REQUEST_TYPE_BITCOIN: if request_type == REQUEST_TYPE_BITCOIN:
req = self.wallet.receive_requests.get(addr) req = self.wallet.receive_requests.get(addr)
elif request_type == REQUEST_TYPE_LN: 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: if req is None:
self.update() self.update()
return return

2
electrum/lnbase.py

@ -420,7 +420,6 @@ class Peer(PrintError):
@log_exceptions @log_exceptions
async def channel_establishment_flow(self, password: Optional[str], funding_sat: int, async def channel_establishment_flow(self, password: Optional[str], funding_sat: int,
push_msat: int, temp_channel_id: bytes) -> Channel: push_msat: int, temp_channel_id: bytes) -> Channel:
#assert push_msat == 0, "push_msat not supported currently"
wallet = self.lnworker.wallet wallet = self.lnworker.wallet
# dry run creating funding tx to see if we even have enough funds # 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)], 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') raise Exception('wrong chain_hash')
funding_sat = int.from_bytes(payload['funding_satoshis'], 'big') funding_sat = int.from_bytes(payload['funding_satoshis'], 'big')
push_msat = int.from_bytes(payload['push_msat'], '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') feerate = int.from_bytes(payload['feerate_per_kw'], 'big')
temp_chan_id = payload['temporary_channel_id'] temp_chan_id = payload['temporary_channel_id']

15
electrum/lnworker.py

@ -67,7 +67,8 @@ class LNWorker(PrintError):
def __init__(self, wallet: 'Abstract_Wallet'): def __init__(self, wallet: 'Abstract_Wallet'):
self.wallet = 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.sweep_address = wallet.get_receiving_address()
self.lock = threading.RLock() self.lock = threading.RLock()
self.ln_keystore = self._read_ln_keystore() self.ln_keystore = self._read_ln_keystore()
@ -125,11 +126,11 @@ class LNWorker(PrintError):
key = bh2u(htlc.payment_hash) key = bh2u(htlc.payment_hash)
if key not in self.invoices: if key not in self.invoices:
return return
preimage, invoice, direction, timestamp = self.invoices.get(key) preimage, invoice, is_received, timestamp = self.invoices.get(key)
if direction == SENT: if direction == SENT:
preimage = _preimage preimage = bh2u(_preimage)
now = time.time() 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.put('lightning_invoices', self.invoices)
self.wallet.storage.write() self.wallet.storage.write()
self.network.trigger_callback('ln_payment_completed', now, direction, htlc, preimage, chan_id) 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): def get_invoice_status(self, payment_hash):
if payment_hash not in self.invoices: if payment_hash not in self.invoices:
return PR_UNKNOWN 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: if timestamp is None:
return PR_UNPAID return PR_UNPAID
return PR_PAID return PR_PAID
@ -508,13 +509,13 @@ class LNWorker(PrintError):
def save_invoice(self, preimage, invoice, direction): def save_invoice(self, preimage, invoice, direction):
lnaddr = lndecode(invoice, expected_hrp=constants.net.SEGWIT_HRP) lnaddr = lndecode(invoice, expected_hrp=constants.net.SEGWIT_HRP)
key = bh2u(lnaddr.paymenthash) 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.put('lightning_invoices', self.invoices)
self.wallet.storage.write() self.wallet.storage.write()
def get_invoice(self, payment_hash: bytes) -> Tuple[bytes, LnAddr]: def get_invoice(self, payment_hash: bytes) -> Tuple[bytes, LnAddr]:
try: 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) preimage = bfh(preimage_hex)
assert sha256(preimage) == payment_hash assert sha256(preimage) == payment_hash
return preimage, lndecode(pay_req, expected_hrp=constants.net.SEGWIT_HRP) return preimage, lndecode(pay_req, expected_hrp=constants.net.SEGWIT_HRP)

4
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.lnbase import Peer, decode_msg, gen_msg
from electrum.lnutil import LNPeerAddr, Keypair, privkey_to_pubkey from electrum.lnutil import LNPeerAddr, Keypair, privkey_to_pubkey
from electrum.lnutil import LightningPeerConnectionClosed, RemoteMisbehaving 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.lnrouter import ChannelDB, LNPathFinder
from electrum.lnworker import LNWorker from electrum.lnworker import LNWorker
@ -189,7 +189,7 @@ class TestPeer(unittest.TestCase):
('d', 'coffee') ('d', 'coffee')
]) ])
pay_req = lnencode(addr, w2.node_keypair.privkey) 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 return pay_req
@staticmethod @staticmethod

Loading…
Cancel
Save