Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
wakiyamap committed Mar 12, 2018
2 parents cc97474 + c3e26a1 commit b0e6276
Show file tree
Hide file tree
Showing 20 changed files with 155 additions and 113 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ env/
.tox/
.buildozer/
bin/
/app.fil

# tox files
.cache/
Expand Down
1 change: 0 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ recursive-include gui *.py
recursive-include plugins *.py
recursive-include packages *.py
recursive-include packages cacert.pem
include app.fil
include icons.qrc
recursive-include icons *
recursive-include scripts *
Expand Down
29 changes: 0 additions & 29 deletions app.fil

This file was deleted.

13 changes: 12 additions & 1 deletion contrib/make_locale
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
#!/usr/bin/env python3
import os
import subprocess
import io
import zipfile
import requests

os.chdir(os.path.dirname(os.path.realpath(__file__)))
os.chdir('..')

code_directories = 'gui plugins lib'
cmd = "find {} -type f -name '*.py' -o -name '*.kv'".format(code_directories)

files = subprocess.check_output(cmd, shell=True)

with open("app.fil", "wb") as f:
f.write(files)

print("Found {} files to translate".format(len(files.splitlines())))

# Generate fresh translation template
if not os.path.exists('lib/locale'):
os.mkdir('lib/locale')
cmd = 'xgettext -s --no-wrap -f app.fil --output=lib/locale/messages.pot'
cmd = 'xgettext -s --from-code UTF-8 --language Python --no-wrap -f app.fil --output=lib/locale/messages.pot'
print('Generate template')
os.system(cmd)

