electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 96f144eb03fa9aa7debe86158d51e639d8f13cd6
parent 463818b12d84cfdd4db741f2517529dd3f933c9c
Author: ThomasV <thomasv@electrum.org>
Date:   Thu, 25 Feb 2016 08:55:06 +0100

make sure the broadcast tx thread always times out

Diffstat:
Mgui/kivy/main_window.py | 2+-
Mgui/qt/main_window.py | 23++++++++++-------------
Mgui/stdio.py | 4+---
Mgui/text.py | 4+---
Mlib/network.py | 16+++++++++++++++-
Mlib/wallet.py | 28----------------------------
6 files changed, 28 insertions(+), 49 deletions(-)

diff --git a/gui/kivy/main_window.py b/gui/kivy/main_window.py @@ -698,7 +698,7 @@ class ElectrumWindow(App): Clock.schedule_once(lambda dt: on_success(tx)) def _broadcast_thread(self, tx, on_complete): - ok, txid = self.wallet.sendtx(tx) + ok, txid = self.network.broadcast(tx) Clock.schedule_once(lambda dt: on_complete(ok, txid)) def broadcast(self, tx, pr=None): diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py @@ -1321,21 +1321,18 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): def broadcast_thread(): # non-GUI thread pr = self.payment_request - if pr is None: - return self.wallet.sendtx(tx) - if pr.has_expired(): + if pr and pr.has_expired(): self.payment_request = None return False, _("Payment request has expired") - status, msg = self.wallet.sendtx(tx) - if not status: - return False, msg - pr.set_paid(tx.hash()) - self.invoices.save() - self.payment_request = None - refund_address = self.wallet.addresses()[0] - ack_status, ack_msg = pr.send_ack(str(tx), refund_address) - if ack_status: - msg = ack_msg + status, msg = self.network.broadcast(tx) + if pr and status is True: + pr.set_paid(tx.hash()) + self.invoices.save() + self.payment_request = None + refund_address = self.wallet.addresses()[0] + ack_status, ack_msg = pr.send_ack(str(tx), refund_address) + if ack_status: + msg = ack_msg return status, msg # Capture current TL window; override might be removed on return diff --git a/gui/stdio.py b/gui/stdio.py @@ -195,10 +195,8 @@ class ElectrumGui: if self.str_description: self.wallet.labels[tx.hash()] = self.str_description - h = self.wallet.send_tx(tx) print(_("Please wait...")) - self.wallet.tx_event.wait() - status, msg = self.wallet.receive_tx( h, tx ) + status, msg = self.network.broadcast(tx) if status: print(_('Payment sent.')) diff --git a/gui/text.py b/gui/text.py @@ -337,10 +337,8 @@ class ElectrumGui: if self.str_description: self.wallet.labels[tx.hash()] = self.str_description - h = self.wallet.send_tx(tx) self.show_message(_("Please wait..."), getchar=False) - self.wallet.tx_event.wait() - status, msg = self.wallet.receive_tx( h, tx ) + status, msg = self.network.broadcast(tx) if status: self.show_message(_('Payment sent.')) diff --git a/lib/network.py b/lib/network.py @@ -824,7 +824,21 @@ class Network(util.DaemonThread): def synchronous_get(self, request, timeout=100000000): queue = Queue.Queue() self.send([request], queue.put) - r = queue.get(True, timeout) + try: + r = queue.get(True, timeout) + except Queue.Empty: + raise BaseException('Server did not answer') if r.get('error'): raise BaseException(r.get('error')) return r.get('result') + + def broadcast(self, tx, timeout=10): + tx_hash = tx.hash() + try: + r = self.synchronous_get(('blockchain.transaction.broadcast', [str(tx)]), timeout) + except BaseException as e: + return False, "error: " + str(e) + result = r.get('result') + if out != tx_hash: + return False, "error: " + out + return True, out diff --git a/lib/wallet.py b/lib/wallet.py @@ -204,7 +204,6 @@ class Abstract_Wallet(PrintError): self.up_to_date = False self.lock = threading.Lock() self.transaction_lock = threading.Lock() - self.tx_event = threading.Event() self.check_history() @@ -1038,33 +1037,6 @@ class Abstract_Wallet(PrintError): if keypairs: tx.sign(keypairs) - - def sendtx(self, tx): - # synchronous - h = self.send_tx(tx) - self.tx_event.wait() - return self.receive_tx(h, tx) - - def send_tx(self, tx): - # asynchronous - self.tx_event.clear() - # fixme: this does not handle the case where server does not answer - if not self.network.interface: - raise BaseException("Not connected") - self.network.send([('blockchain.transaction.broadcast', [str(tx)])], self.on_broadcast) - return tx.hash() - - def on_broadcast(self, r): - self.tx_result = r.get('result') - self.tx_event.set() - - def receive_tx(self, tx_hash, tx): - out = self.tx_result - if out != tx_hash: - return False, "error: " + out - run_hook('receive_tx', tx, self) - return True, out - def update_password(self, old_password, new_password): if new_password == '': new_password = None