Merge remote-tracking branch 'upstream/master' into upstreamMerge

This commit is contained in:
Vivek Teega 2019-01-03 18:46:09 +05:30
commit 8702ed096b
28 changed files with 94 additions and 47 deletions

View File

@ -1,3 +1,11 @@
# Release 3.3.2 - (December 21, 2018)
* Fix Qt history export bug
* Improve network timeouts
* Prepend server transaction_broadcast error messages with
explanatory message. Render error messages as plain text.
# Release 3.3.1 - (December 20, 2018)
* Qt: Fix invoices tab crash (#4941)

@ -1 +1 @@
Subproject commit bce0d7a427ecf2106bf4d1ec56feb4067a50b234
Subproject commit d586021ba0d4820d6587cff000756b3d035d4f08

View File

@ -109,6 +109,13 @@ class ElectrumWindow(App):
def toggle_oneserver(self, x):
self.oneserver = not self.oneserver
proxy_str = StringProperty('')
def update_proxy_str(self, proxy: dict):
mode = proxy.get('mode')
host = proxy.get('host')
port = proxy.get('port')
self.proxy_str = (host + ':' + port) if mode else _('None')
def choose_server_dialog(self, popup):
from .uix.dialogs.choice_dialog import ChoiceDialog
protocol = 's'
@ -288,6 +295,7 @@ class ElectrumWindow(App):
self.auto_connect = net_params.auto_connect
self.oneserver = net_params.oneserver
self.proxy_config = net_params.proxy if net_params.proxy else {}
self.update_proxy_str(self.proxy_config)
self.plugins = kwargs.get('plugins', [])
self.gui_object = kwargs.get('gui_object', None)
@ -667,6 +675,7 @@ class ElectrumWindow(App):
self.tabs = self.root.ids['tabs']
def update_interfaces(self, dt):
net_params = self.network.get_parameters()
self.num_nodes = len(self.network.get_interfaces())
self.num_chains = len(self.network.get_blockchains())
chain = self.network.blockchain()
@ -675,6 +684,10 @@ class ElectrumWindow(App):
interface = self.network.interface
if interface:
self.server_host = interface.host
else:
self.server_host = str(net_params.host) + ' (connecting...)'
self.proxy_config = net_params.proxy or {}
self.update_proxy_str(self.proxy_config)
def on_network_event(self, event, *args):
Logger.info('network event: '+ event)
@ -924,8 +937,11 @@ class ElectrumWindow(App):
self.wallet.invoices.save()
self.update_tab('invoices')
else:
msg = msg[:500] if msg else _('There was an error broadcasting the transaction.')
self.show_error(msg)
display_msg = _('The server returned an error when broadcasting the transaction.')
if msg:
display_msg += '\n' + msg
display_msg = display_msg[:500]
self.show_error(display_msg)
if self.network and self.network.is_connected():
self.show_info(_('Sending'))

View File

@ -24,10 +24,7 @@ Popup:
CardSeparator
SettingsItem:
proxy: app.proxy_config.get('mode')
host: app.proxy_config.get('host')
port: app.proxy_config.get('port')
title: _("Proxy") + ': ' + ((self.host +':' + self.port) if self.proxy else _('None'))
title: _("Proxy") + ': ' + app.proxy_str
description: _('Proxy configuration')
action: lambda x: app.popup_dialog('proxy')

View File

@ -73,5 +73,4 @@ Popup:
if proxy['mode']=='none': proxy = None
net_params = net_params._replace(proxy=proxy)
app.network.run_from_another_thread(app.network.set_parameters(net_params))
app.proxy_config = proxy if proxy else {}
nd.dismiss()

View File

@ -23,7 +23,7 @@ Popup:
height: '36dp'
size_hint_x: 3
size_hint_y: None
text: app.server_host
text: app.network.get_parameters().host
Label:
height: '36dp'
size_hint_x: 1
@ -36,7 +36,7 @@ Popup:
height: '36dp'
size_hint_x: 3
size_hint_y: None
text: app.server_port
text: app.network.get_parameters().port
Widget
Button:
id: chooser

View File

@ -152,8 +152,11 @@ class AddressList(MyTreeView):
is_multisig = isinstance(self.wallet, Multisig_Wallet)
can_delete = self.wallet.can_delete_address()
selected = self.selected_in_column(1)
if not selected:
return
multi_select = len(selected) > 1
addrs = [self.model().itemFromIndex(item).text() for item in selected]
menu = QMenu()
if not multi_select:
idx = self.indexAt(position)
col = idx.column()
@ -162,8 +165,6 @@ class AddressList(MyTreeView):
return
addr = addrs[0]
menu = QMenu()
if not multi_select:
addr_column_title = self.model().horizontalHeaderItem(2).text()
addr_idx = idx.sibling(idx.row(), 2)

View File

@ -57,7 +57,8 @@ class Exception_Window(BaseCrashReporter, QWidget, MessageBoxMixin):
collapse_info = QPushButton(_("Show report contents"))
collapse_info.clicked.connect(
lambda: self.msg_box(QMessageBox.NoIcon,
self, _("Report contents"), self.get_report_string()))
self, _("Report contents"), self.get_report_string(),
rich_text=True))
main_box.addWidget(collapse_info)

