diff --git a/electrum/gui/qml/components/WalletMainView.qml b/electrum/gui/qml/components/WalletMainView.qml index 1ab844005..e58e69bfd 100644 --- a/electrum/gui/qml/components/WalletMainView.qml +++ b/electrum/gui/qml/components/WalletMainView.qml @@ -267,6 +267,9 @@ Item { }) dialog.open() } + function onBroadcastFailed() { + notificationPopup.show(qsTr('Broadcast transaction failed')) + } } Component { diff --git a/electrum/gui/qml/qetxdetails.py b/electrum/gui/qml/qetxdetails.py index 4abaeb1a1..1f30012f8 100644 --- a/electrum/gui/qml/qetxdetails.py +++ b/electrum/gui/qml/qetxdetails.py @@ -284,4 +284,24 @@ class QETxDetails(QObject): @pyqtSlot() def broadcast(self): assert self._tx.is_complete() + + try: + self._wallet.broadcastfailed.disconnect(self.onBroadcastFailed) + except: + pass + self._wallet.broadcastFailed.connect(self.onBroadcastFailed) + + self._can_broadcast = False + self.detailsChanged.emit() + self._wallet.broadcast(self._tx) + + @pyqtSlot(str,str,str) + def onBroadcastFailed(self, txid, code, reason): + if txid != self._txid: + return + + self._wallet.broadcastFailed.disconnect(self.onBroadcastFailed) + + self._can_broadcast = True + self.detailsChanged.emit() diff --git a/electrum/gui/qml/qewallet.py b/electrum/gui/qml/qewallet.py index 329bd8a73..8448cdae5 100644 --- a/electrum/gui/qml/qewallet.py +++ b/electrum/gui/qml/qewallet.py @@ -62,7 +62,7 @@ class QEWallet(AuthMixin, QObject, QtEventListener): paymentFailed = pyqtSignal([str,str], arguments=['key','reason']) requestNewPassword = pyqtSignal() transactionSigned = pyqtSignal([str], arguments=['txid']) - #broadcastSucceeded = pyqtSignal([str], arguments=['txid']) + broadcastSucceeded = pyqtSignal([str], arguments=['txid']) broadcastFailed = pyqtSignal([str,str,str], arguments=['txid','code','reason']) labelsUpdated = pyqtSignal() otpRequested = pyqtSignal() @@ -476,21 +476,25 @@ class QEWallet(AuthMixin, QObject, QtEventListener): def broadcast(self, tx): assert tx.is_complete() - self.network = self.wallet.network # TODO not always defined? + network = self.wallet.network # TODO not always defined? - try: - self._logger.info('running broadcast in thread') - self.network.run_from_another_thread(self.network.broadcast_transaction(tx)) - self._logger.info('broadcast submit done') - except TxBroadcastError as e: - self.broadcastFailed.emit(tx.txid(),'',repr(e)) - self._logger.error(e) - except BestEffortRequestFailed as e: - self.broadcastFailed.emit(tx.txid(),'',repr(e)) - self._logger.error(e) + def broadcast_thread(): + try: + self._logger.info('running broadcast in thread') + result = network.run_from_another_thread(network.broadcast_transaction(tx)) + self._logger.info(repr(result)) + except TxBroadcastError as e: + self._logger.error(repr(e)) + self.broadcastFailed.emit(tx.txid(),'',repr(e)) + except BestEffortRequestFailed as e: + self._logger.error(repr(e)) + self.broadcastFailed.emit(tx.txid(),'',repr(e)) + else: + self.broadcastSucceeded.emit(tx.txid()) + + threading.Thread(target=broadcast_thread).start() #TODO: properly catch server side errors, e.g. bad-txns-inputs-missingorspent - #might need callback from network.py paymentAuthRejected = pyqtSignal() def ln_auth_rejected(self):