mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-09-03 02:35:20 +00:00
Store boolean is_received in lightning invoices. Sort lightning history with timestamp. Minor fixes
This commit is contained in:
parent
4e3b2b5479
commit
2af178a586
6 changed files with 36 additions and 27 deletions
|
@ -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')
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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']
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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…
Add table
Reference in a new issue