View File

@ -89,6 +89,7 @@ class HistoryModel(QAbstractItemModel, PrintError):
self.view = None # type: HistoryList
self.transactions = OrderedDictWithIndex()
self.tx_status_cache = {} # type: Dict[str, Tuple[int, str]]
self.summary = None
def set_view(self, history_list: 'HistoryList'):
# FIXME HistoryModel and HistoryList mutually depend on each other.

View File

@ -86,6 +86,7 @@ class StatusBarButton(QPushButton):
self.clicked.connect(self.onPress)
self.func = func
self.setIconSize(QSize(25,25))
self.setCursor(QCursor(Qt.PointingHandCursor))
def onPress(self, checked=False):
'''Drops the unwanted PyQt5 "checked" argument'''
@ -610,7 +611,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
_("Before reporting a bug, upgrade to the most recent version of Electrum (latest release or git HEAD), and include the version number in your report."),
_("Try to explain not only what the bug is, but how it occurs.")
])
self.show_message(msg, title="Electrum - " + _("Reporting Bugs"))
self.show_message(msg, title="Electrum - " + _("Reporting Bugs"), rich_text=True)
def notify_transactions(self):
if self.tx_notification_queue.qsize() == 0:
@ -1697,7 +1698,10 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.invoice_list.update()
self.do_clear()
else:
parent.show_error(msg)
display_msg = _('The server returned an error when broadcasting the transaction.')
if msg:
display_msg += '\n' + msg
parent.show_error(display_msg)
WaitingDialog(self, _('Broadcasting transaction...'),
broadcast_thread, broadcast_done, self.on_error)

View File

