Set status of onchain invoices to PR_INFLIGHT while tx is being broadcast
This commit is contained in:
@@ -96,10 +96,9 @@ class QEInvoice(QObject, QtEventListener):
|
||||
@event_listener
|
||||
def on_event_invoice_status(self, wallet, key, status):
|
||||
if wallet == self._wallet.wallet and key == self.key:
|
||||
self.update_userinfo()
|
||||
self.determine_can_pay()
|
||||
self.statusChanged.emit()
|
||||
if status in [PR_INFLIGHT, PR_ROUTING]:
|
||||
self.determine_can_pay()
|
||||
self.userinfo = _('In progress...')
|
||||
|
||||
walletChanged = pyqtSignal()
|
||||
@pyqtProperty(QEWallet, notify=walletChanged)
|
||||
@@ -331,6 +330,7 @@ class QEInvoice(QObject, QtEventListener):
|
||||
self.userinfo = {
|
||||
PR_EXPIRED: _('This invoice has expired'),
|
||||
PR_PAID: _('This invoice was already paid'),
|
||||
PR_INFLIGHT: _('Payment in progress...') + ' (' + _('broadcasting') + ')',
|
||||
PR_UNCONFIRMED: _('Payment in progress...') + ' (' + _('waiting for confirmation') + ')',
|
||||
PR_UNKNOWN: _('Invoice has unknown status'),
|
||||
}[self.status]
|
||||
|
||||
@@ -549,6 +549,7 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
||||
assert tx.is_complete()
|
||||
|
||||
def broadcast_thread():
|
||||
self.wallet.set_broadcasting(tx, True)
|
||||
try:
|
||||
self._logger.info('running broadcast in thread')
|
||||
self.wallet.network.run_from_another_thread(self.wallet.network.broadcast_transaction(tx))
|
||||
@@ -562,6 +563,7 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
||||
self._logger.info('broadcast success')
|
||||
self.broadcastSucceeded.emit(tx.txid())
|
||||
self.historyModel.requestRefresh.emit() # via qt thread
|
||||
self.wallet.set_broadcasting(tx, False)
|
||||
|
||||
threading.Thread(target=broadcast_thread, daemon=True).start()
|
||||
|
||||
|
||||
@@ -761,7 +761,10 @@ class SendTab(QWidget, MessageBoxMixin, Logger):
|
||||
# Capture current TL window; override might be removed on return
|
||||
parent = self.window.top_level_window(lambda win: isinstance(win, MessageBoxMixin))
|
||||
|
||||
self.wallet.set_broadcasting(tx, True)
|
||||
|
||||
def broadcast_done(result):
|
||||
self.wallet.set_broadcasting(tx, False)
|
||||
# GUI thread
|
||||
if result:
|
||||
success, msg = result
|
||||
|
||||
@@ -243,6 +243,7 @@ class BaseInvoice(StoredObject):
|
||||
class Invoice(BaseInvoice):
|
||||
lightning_invoice = attr.ib(type=str, kw_only=True) # type: Optional[str]
|
||||
__lnaddr = None
|
||||
_is_broadcasting = False
|
||||
|
||||
def is_lightning(self):
|
||||
return self.lightning_invoice is not None
|
||||
|
||||
@@ -75,7 +75,7 @@ from .plugin import run_hook
|
||||
from .address_synchronizer import (AddressSynchronizer, TX_HEIGHT_LOCAL,
|
||||
TX_HEIGHT_UNCONF_PARENT, TX_HEIGHT_UNCONFIRMED, TX_HEIGHT_FUTURE)
|
||||
from .invoices import BaseInvoice, Invoice, Request
|
||||
from .invoices import PR_PAID, PR_UNPAID, PR_UNKNOWN, PR_EXPIRED, PR_UNCONFIRMED
|
||||
from .invoices import PR_PAID, PR_UNPAID, PR_UNKNOWN, PR_EXPIRED, PR_UNCONFIRMED, PR_INFLIGHT
|
||||
from .contacts import Contacts
|
||||
from .interface import NetworkException
|
||||
from .mnemonic import Mnemonic
|
||||
@@ -2405,6 +2405,8 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
||||
|
||||
def get_invoice_status(self, invoice: BaseInvoice):
|
||||
"""Returns status of (incoming) request or (outgoing) invoice."""
|
||||
if isinstance(invoice, Invoice) and invoice._is_broadcasting:
|
||||
return PR_INFLIGHT
|
||||
# lightning invoices can be paid onchain
|
||||
if invoice.is_lightning() and self.lnworker:
|
||||
status = self.lnworker.get_invoice_status(invoice)
|
||||
@@ -2496,6 +2498,18 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
||||
d['bip70'] = x.bip70
|
||||
return d
|
||||
|
||||
def get_invoices_and_requests_touched_by_tx(self, tx):
|
||||
request_keys = set()
|
||||
invoice_keys = set()
|
||||
with self.lock, self.transaction_lock:
|
||||
for txo in tx.outputs():
|
||||
addr = txo.address
|
||||
if request:=self.get_request_by_addr(addr):
|
||||
request_keys.add(request.get_id())
|
||||
for invoice_key in self._invoices_from_scriptpubkey_map.get(txo.scriptpubkey, set()):
|
||||
invoice_keys.add(invoice_key)
|
||||
return request_keys, invoice_keys
|
||||
|
||||
def _update_invoices_and_reqs_touched_by_tx(self, tx_hash: str) -> None:
|
||||
# FIXME in some cases if tx2 replaces unconfirmed tx1 in the mempool, we are not called.
|
||||
# For a given receive request, if tx1 touches it but tx2 does not, then
|
||||
@@ -2503,16 +2517,24 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
||||
tx = self.db.get_transaction(tx_hash)
|
||||
if tx is None:
|
||||
return
|
||||
relevant_invoice_keys = set()
|
||||
with self.lock, self.transaction_lock:
|
||||
for txo in tx.outputs():
|
||||
addr = txo.address
|
||||
if request:=self.get_request_by_addr(addr):
|
||||
status = self.get_invoice_status(request)
|
||||
util.trigger_callback('request_status', self, request.get_id(), status)
|
||||
for invoice_key in self._invoices_from_scriptpubkey_map.get(txo.scriptpubkey, set()):
|
||||
relevant_invoice_keys.add(invoice_key)
|
||||
self._update_onchain_invoice_paid_detection(relevant_invoice_keys)
|
||||
request_keys, invoice_keys = self.get_invoices_and_requests_touched_by_tx(tx)
|
||||
for key in request_keys:
|
||||
request = self.get_request(key)
|
||||
if not request:
|
||||
continue
|
||||
status = self.get_invoice_status(request)
|
||||
util.trigger_callback('request_status', self, request.get_id(), status)
|
||||
self._update_onchain_invoice_paid_detection(invoice_keys)
|
||||
|
||||
def set_broadcasting(self, tx: Transaction, b: bool):
|
||||
request_keys, invoice_keys = self.get_invoices_and_requests_touched_by_tx(tx)
|
||||
for key in invoice_keys:
|
||||
invoice = self._invoices.get(key)
|
||||
if not invoice:
|
||||
continue
|
||||
invoice._is_broadcasting = b
|
||||
status = self.get_invoice_status(invoice)
|
||||
util.trigger_callback('invoice_status', self, key, status)
|
||||
|
||||
def get_bolt11_invoice(self, req: Request) -> str:
|
||||
if not self.lnworker:
|
||||
|
||||
Reference in New Issue
Block a user