Expand Down
5 changes: 2 additions & 3 deletions gui/qt/installwizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ def on_filename(filename):
try:
self.storage = WalletStorage(path, manual_upgrades=True)
self.next_button.setEnabled(True)
except IOError:
except BaseException:
traceback.print_exc(file=sys.stderr)
self.storage = None
self.next_button.setEnabled(False)
if self.storage:
Expand Down Expand Up @@ -245,8 +246,6 @@ def on_filename(filename):
try:
self.run('choose_hw_device', HWD_SETUP_DECRYPT_WALLET)
except InvalidPassword as e:
# FIXME if we get here because of mistyped passphrase
# then that passphrase gets "cached"
QMessageBox.information(
None, _('Error'),
_('Failed to decrypt using this hardware device.') + '\n' +
Expand Down
2 changes: 1 addition & 1 deletion gui/qt/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -1171,7 +1171,7 @@ def feerounding_onclick():
self.fee_adv_controls.setVisible(False)

self.preview_button = EnterButton(_("Preview"), self.do_preview)
self.preview_button.setToolTip(_('Display the details of your transactions before signing it.'))
self.preview_button.setToolTip(_('Display the details of your transaction before signing it.'))
self.send_button = EnterButton(_("Send"), self.do_send)
self.clear_button = EnterButton(_("Clear"), self.do_clear)
buttons = QHBoxLayout()
Expand Down
4 changes: 2 additions & 2 deletions gui/qt/transaction_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,8 @@ def sign_done(success):
if success:
self.prompt_if_unsaved = True
self.saved = False
self.save_button.setDisabled(False)
self.save_button.setToolTip("")
self.save_button.setDisabled(False)
self.save_button.setToolTip("")
self.update()
self.main_window.pop_top_level_window(self)

Expand Down
14 changes: 11 additions & 3 deletions lib/base_wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
from .wallet import Imported_Wallet, Standard_Wallet, Multisig_Wallet, wallet_types
from .storage import STO_EV_USER_PW, STO_EV_XPUB_PW, get_derivation_used_for_hw_device_encryption
from .i18n import _
from .util import UserCancelled
from .util import UserCancelled, InvalidPassword

# hardware device setup purpose
HWD_SETUP_NEW_WALLET, HWD_SETUP_DECRYPT_WALLET = range(0, 2)
Expand Down Expand Up @@ -164,7 +164,7 @@ def on_import(self, text):
k = keystore.Imported_KeyStore({})
self.storage.put('keystore', k.dump())
w = Imported_Wallet(self.storage)
for x in text.split():
for x in keystore.get_private_keys(text):
w.import_private_key(x, None)
self.keystores.append(w.keystore)
else:
Expand Down Expand Up @@ -259,7 +259,15 @@ def on_device(self, name, device_info, *, purpose):
derivation = get_derivation_used_for_hw_device_encryption()
xpub = self.plugin.get_xpub(device_info.device.id_, derivation, 'standard', self)
password = keystore.Xpub.get_pubkey_from_xpub(xpub, ())
self.storage.decrypt(password)
try:
self.storage.decrypt(password)
except InvalidPassword:
# try to clear session so that user can type another passphrase
devmgr = self.plugins.device_manager
client = devmgr.client_by_id(device_info.device.id_)
if hasattr(client, 'clear_session'): # FIXME not all hw wallet plugins have this
client.clear_session()
raise
else:
raise Exception('unknown purpose: %s' % purpose)

Expand Down
19 changes: 14 additions & 5 deletions lib/bitcoin.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,10 @@ def base_decode(v, length, base):
chars = __b43chars
long_value = 0
for (i, c) in enumerate(v[::-1]):
long_value += chars.find(bytes([c])) * (base**i)
digit = chars.find(bytes([c]))
if digit == -1:
raise ValueError('Forbidden character {} for base {}'.format(c, base))
long_value += digit * (base**i)
result = bytearray()
while long_value >= 256:
div, mod = divmod(long_value, 256)
Expand All @@ -428,6 +431,10 @@ def base_decode(v, length, base):
return bytes(result)


class InvalidChecksum(Exception):
pass


def EncodeBase58Check(vchIn):
hash = Hash(vchIn)
return base_encode(vchIn + hash[0:4], base=58)
Expand All @@ -440,7 +447,7 @@ def DecodeBase58Check(psz):
hash = Hash(key)
cs32 = hash[0:4]
if cs32 != csum:
return None
raise InvalidChecksum('expected {}, actual {}'.format(bh2u(cs32), bh2u(csum)))
else:
return key

Expand Down Expand Up @@ -479,9 +486,11 @@ def deserialize_privkey(key):
if ':' in key:
txin_type, key = key.split(sep=':', maxsplit=1)
assert txin_type in SCRIPT_TYPES
vch = DecodeBase58Check(key)
if not vch:
raise BaseException("cannot deserialize", key)
try:
vch = DecodeBase58Check(key)
except BaseException:
neutered_privkey = str(key)[:3] + '..' + str(key)[-2:]
raise BaseException("cannot deserialize", neutered_privkey)

if txin_type is None:
# keys exported in version 3.0.x encoded script type in first byte
Expand Down
2 changes: 1 addition & 1 deletion lib/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def get_socket(self):
context = self.get_ssl_context(cert_reqs=ssl.CERT_REQUIRED, ca_certs=ca_path)
s = context.wrap_socket(s, do_handshake_on_connect=True)
except ssl.SSLError as e:
print_error(e)
self.print_error(e)
s = None
except:
return
Expand Down
2 changes: 1 addition & 1 deletion lib/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ def process_pending_sends(self):
# check cached response for subscriptions
r = self.sub_cache.get(k)
if r is not None:
util.print_error("cache hit", k)
self.print_error("cache hit", k)
callback(r)
else:
message_id = self.queue_request(method, params)
Expand Down
10 changes: 3 additions & 7 deletions lib/plot.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
from PyQt5.QtGui import *
from electrum_mona.i18n import _


import datetime
from collections import defaultdict
from electrum_mona.bitcoin import COIN

import matplotlib
matplotlib.use('Qt5Agg')
import matplotlib.pyplot as plt
import matplotlib.dates as md
from matplotlib.patches import Ellipse
from matplotlib.offsetbox import AnchoredOffsetbox, TextArea, DrawingArea, HPacker

from .i18n import _
from .bitcoin import COIN


class NothingToPlotException(Exception):
Expand Down
2 changes: 1 addition & 1 deletion lib/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ def select_device(self, plugin, handler, keystore, devices=None):
if info.label == keystore.label:
return info
msg = _("Please select which {} device to use:").format(plugin.device)
descriptions = [info.label + ' (%s)'%(_("initialized") if info.initialized else _("wiped")) for info in infos]
descriptions = [str(info.label) + ' (%s)'%(_("initialized") if info.initialized else _("wiped")) for info in infos]
c = handler.query_choice(msg, descriptions)
if c is None:
raise UserCancelled()
Expand Down
4 changes: 3 additions & 1 deletion lib/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
def multisig_type(wallet_type):
'''If wallet_type is mofn multi-sig, return [m, n],
otherwise return None.'''
if not wallet_type:
return None
match = re.match('(\d+)of(\d+)', wallet_type)
if match:
match = [int(x) for x in match.group(1, 2)]
Expand Down Expand Up @@ -417,7 +419,7 @@ def convert_wallet_type(self):
d['seed'] = seed
self.put(key, d)
else:
raise
raise Exception('Unable to tell wallet type. Is this even a wallet file?')
# remove junk
self.put('master_public_key', None)
self.put('master_public_keys', None)
Expand Down
29 changes: 28 additions & 1 deletion lib/tests/test_bitcoin.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
var_int, op_push, address_to_script, regenerate_key,
verify_message, deserialize_privkey, serialize_privkey, is_segwit_address,
is_b58_address, address_to_scripthash, is_minikey, is_compressed, is_xpub,
xpub_type, is_xprv, is_bip32_derivation, seed_type, deserialize_privkey_old)
xpub_type, is_xprv, is_bip32_derivation, seed_type, deserialize_privkey_old, is_private_key_old)
from lib.util import bfh
from lib import constants