@ -190,24 +190,24 @@ class MessageBoxMixin(object):
parent, title or '',
msg, buttons=Yes|No, defaultButton=No) == Yes
def show_warning(self, msg, parent=None, title=None):
def show_warning(self, msg, parent=None, title=None, **kwargs):
return self.msg_box(QMessageBox.Warning, parent,
title or _('Warning'), msg)
title or _('Warning'), msg, **kwargs)
def show_error(self, msg, parent=None):
def show_error(self, msg, parent=None, **kwargs):
return self.msg_box(QMessageBox.Warning, parent,
_('Error'), msg)
_('Error'), msg, **kwargs)
def show_critical(self, msg, parent=None, title=None):
def show_critical(self, msg, parent=None, title=None, **kwargs):
return self.msg_box(QMessageBox.Critical, parent,
title or _('Critical Error'), msg)
title or _('Critical Error'), msg, **kwargs)
def show_message(self, msg, parent=None, title=None):
def show_message(self, msg, parent=None, title=None, **kwargs):
return self.msg_box(QMessageBox.Information, parent,
title or _('Information'), msg)
title or _('Information'), msg, **kwargs)
def msg_box(self, icon, parent, title, text, buttons=QMessageBox.Ok,
defaultButton=QMessageBox.NoButton):
defaultButton=QMessageBox.NoButton, rich_text=False):
parent = parent or self.top_level_window()
if type(icon) is QPixmap:
d = QMessageBox(QMessageBox.Information, title, str(text), buttons, parent)
@ -216,7 +216,12 @@ class MessageBoxMixin(object):
d = QMessageBox(icon, title, str(text), buttons, parent)
d.setWindowModality(Qt.WindowModal)
d.setDefaultButton(defaultButton)
d.setTextInteractionFlags(Qt.TextSelectableByMouse | Qt.LinksAccessibleByMouse)
if rich_text:
d.setTextInteractionFlags(Qt.TextSelectableByMouse| Qt.LinksAccessibleByMouse)
d.setTextFormat(Qt.RichText)
else:
d.setTextInteractionFlags(Qt.TextSelectableByMouse)
d.setTextFormat(Qt.PlainText)
return d.exec_()
class WindowModalDialog(QDialog, MessageBoxMixin):

View File

@ -206,7 +206,9 @@ class ElectrumGui:
try:
self.network.run_from_another_thread(self.network.broadcast_transaction(tx))
except Exception as e:
print(repr(e))
display_msg = _('The server returned an error when broadcasting the transaction.')
display_msg += '\n' + repr(e)
print(display_msg)
else:
print(_('Payment sent.'))
#self.do_clear()

View File

@ -15,7 +15,7 @@ from electrum.storage import WalletStorage
from electrum.network import NetworkParameters
from electrum.interface import deserialize_server
_ = lambda x:x
_ = lambda x:x # i18n
class ElectrumGui:
@ -370,7 +370,9 @@ class ElectrumGui:
try:
self.network.run_from_another_thread(self.network.broadcast_transaction(tx))
except Exception as e:
self.show_message(repr(e))
display_msg = _('The server returned an error when broadcasting the transaction.')
display_msg += '\n' + repr(e)
self.show_message(display_msg)
else:
self.show_message(_('Payment sent.'))
self.do_clear()

View File

@ -737,6 +737,7 @@ class Network(PrintError):
timeout = self.get_network_timeout_seconds(NetworkTimeout.Urgent)
out = await self.interface.session.send_request('blockchain.transaction.broadcast', [str(tx)], timeout=timeout)
if out != tx.txid():
# note: this is untrusted input from the server
raise Exception(out)
return out # txid

View File

@ -26,7 +26,7 @@
import threading
from PyQt5.Qt import QVBoxLayout, QLabel
from PyQt5.QtWidgets import QVBoxLayout, QLabel
from electrum.gui.qt.password_dialog import PasswordLayout, PW_PASSPHRASE
from electrum.gui.qt.util import *

View File

@ -1,9 +1,9 @@
from functools import partial
import threading
from PyQt5.Qt import Qt
from PyQt5.Qt import QGridLayout, QInputDialog, QPushButton
from PyQt5.Qt import QVBoxLayout, QLabel
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QGridLayout, QInputDialog, QPushButton
from PyQt5.QtWidgets import QVBoxLayout, QLabel
from electrum.gui.qt.util import *
from electrum.i18n import _

View File

@ -7,7 +7,7 @@ from binascii import hexlify, unhexlify
import websocket
from PyQt5.Qt import QDialog, QLineEdit, QTextEdit, QVBoxLayout, QLabel
from PyQt5.QtWidgets import QDialog, QLineEdit, QTextEdit, QVBoxLayout, QLabel
import PyQt5.QtCore as QtCore
from PyQt5.QtWidgets import *

View File

