From 184a9d68d86eefd2738ba60ff5f43f72b334ef9a Mon Sep 17 00:00:00 2001 From: zebra-lucky Date: Fri, 6 Apr 2018 02:42:04 +0300 Subject: [PATCH] integrate electrum-3.0.6 changes --- RELEASE-NOTES | 4 ++++ electrum-zcash | 3 ++- gui/kivy/main_window.py | 8 +++++-- gui/qt/address_dialog.py | 2 +- gui/qt/main_window.py | 28 +++++++++++++++++++----- gui/qt/qrcodewidget.py | 3 +-- gui/stdio.py | 16 +++++++------- icons/unpaid.png | Bin 27679 -> 23805 bytes lib/commands.py | 8 +++---- lib/exchange_rate.py | 7 +++++- lib/mnemonic.py | 5 ++++- lib/transaction.py | 13 +++++++++-- lib/version.py | 2 +- lib/wallet.py | 3 ++- lib/websockets.py | 14 +++++++----- plugins/ledger/ledger.py | 45 ++++++++++++++++++++++++++++----------- 16 files changed, 113 insertions(+), 48 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index de06fbe7..6a2adb12 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,7 @@ +# Release 3.0.6 : + + * Integrate changes from Electrum-3.0.6 + # Release 3.0.5 : (Security update) This is a follow-up to the 3.0.4 release, which did not completely fix diff --git a/electrum-zcash b/electrum-zcash index 706e90ea..de05f2a3 100755 --- a/electrum-zcash +++ b/electrum-zcash @@ -278,7 +278,8 @@ def run_offline_command(config, config_options): # arguments passed to function args = [config.get(x) for x in cmd.params] # decode json arguments - args = list(map(json_decode, args)) + if cmdname not in ('setconfig',): + args = list(map(json_decode, args)) # options kwargs = {} for x in cmd.options: diff --git a/gui/kivy/main_window.py b/gui/kivy/main_window.py index 269fe395..38ee1ffe 100644 --- a/gui/kivy/main_window.py +++ b/gui/kivy/main_window.py @@ -923,6 +923,10 @@ class ElectrumWindow(App): return if not self.wallet.can_export(): return - key = str(self.wallet.export_private_key(addr, password)[0]) - pk_label.data = key + try: + key = str(self.wallet.export_private_key(addr, password)[0]) + pk_label.data = key + except InvalidPassword: + self.show_error("Invalid PIN") + return self.protected(_("Enter your PIN code in order to decrypt your private key"), show_private_key, (addr, pk_label)) diff --git a/gui/qt/address_dialog.py b/gui/qt/address_dialog.py index c5c9503c..c3bbbdd6 100644 --- a/gui/qt/address_dialog.py +++ b/gui/qt/address_dialog.py @@ -93,6 +93,6 @@ class AddressDialog(WindowModalDialog): def show_qr(self): text = self.address try: - self.parent.show_qrcode(text, 'Address') + self.parent.show_qrcode(text, 'Address', parent=self) except Exception as e: self.show_message(str(e)) diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py index 9cac3493..66fde53b 100644 --- a/gui/qt/main_window.py +++ b/gui/qt/main_window.py @@ -2135,6 +2135,10 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): self.show_message(_("This is a watching-only wallet")) return + if isinstance(self.wallet, Multisig_Wallet): + self.show_message(_('WARNING: This is a multi-signature wallet.') + '\n' + + _('It can not be "backed up" by simply exporting these private keys.')) + d = WindowModalDialog(self, _('Private keys')) d.setMinimumSize(850, 300) vbox = QVBoxLayout(d) @@ -2160,25 +2164,38 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): private_keys = {} addresses = self.wallet.get_addresses() done = False + cancelled = False def privkeys_thread(): for addr in addresses: time.sleep(0.1) - if done: + if done or cancelled: break privkey = self.wallet.export_private_key(addr, password)[0] private_keys[addr] = privkey self.computing_privkeys_signal.emit() - self.computing_privkeys_signal.disconnect() - self.show_privkeys_signal.emit() + if not cancelled: + self.computing_privkeys_signal.disconnect() + self.show_privkeys_signal.emit() def show_privkeys(): s = "\n".join( map( lambda x: x[0] + "\t"+ x[1], private_keys.items())) e.setText(s) b.setEnabled(True) self.show_privkeys_signal.disconnect() + nonlocal done + done = True + + def on_dialog_closed(*args): + nonlocal done + nonlocal cancelled + if not done: + cancelled = True + self.computing_privkeys_signal.disconnect() + self.show_privkeys_signal.disconnect() self.computing_privkeys_signal.connect(lambda: e.setText("Please wait... %d/%d"%(len(private_keys),len(addresses)))) self.show_privkeys_signal.connect(show_privkeys) + d.finished.connect(on_dialog_closed) threading.Thread(target=privkeys_thread).start() if not d.exec_(): @@ -2549,7 +2566,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): unit_combo = QComboBox() unit_combo.addItems(units) unit_combo.setCurrentIndex(units.index(self.base_unit())) - def on_unit(x): + def on_unit(x, nz): unit_result = units[unit_combo.currentIndex()] if self.base_unit() == unit_result: return @@ -2564,13 +2581,14 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): else: raise Exception('Unknown base unit') self.config.set_key('decimal_point', self.decimal_point, True) + nz.setMaximum(self.decimal_point) self.history_list.update() self.request_list.update() self.address_list.update() for edit, amount in zip(edits, amounts): edit.setAmount(amount) self.update_status() - unit_combo.currentIndexChanged.connect(on_unit) + unit_combo.currentIndexChanged.connect(lambda x: on_unit(x, nz)) gui_widgets.append((unit_label, unit_combo)) block_explorers = sorted(util.block_explorer_info().keys()) diff --git a/gui/qt/qrcodewidget.py b/gui/qt/qrcodewidget.py index 0d1cc77a..4a53290f 100644 --- a/gui/qt/qrcodewidget.py +++ b/gui/qt/qrcodewidget.py @@ -113,8 +113,7 @@ class QRDialog(WindowModalDialog): def copy_to_clipboard(): p = qscreen.grabWindow(qrw.winId()) - p.save(filename, 'png') - QApplication.clipboard().setImage(QImage(filename)) + QApplication.clipboard().setPixmap(p) self.show_message(_("QR code copied to clipboard")) b = QPushButton(_("Copy")) diff --git a/gui/stdio.py b/gui/stdio.py index 77f12153..ac9c43c3 100644 --- a/gui/stdio.py +++ b/gui/stdio.py @@ -85,12 +85,11 @@ class ElectrumGui: delta = (80 - sum(width) - 4)/3 format_str = "%"+"%d"%width[0]+"s"+"%"+"%d"%(width[1]+delta)+"s"+"%" \ + "%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s" - b = 0 messages = [] for item in self.wallet.get_history(): - tx_hash, confirmations, value, timestamp, balance = item - if confirmations: + tx_hash, height, conf, timestamp, delta, balance = item + if conf: try: time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] except Exception: @@ -99,7 +98,7 @@ class ElectrumGui: time_str = 'unconfirmed' label = self.wallet.get_label(tx_hash) - messages.append( format_str%( time_str, label, format_satoshis(value, whitespaces=True), format_satoshis(balance, whitespaces=True) ) ) + messages.append( format_str%( time_str, label, format_satoshis(delta, whitespaces=True), format_satoshis(balance, whitespaces=True) ) ) self.print_list(messages[::-1], format_str%( _("Date"), _("Description"), _("Amount"), _("Balance"))) @@ -149,12 +148,13 @@ class ElectrumGui: for i, x in enumerate( self.wallet.network.banner.split('\n') ): print( x ) - def print_list(self, list, firstline): - self.maxpos = len(list) + def print_list(self, lst, firstline): + lst = list(lst) + self.maxpos = len(lst) if not self.maxpos: return print(firstline) for i in range(self.maxpos): - msg = list[i] if i < len(list) else "" + msg = lst[i] if i < len(lst) else "" print(msg) @@ -176,7 +176,7 @@ class ElectrumGui: print(_('Invalid Fee')) return - if self.wallet.use_encryption: + if self.wallet.has_password(): password = self.password_dialog() if not password: return diff --git a/icons/unpaid.png b/icons/unpaid.png index e0f3639df66d088a384073442d6451b0f34ecfaa..579ec4eb533866a6d97ee922e15257446649c66f 100644 GIT binary patch literal 23805 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
8K2Dws_YGPuXD)jzB_2(rO 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 diff --git a/lib/commands.py b/lib/commands.py index 91d994ea..e20f2097 100644 --- a/lib/commands.py +++ b/lib/commands.py @@ -34,7 +34,7 @@ from functools import wraps from decimal import Decimal from .import util -from .util import bfh, bh2u, format_satoshis +from .util import bfh, bh2u, format_satoshis, json_decode from .import bitcoin from .bitcoin import is_address, hash_160, COIN, TYPE_ADDRESS from .i18n import _ @@ -151,10 +151,8 @@ class Commands: @command('') def setconfig(self, key, value): """Set a configuration variable. 'value' may be a string or a Python expression.""" - try: - value = ast.literal_eval(value) - except: - pass + if key not in ('rpcuser', 'rpcpassword'): + value = json_decode(value) self.config.set_key(key, value) return True diff --git a/lib/exchange_rate.py b/lib/exchange_rate.py index 84dfb92a..f2cdcac1 100644 --- a/lib/exchange_rate.py +++ b/lib/exchange_rate.py @@ -5,6 +5,7 @@ import sys from threading import Thread import time import csv +import decimal from decimal import Decimal from .bitcoin import COIN @@ -197,7 +198,11 @@ class FxThread(ThreadJob): def ccy_amount_str(self, amount, commas): prec = CCY_PRECISIONS.get(self.ccy, 2) fmt_str = "{:%s.%df}" % ("," if commas else "", max(0, prec)) - return fmt_str.format(round(amount, prec)) + try: + rounded_amount = round(amount, prec) + except decimal.InvalidOperation: + rounded_amount = amount + return fmt_str.format(rounded_amount) def run(self): # This runs from the plugins thread which catches exceptions diff --git a/lib/mnemonic.py b/lib/mnemonic.py index 10e0e08b..7096e20f 100644 --- a/lib/mnemonic.py +++ b/lib/mnemonic.py @@ -171,7 +171,10 @@ class Mnemonic(object): n_custom = int(math.ceil(math.log(custom_entropy, 2))) n = max(16, num_bits - n_custom) print_error("make_seed", prefix, "adding %d bits"%n) - my_entropy = ecdsa.util.randrange(pow(2, n)) + my_entropy = 1 + while my_entropy < pow(2, n - bpw): + # try again if seed would not contain enough words + my_entropy = ecdsa.util.randrange(pow(2, n)) nonce = 0 while True: nonce += 1 diff --git a/lib/transaction.py b/lib/transaction.py index 4720f735..1859b9a0 100644 --- a/lib/transaction.py +++ b/lib/transaction.py @@ -45,6 +45,14 @@ class SerializationError(Exception): """ Thrown when there's a problem deserializing or serializing """ +class UnknownTxinType(Exception): + pass + + +class NotRecognizedRedeemScript(Exception): + pass + + class BCDataStream(object): def __init__(self): self.input = None @@ -302,7 +310,8 @@ def parse_scriptSig(d, _bytes): if match_decoded(decoded, match): item = decoded[0][1] if item[0] != 0: - # payto_pubkey + # assert item[0] == 0x30 + # pay-to-pubkey d['type'] = 'p2pk' d['address'] = "(pubkey)" d['signatures'] = [bh2u(item)] @@ -358,7 +367,7 @@ def parse_redeemScript(s): match_multisig = [ op_m ] + [opcodes.OP_PUSHDATA4]*n + [ op_n, opcodes.OP_CHECKMULTISIG ] if not match_decoded(dec2, match_multisig): print_error("cannot find address in input script", bh2u(s)) - return + raise NotRecognizedRedeemScript() x_pubkeys = [bh2u(x[1]) for x in dec2[1:-2]] pubkeys = [safe_parse_pubkey(x) for x in x_pubkeys] redeemScript = multisig_script(pubkeys, m) diff --git a/lib/version.py b/lib/version.py index 15ad3699..22864a33 100644 --- a/lib/version.py +++ b/lib/version.py @@ -1,4 +1,4 @@ -ELECTRUM_VERSION = '3.0.5' # version of the client package +ELECTRUM_VERSION = '3.0.6' # version of the client package PROTOCOL_VERSION = '1.2' # protocol version requested # The hash of the mnemonic seed must begin with this diff --git a/lib/wallet.py b/lib/wallet.py index 1a58d9ca..5ef81bd5 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -360,7 +360,8 @@ class Abstract_Wallet(PrintError): def add_unverified_tx(self, tx_hash, tx_height): if tx_height == 0 and tx_hash in self.verified_tx: self.verified_tx.pop(tx_hash) - self.verifier.merkle_roots.pop(tx_hash, None) + if self.verifier: + self.verifier.merkle_roots.pop(tx_hash, None) # tx will be verified only if height > 0 if tx_hash not in self.verified_tx: diff --git a/lib/websockets.py b/lib/websockets.py index f2bd9149..415556b3 100644 --- a/lib/websockets.py +++ b/lib/websockets.py @@ -84,7 +84,8 @@ class WsClientThread(util.DaemonThread): l = self.subscriptions.get(addr, []) l.append((ws, amount)) self.subscriptions[addr] = l - self.network.send([('blockchain.address.subscribe', [addr])], self.response_queue.put) + h = self.network.addr_to_scripthash(addr) + self.network.send([('blockchain.scripthash.subscribe', [h])], self.response_queue.put) def run(self): @@ -100,10 +101,13 @@ class WsClientThread(util.DaemonThread): result = r.get('result') if result is None: continue - if method == 'blockchain.address.subscribe': - self.network.send([('blockchain.address.get_balance', params)], self.response_queue.put) - elif method == 'blockchain.address.get_balance': - addr = params[0] + if method == 'blockchain.scripthash.subscribe': + self.network.send([('blockchain.scripthash.get_balance', params)], self.response_queue.put) + elif method == 'blockchain.scripthash.get_balance': + h = params[0] + addr = self.network.h2addr.get(h, None) + if addr is None: + util.print_error("can't find address for scripthash: %s" % h) l = self.subscriptions.get(addr, []) for ws, amount in l: if not ws.closed: diff --git a/plugins/ledger/ledger.py b/plugins/ledger/ledger.py index 10358667..3f2c7616 100644 --- a/plugins/ledger/ledger.py +++ b/plugins/ledger/ledger.py @@ -33,6 +33,10 @@ try: except ImportError: BTCHIP = False +MSG_NEEDS_FW_UPDATE_GENERIC = _('Firmware version too old. Please update at') + \ + ' https://www.ledgerwallet.com' + + class Ledger_Client(): def __init__(self, hidDevice): self.dongleObject = btchip(hidDevice) @@ -54,8 +58,23 @@ class Ledger_Client(): return "" def i4b(self, x): - return pack('>I', x) + return pack('>I', x) + def test_pin_unlocked(func): + """Function decorator to test the Ledger for being unlocked, and if not, + raise a human-readable exception. + """ + def catch_exception(self, *args, **kwargs): + try: + return func(self, *args, **kwargs) + except BTChipException as e: + if e.sw == 0x6982: + raise Exception(_('Your Ledger is locked. Please unlock it.')) + else: + raise + return catch_exception + + @test_pin_unlocked def get_xpub(self, bip32_path, xtype): self.checkDevice() # bip32_path is of the form 44'/133'/1' @@ -72,7 +91,7 @@ class Ledger_Client(): if len(splitPath) > 1: prevPath = "/".join(splitPath[0:len(splitPath) - 1]) nodeData = self.dongleObject.getWalletPublicKey(prevPath) - publicKey = compress_public_key(nodeData['publicKey'])# + publicKey = compress_public_key(nodeData['publicKey']) h = hashlib.new('ripemd160') h.update(hashlib.sha256(publicKey).digest()) fingerprint = unpack(">I", h.digest()[0:4])[0] @@ -117,7 +136,7 @@ class Ledger_Client(): if not checkFirmware(firmware): self.dongleObject.dongle.close() - raise Exception("HW1 firmware version too old. Please update at https://www.ledgerwallet.com") + raise Exception(MSG_NEEDS_FW_UPDATE_GENERIC) try: self.dongleObject.getOperationMode() except BTChipException as e: @@ -184,14 +203,14 @@ class Ledger_KeyStore(Hardware_KeyStore): return obj def get_derivation(self): - return self.derivation + return self.derivation def get_client(self): return self.plugin.get_client(self).dongleObject - + def get_client_electrum(self): return self.plugin.get_client(self) - + def give_error(self, message, clear_client = False): print_error(message) if not self.signing: @@ -336,7 +355,7 @@ class Ledger_KeyStore(Hardware_KeyStore): self.handler.show_message(_("Confirm Transaction on your Ledger device...")) try: # Get trusted inputs from the original transactions - for utxo in inputs: + for utxo in inputs: sequence = int_to_hex(utxo[5], 4) if not p2shTransaction: txtmp = bitcoinTransaction(bfh(utxo[0])) @@ -398,7 +417,7 @@ class LedgerPlugin(HW_PluginBase): libraries_available = BTCHIP keystore_class = Ledger_KeyStore client = None - DEVICE_IDS = [ + DEVICE_IDS = [ (0x2581, 0x1807), # HW.1 legacy btchip (0x2581, 0x2b7c), # HW.1 transitional production (0x2581, 0x3b7c), # HW.1 ledger production @@ -422,12 +441,12 @@ class LedgerPlugin(HW_PluginBase): def get_btchip_device(self, device): ledger = False if (device.product_key[0] == 0x2581 and device.product_key[1] == 0x3b7c) or (device.product_key[0] == 0x2581 and device.product_key[1] == 0x4b7c) or (device.product_key[0] == 0x2c97): - ledger = True + ledger = True dev = hid.device() dev.open_path(device.path) dev.set_nonblocking(True) return HIDDongleHIDAPI(dev, ledger, BTCHIP_DEBUG) - + def create_client(self, device, handler): self.handler = handler @@ -436,7 +455,7 @@ class LedgerPlugin(HW_PluginBase): client = Ledger_Client(client) return client - def setup_device(self, device_info, wizard): + def setup_device(self, device_info, wizard): devmgr = self.device_manager() device_id = device_info.device.id_ client = devmgr.client_by_id(device_id) @@ -457,10 +476,10 @@ class LedgerPlugin(HW_PluginBase): devmgr = self.device_manager() handler = keystore.handler with devmgr.hid_lock: - client = devmgr.client_for_keystore(self, handler, keystore, force_pair) + client = devmgr.client_for_keystore(self, handler, keystore, force_pair) # returns the client for a given keystore. can use xpub #if client: # client.used() if client is not None: - client.checkDevice() + client.checkDevice() return client