electrum

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

commit b3a67f7a1f888d6151b36cdab2fc450c8f46e05c
parent 2829de5d49460cfdc68a8e4eb371ecdfda0e2b3d
Author: ThomasV <thomasv@electrum.org>
Date:   Tue, 13 Feb 2018 09:47:30 +0100

Merge branch 'master' of github.com:spesmilo/electrum

Diffstat:
M.travis.yml | 2+-
Mcontrib/build-osx/make_osx | 10++++------
Mcontrib/build-wine/prepare-wine.sh | 19++++---------------
Acontrib/deterministic-build/requirements-binaries.txt | 6++++++
Mcontrib/freeze_packages.sh | 33++++++++-------------------------
Acontrib/requirements/requirements-binaries.txt | 4++++
Rrequirements-hw.txt -> contrib/requirements/requirements-hw.txt | 0
Rrequirements_travis.txt -> contrib/requirements/requirements-travis.txt | 0
Acontrib/requirements/requirements.txt | 9+++++++++
Mgui/kivy/uix/dialogs/bump_fee_dialog.py | 2+-
Mgui/kivy/uix/dialogs/fee_dialog.py | 4++--
Mgui/kivy/uix/screens.py | 7++++++-
Mgui/kivy/uix/ui_screens/address.kv | 6+++---
Mgui/qt/fee_slider.py | 6+++---
Mgui/qt/main_window.py | 4++--
Mlib/simple_config.py | 6+++---
Mlib/wallet.py | 18+++++-------------
Msetup.py | 19++++++-------------
18 files changed, 67 insertions(+), 88 deletions(-)