Expand Down Expand Up @@ -376,6 +376,25 @@ class Test_keyImport(unittest.TestCase):
'scripthash': '60ad5a8b922f758cd7884403e90ee7e6f093f8d21a0ff24c9a865e695ccefdf1'},
)

priv_pub_addr_old = (
{'priv': 'TNsb2t6wGVTrZCeeTP5C9eEA3UdqQpDCaYQYbEof1wPuTDzLsbni',
'exported_privkey': 'p2pkh:TNsb2t6wGVTrZCeeTP5C9eEA3UdqQpDCaYQYbEof1wPuTDzLsbni',
'pub': '03581803a5795674e8ba65765d7d8bc4c89ce96835e19538437390b010a0e693f7',
'address': 'MKLkoVY9am6aRxTeCAzVrywyg8PC5uQVPW',
'minikey' : False,
'txin_type': 'p2pkh',
'compressed': True,
'addr_encoding': 'base58'},
{'priv': 'TNsb2t6wGVTrZCeeTP5C9eEA3UdqQpDCaYQYbEof1wPuTDzLsbni',
'exported_privkey': 'TNsb2t6wGVTrZCeeTP5C9eEA3UdqQpDCaYQYbEof1wPuTDzLsbni',
'pub': '03581803a5795674e8ba65765d7d8bc4c89ce96835e19538437390b010a0e693f7',
'address': 'MKLkoVY9am6aRxTeCAzVrywyg8PC5uQVPW',
'minikey' : False,
'txin_type': 'p2pkh',
'compressed': True,
'addr_encoding': 'base58'}
)

def test_public_key_from_private_key(self):
for priv_details in self.priv_pub_addr:
txin_type, privkey, compressed = deserialize_privkey(priv_details['priv'])
Expand Down Expand Up @@ -412,6 +431,14 @@ def test_is_private_key(self):
self.assertFalse(is_private_key(priv_details['address']))
self.assertFalse(is_private_key("not a privkey"))

def test_is_private_key_old(self):
for priv_details in self.priv_pub_addr_old:
self.assertTrue(is_private_key_old(priv_details['priv']))
self.assertTrue(is_private_key_old(priv_details['exported_privkey']))
self.assertFalse(is_private_key_old(priv_details['pub']))
self.assertFalse(is_private_key_old(priv_details['address']))
self.assertFalse(is_private_key_old("not a privkey"))

def test_serialize_privkey(self):
for priv_details in self.priv_pub_addr:
txin_type, privkey, compressed = deserialize_privkey(priv_details['priv'])
Expand Down

0 comments on commit b0e6276

Please sign in to comment.