Browse Source

rate limit txn notifications in qt

3.3.3.1
SomberNight 7 years ago
parent
commit
4e0d179937
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 68
      electrum/gui/qt/main_window.py

68
electrum/gui/qt/main_window.py

@ -31,6 +31,7 @@ import csv
from decimal import Decimal from decimal import Decimal
import base64 import base64
from functools import partial from functools import partial
import queue
from PyQt5.QtGui import * from PyQt5.QtGui import *
from PyQt5.QtCore import * from PyQt5.QtCore import *
@ -90,7 +91,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
payment_request_ok_signal = pyqtSignal() payment_request_ok_signal = pyqtSignal()
payment_request_error_signal = pyqtSignal() payment_request_error_signal = pyqtSignal()
notify_transactions_signal = pyqtSignal()
new_fx_quotes_signal = pyqtSignal() new_fx_quotes_signal = pyqtSignal()
new_fx_history_signal = pyqtSignal() new_fx_history_signal = pyqtSignal()
network_signal = pyqtSignal(str, object) network_signal = pyqtSignal(str, object)
@ -120,10 +120,13 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.not_enough_funds = False self.not_enough_funds = False
self.pluginsdialog = None self.pluginsdialog = None
self.require_fee_update = False self.require_fee_update = False
self.tx_notifications = []
self.tl_windows = [] self.tl_windows = []
self.tx_external_keypairs = {} self.tx_external_keypairs = {}
self.tx_notification_queue = queue.Queue()
self.tx_notification_last_time = 0
self.tx_notification_event = threading.Event()
self.create_status_bar() self.create_status_bar()
self.need_update = threading.Event() self.need_update = threading.Event()
@ -181,7 +184,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.payment_request_ok_signal.connect(self.payment_request_ok) self.payment_request_ok_signal.connect(self.payment_request_ok)
self.payment_request_error_signal.connect(self.payment_request_error) self.payment_request_error_signal.connect(self.payment_request_error)
self.notify_transactions_signal.connect(self.notify_transactions)
self.history_list.setFocus(True) self.history_list.setFocus(True)
# network callbacks # network callbacks
@ -299,8 +301,10 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.gui_object.network_updated_signal_obj.network_updated_signal \ self.gui_object.network_updated_signal_obj.network_updated_signal \
.emit(event, args) .emit(event, args)
elif event == 'new_transaction': elif event == 'new_transaction':
self.tx_notifications.append(args[0]) # FIXME maybe this event should also include which wallet
self.notify_transactions_signal.emit() # the tx is for. now all wallets get this.
self.tx_notification_queue.put(args[0])
self.tx_notification_event.set()
elif event in ['status', 'banner', 'verified', 'fee']: elif event in ['status', 'banner', 'verified', 'fee']:
# Handle in GUI thread # Handle in GUI thread
self.network_signal.emit(event, args) self.network_signal.emit(event, args)
@ -356,7 +360,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.utxo_list.update() self.utxo_list.update()
self.need_update.set() self.need_update.set()
# Once GUI has been initialized check if we want to announce something since the callback has been called before the GUI was initialized # Once GUI has been initialized check if we want to announce something since the callback has been called before the GUI was initialized
self.notify_transactions()
# update menus # update menus
self.seed_menu.setEnabled(self.wallet.has_seed()) self.seed_menu.setEnabled(self.wallet.has_seed())
self.update_lock_icon() self.update_lock_icon()
@ -587,28 +590,37 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.show_message(msg, title="Electrum - " + _("Reporting Bugs")) self.show_message(msg, title="Electrum - " + _("Reporting Bugs"))
def notify_transactions(self): def notify_transactions(self):
if not self.network or not self.network.is_connected(): # note: during initial history sync for a wallet, many txns will be
# received multiple times. hence the "total amount received" will be
# a lot higher than should be. this is expected though not intended
if not self.tx_notification_event.is_set():
return return
self.print_error("Notifying GUI") now = time.time()
if len(self.tx_notifications) > 0: if self.tx_notification_last_time + 5 > now:
# Combine the transactions if there are at least three return
num_txns = len(self.tx_notifications) self.tx_notification_event.clear()
if num_txns >= 3: self.tx_notification_last_time = now
total_amount = 0 self.print_error("Notifying GUI about new transactions")
for tx in self.tx_notifications: txns = []
is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx) while True:
if v > 0: try:
total_amount += v txns.append(self.tx_notification_queue.get_nowait())
self.notify(_("{} new transactions received: Total amount received in the new transactions {}") except queue.Empty:
.format(num_txns, self.format_amount_and_units(total_amount))) break
self.tx_notifications = [] # Combine the transactions if there are at least three
else: if len(txns) >= 3:
for tx in self.tx_notifications: total_amount = 0
if tx: for tx in txns:
self.tx_notifications.remove(tx) is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx)
is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx) if v > 0:
if v > 0: total_amount += v
self.notify(_("New transaction received: {}").format(self.format_amount_and_units(v))) self.notify(_("{} new transactions received: Total amount received in the new transactions {}")
.format(len(txns), self.format_amount_and_units(total_amount)))
else:
for tx in txns:
is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx)
if v > 0:
self.notify(_("New transaction received: {}").format(self.format_amount_and_units(v)))
def notify(self, message): def notify(self, message):
if self.tray: if self.tray:
@ -651,6 +663,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
if self.require_fee_update: if self.require_fee_update:
self.do_update_fee() self.do_update_fee()
self.require_fee_update = False self.require_fee_update = False
self.notify_transactions()
def format_amount(self, x, is_diff=False, whitespaces=False): def format_amount(self, x, is_diff=False, whitespaces=False):
return format_satoshis(x, self.num_zeros, self.decimal_point, is_diff=is_diff, whitespaces=whitespaces) return format_satoshis(x, self.num_zeros, self.decimal_point, is_diff=is_diff, whitespaces=whitespaces)

Loading…
Cancel
Save