diff --git a/.travis.yml b/.travis.yml @@ -4,7 +4,7 @@ python: - 3.5 - 3.6 install: - - pip install -r requirements_travis.txt + - pip install -r contrib/requirements/requirements-travis.txt cache: - pip script: diff --git a/contrib/build-osx/make_osx b/contrib/build-osx/make_osx @@ -20,7 +20,7 @@ PYTHON_VERSION=3.6.4 info "Installing Python $PYTHON_VERSION" -export PATH="~/.pyenv/bin:~/.pyenv/shims:$PATH:~/Library/Python/3.6/bin" +export PATH="~/.pyenv/bin:~/.pyenv/shims:~/Library/Python/3.6/bin:$PATH" if [ -d "~/.pyenv" ]; then pyenv update else @@ -31,10 +31,8 @@ pyenv global $PYTHON_VERSION || \ fail "Unable to use Python $PYTHON_VERSION" -if ! which pyinstaller > /dev/null; then - info "Installing pyinstaller" - python3 -m pip install pyinstaller -I --user || fail "Could not install pyinstaller" -fi +info "Installing pyinstaller" +python3 -m pip install pyinstaller -I --user || fail "Could not install pyinstaller" info "Using these versions for building Electrum:" sw_vers @@ -58,7 +56,7 @@ cp /tmp/electrum-build/electrum-icons/icons_rc.py ./gui/qt/ info "Installing requirements..." python3 -m pip install -Ir ./contrib/deterministic-build/requirements.txt --user && \ -python3 -m pip install pyqt5 --user || \ +python3 -m pip install -Ir ./contrib/deterministic-build/requirements-binaries.txt --user || \ fail "Could not install requirements" info "Installing hardware wallet requirements..." diff --git a/contrib/build-wine/prepare-wine.sh b/contrib/build-wine/prepare-wine.sh @@ -73,27 +73,17 @@ done $PYTHON -m pip install pip --upgrade # Install pywin32-ctypes (needed by pyinstaller) -$PYTHON -m pip install pywin32-ctypes +$PYTHON -m pip install pywin32-ctypes==0.1.2 -# Install PyQt -$PYTHON -m pip install PyQt5 - -## Install pyinstaller -#$PYTHON -m pip install pyinstaller==3.3 +# install PySocks +$PYTHON -m pip install win_inet_pton==1.0.1 +$PYTHON -m pip install -r ../../deterministic-build/requirements-binaries.txt # Install ZBar #wget -q -O zbar.exe "https://sourceforge.net/projects/zbar/files/zbar/0.10/zbar-0.10-setup.exe/download" #wine zbar.exe -# install Cryptodome -$PYTHON -m pip install pycryptodomex - -# install PySocks -$PYTHON -m pip install win_inet_pton - -# install websocket (python2) -$PYTHON -m pip install websocket-client # Upgrade setuptools (so Electrum can be installed later) $PYTHON -m pip install setuptools --upgrade @@ -111,5 +101,4 @@ wine nsis.exe /S # add dlls needed for pyinstaller: cp $WINEPREFIX/drive_c/python$PYTHON_VERSION/Lib/site-packages/PyQt5/Qt/bin/* $WINEPREFIX/drive_c/python$PYTHON_VERSION/ - echo "Wine is configured. Please run prepare-pyinstaller.sh" diff --git a/contrib/deterministic-build/requirements-binaries.txt b/contrib/deterministic-build/requirements-binaries.txt @@ -0,0 +1,5 @@ +pycryptodomex==3.4.12 +PyQt5==5.9 +sip==4.19.7 +six==1.11.0 +websocket-client==0.46.0+ \ No newline at end of file diff --git a/contrib/freeze_packages.sh b/contrib/freeze_packages.sh @@ -6,34 +6,17 @@ contrib=$(dirname "$0") which virtualenv > /dev/null 2>&1 || { echo "Please install virtualenv" && exit 1; } -# standard Electrum dependencies +for i in '' '-hw' '-binaries'; do + rm "$venv_dir" -rf + virtualenv -p $(which python3) $venv_dir -rm "$venv_dir" -rf -virtualenv -p $(which python3) $venv_dir + source $venv_dir/bin/activate -source $venv_dir/bin/activate + echo "Installing $i dependencies" -echo "Installing main dependencies" - -pushd $contrib/.. -python setup.py install -popd - -pip freeze | sed '/^Electrum/ d' > $contrib/deterministic-build/requirements.txt - - -# hw wallet library dependencies - -rm "$venv_dir" -rf -virtualenv -p $(which python3) $venv_dir - -source $venv_dir/bin/activate - -echo "Installing hw wallet dependencies" - -python -m pip install -r $contrib/../requirements-hw.txt --upgrade - -pip freeze | sed '/^Electrum/ d' > $contrib/deterministic-build/requirements-hw.txt + python -m pip install -r $contrib/requirements/requirements${i}.txt --upgrade + pip freeze | sed '/^Electrum/ d' > $contrib/deterministic-build/requirements${i}.txt +done echo "Done. Updated requirements" diff --git a/contrib/requirements/requirements-binaries.txt b/contrib/requirements/requirements-binaries.txt @@ -0,0 +1,3 @@ +PyQt5 +pycryptodomex +websocket-client+ \ No newline at end of file diff --git a/requirements-hw.txt b/contrib/requirements/requirements-hw.txt diff --git a/requirements_travis.txt b/contrib/requirements/requirements-travis.txt diff --git a/contrib/requirements/requirements.txt b/contrib/requirements/requirements.txt @@ -0,0 +1,9 @@ +pyaes>=0.1a1 +ecdsa>=0.9 +pbkdf2 +requests +qrcode +protobuf +dnspython +jsonrpclib-pelix +PySocks>=1.6.6 diff --git a/gui/kivy/uix/dialogs/bump_fee_dialog.py b/gui/kivy/uix/dialogs/bump_fee_dialog.py @@ -73,7 +73,7 @@ class BumpFeeDialog(Factory.Popup): self.callback = callback self.config = app.electrum_config self.fee_step = self.config.max_fee_rate() / 10 - self.dynfees = self.config.get('dynamic_fees', True) and self.app.network + self.dynfees = self.config.is_dynfee() and self.app.network self.ids.old_fee.value = self.app.format_amount_and_units(self.init_fee) self.update_slider() self.update_text() diff --git a/gui/kivy/uix/dialogs/fee_dialog.py b/gui/kivy/uix/dialogs/fee_dialog.py @@ -78,8 +78,8 @@ class FeeDialog(Factory.Popup): self.config = config self.fee_rate = self.config.fee_per_kb() self.callback = callback - self.mempool = self.config.get('mempool_fees', False) - self.dynfees = self.config.get('dynamic_fees', True) + self.mempool = self.config.use_mempool_fees() + self.dynfees = self.config.is_dynfee() self.ids.mempool.active = self.mempool self.ids.dynfees.active = self.dynfees self.update_slider() diff --git a/gui/kivy/uix/screens.py b/gui/kivy/uix/screens.py @@ -522,7 +522,12 @@ class AddressScreen(CScreen): def update(self): self.menu_actions = [('Receive', self.do_show), ('Details', self.do_view)] wallet = self.app.wallet - _list = wallet.get_change_addresses() if self.screen.show_change else wallet.get_receiving_addresses() + if self.screen.show_change == 0: + _list = wallet.get_receiving_addresses() + elif self.screen.show_change == 1: + _list = wallet.get_change_addresses() + else: + _list = wallet.get_addresses() search = self.screen.message container = self.screen.ids.search_container container.clear_widgets() diff --git a/gui/kivy/uix/ui_screens/address.kv b/gui/kivy/uix/ui_screens/address.kv @@ -50,7 +50,7 @@ AddressScreen: name: 'address' message: '' pr_status: 'Pending' - show_change: False + show_change: 0 show_used: 0 on_message: self.parent.update() @@ -70,9 +70,9 @@ AddressScreen: spacing: '5dp' AddressButton: id: search - text: _('Change') if root.show_change else _('Receiving') + text: {0:_('Receiving'), 1:_('Change'), 2:_('All')}[root.show_change] on_release: - root.show_change = not root.show_change + root.show_change = (root.show_change + 1) % 3 Clock.schedule_once(lambda dt: app.address_screen.update()) AddressFilter: opacity: 1 diff --git a/gui/qt/fee_slider.py b/gui/qt/fee_slider.py @@ -21,7 +21,7 @@ class FeeSlider(QSlider): def moved(self, pos): with self.lock: if self.dyn: - fee_rate = self.config.depth_to_fee(pos) if self.config.get('mempool_fees') else self.config.eta_to_fee(pos) + fee_rate = self.config.depth_to_fee(pos) if self.config.use_mempool_fees() else self.config.eta_to_fee(pos) else: fee_rate = self.config.static_fee(pos) tooltip = self.get_tooltip(pos, fee_rate) @@ -30,7 +30,7 @@ class FeeSlider(QSlider): self.callback(self.dyn, pos, fee_rate) def get_tooltip(self, pos, fee_rate): - mempool = self.config.get('mempool_fees') + mempool = self.config.use_mempool_fees() target, estimate = self.config.get_fee_text(pos, self.dyn, mempool, fee_rate) if self.dyn: return _('Target') + ': ' + target + '\n' + _('Current rate') + ': ' + estimate @@ -40,7 +40,7 @@ class FeeSlider(QSlider): def update(self): with self.lock: self.dyn = self.config.is_dynfee() - mempool = self.config.get('mempool_fees') + mempool = self.config.use_mempool_fees() maxp, pos, fee_rate = self.config.get_fee_slider(self.dyn, mempool) self.setRange(0, maxp) self.setValue(pos) diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py @@ -1081,7 +1081,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): def fee_cb(dyn, pos, fee_rate): if dyn: - if self.config.get('mempool_fees'): + if self.config.use_mempool_fees(): self.config.set_key('depth_level', pos, False) else: self.config.set_key('fee_level', pos, False) @@ -2669,7 +2669,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): fee_type_label = HelpLabel(_('Fee estimation') + ':', msg) fee_type_combo = QComboBox() fee_type_combo.addItems([_('Time based'), _('Mempool based')]) - fee_type_combo.setCurrentIndex(1 if self.config.get('mempool_fees') else 0) + fee_type_combo.setCurrentIndex(1 if self.config.use_mempool_fees() else 0) def on_fee_type(x): self.config.set_key('mempool_fees', x==1) self.fee_slider.update() diff --git a/lib/simple_config.py b/lib/simple_config.py @@ -324,7 +324,7 @@ class SimpleConfig(PrintError): def get_fee_status(self): dyn = self.is_dynfee() - mempool = self.get('mempool_fees') + mempool = self.use_mempool_fees() pos = self.get_depth_level() if mempool else self.get_fee_level() fee_rate = self.fee_per_kb() target, tooltip = self.get_fee_text(pos, dyn, mempool, fee_rate) @@ -395,10 +395,10 @@ class SimpleConfig(PrintError): return bool(self.mempool_fees) def is_dynfee(self): - return self.get('dynamic_fees', True) + return bool(self.get('dynamic_fees', True)) def use_mempool_fees(self): - return self.get('mempool_fees', False) + return bool(self.get('mempool_fees', False)) def fee_per_kb(self): """Returns sat/kvB fee to pay for a txn. diff --git a/lib/wallet.py b/lib/wallet.py @@ -322,6 +322,9 @@ class Abstract_Wallet(PrintError): def synchronize(self): pass + def is_deterministic(self): + return self.keystore.is_deterministic() + def set_up_to_date(self, up_to_date): with self.lock: self.up_to_date = up_to_date @@ -1883,9 +1886,6 @@ class Deterministic_Wallet(Abstract_Wallet): def has_seed(self): return self.keystore.has_seed() - def is_deterministic(self): - return self.keystore.is_deterministic() - def get_receiving_addresses(self): return self.receiving_addresses @@ -1971,16 +1971,8 @@ class Deterministic_Wallet(Abstract_Wallet): def synchronize(self): with self.lock: - if self.is_deterministic(): - self.synchronize_sequence(False) - self.synchronize_sequence(True) - else: - if len(self.receiving_addresses) != len(self.keystore.keypairs): - pubkeys = self.keystore.keypairs.keys() - self.receiving_addresses = [self.pubkeys_to_address(i) for i in pubkeys] - self.save_addresses() - for addr in self.receiving_addresses: - self.add_address(addr) + self.synchronize_sequence(False) + self.synchronize_sequence(True) def is_beyond_limit(self, address): is_change, i = self.get_address_index(address) diff --git a/setup.py b/setup.py @@ -9,7 +9,10 @@ import platform import imp import argparse -with open('requirements-hw.txt') as f: +with open('contrib/requirements/requirements.txt') as f: + requirements = f.read().splitlines() + +with open('contrib/requirements/requirements-hw.txt') as f: requirements_hw = f.read().splitlines() version = imp.load_source('version', 'lib/version.py') @@ -17,7 +20,7 @@ version = imp.load_source('version', 'lib/version.py') if sys.version_info[:3] < (3, 4, 0): sys.exit("Error: Electrum requires Python version >= 3.4.0...") -data_files = ['requirements-hw.txt'] +data_files = ['contrib/requirements/' + r for r in ['requirements.txt', 'requirements-hw.txt']] if platform.system() in ['Linux', 'FreeBSD', 'DragonFly']: parser = argparse.ArgumentParser() @@ -38,17 +41,7 @@ if platform.system() in ['Linux', 'FreeBSD', 'DragonFly']: setup( name="Electrum", version=version.ELECTRUM_VERSION, - install_requires=[ - 'pyaes>=0.1a1', - 'ecdsa>=0.9', - 'pbkdf2', - 'requests', - 'qrcode', - 'protobuf', - 'dnspython', - 'jsonrpclib-pelix', - 'PySocks>=1.6.6', - ], + install_requires=requirements, extras_require={ 'hardware': requirements_hw, },