@ -170,19 +170,22 @@ class Plugin(RevealerPlugin):
code_id = self.versioned_seed.checksum
dialog.show_message(''.join([_("{} encrypted for Revealer {}_{} saved as PNG and PDF at: ").format(self.was, version, code_id),
"<b>", self.get_path_to_revealer_file(), "</b>", "<br/>",
"<br/>", "<b>", _("Always check you backups.")]))
"<br/>", "<b>", _("Always check you backups.")]),
rich_text=True)
dialog.close()
def ext_warning(self, dialog):
dialog.show_message(''.join(["<b>",_("Warning"), ": </b>",
_("your seed extension will <b>not</b> be included in the encrypted backup.")]))
_("your seed extension will <b>not</b> be included in the encrypted backup.")]),
rich_text=True)
dialog.close()
def bdone(self, dialog):
version = self.versioned_seed.version
code_id = self.versioned_seed.checksum
dialog.show_message(''.join([_("Digital Revealer ({}_{}) saved as PNG and PDF at:").format(version, code_id),
"<br/>","<b>", self.get_path_to_revealer_file(), '</b>']))
"<br/>","<b>", self.get_path_to_revealer_file(), '</b>']),
rich_text=True)
def customtxt_limits(self):
@ -208,7 +211,8 @@ class Plugin(RevealerPlugin):
.format(warning=_("Warning"),
ver0=_("Revealers starting with 0 are not secure due to a vulnerability."),
url=_("More info at: {}").format(f'<a href="{link}">{link}</a>'),
risk=_("Proceed at your own risk.")))
risk=_("Proceed at your own risk.")),
rich_text=True)
def cypherseed_dialog(self, window):
self.warn_old_revealer()

View File

@ -1,9 +1,9 @@
from functools import partial
import threading
from PyQt5.Qt import Qt
from PyQt5.Qt import QGridLayout, QInputDialog, QPushButton
from PyQt5.Qt import QVBoxLayout, QLabel
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QGridLayout, QInputDialog, QPushButton
from PyQt5.QtWidgets import QVBoxLayout, QLabel
from electrum.gui.qt.util import *
from electrum.i18n import _

View File

@ -1,9 +1,9 @@
from functools import partial
import threading
from PyQt5.Qt import Qt
from PyQt5.Qt import QGridLayout, QInputDialog, QPushButton
from PyQt5.Qt import QVBoxLayout, QLabel
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QGridLayout, QInputDialog, QPushButton
from PyQt5.QtWidgets import QVBoxLayout, QLabel
from electrum.gui.qt.util import *
from electrum.i18n import _

View File

@ -45,7 +45,7 @@ from electrum.mnemonic import Mnemonic
from electrum.wallet import Multisig_Wallet, Deterministic_Wallet
from electrum.i18n import _
from electrum.plugin import BasePlugin, hook
from electrum.util import NotEnoughFunds
from electrum.util import NotEnoughFunds, UserFacingException
from electrum.storage import STO_EV_USER_PW
from electrum.network import Network
@ -319,7 +319,13 @@ class Wallet_2fa(Multisig_Wallet):
otp = int(otp)
long_user_id, short_id = self.get_user_id()
raw_tx = tx.serialize()
r = server.sign(short_id, raw_tx, otp)
try:
r = server.sign(short_id, raw_tx, otp)
except TrustedCoinException as e:
if e.status_code == 400: # invalid OTP
raise UserFacingException(_('Invalid one-time password.')) from e
else:
raise
if r:
raw_tx = r.get('transaction')
tx.update(raw_tx)

View File

@ -1,5 +1,5 @@
ELECTRUM_VERSION = '3.3.1' # version of the client package
APK_VERSION = '3.3.1.0' # read by buildozer.spec
ELECTRUM_VERSION = '3.3.2' # version of the client package
APK_VERSION = '3.3.2.0' # read by buildozer.spec
PROTOCOL_VERSION = '1.4' # protocol version requested

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

BIN
icons/clock5.pdn Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB