URI: 
       tMerge branch 'master' of github.com:spesmilo/electrum - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit b3a67f7a1f888d6151b36cdab2fc450c8f46e05c
   DIR parent 2829de5d49460cfdc68a8e4eb371ecdfda0e2b3d
  HTML 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 +-
         M contrib/build-osx/make_osx          |      10 ++++------
         M contrib/build-wine/prepare-wine.sh  |      19 ++++---------------
         A contrib/deterministic-build/requir… |       6 ++++++
         M contrib/freeze_packages.sh          |      33 ++++++++-----------------------
         A contrib/requirements/requirements-… |       4 ++++
         R requirements-hw.txt -> contrib/req… |       0 
         R requirements_travis.txt -> contrib… |       0 
         A contrib/requirements/requirements.… |       9 +++++++++
         M gui/kivy/uix/dialogs/bump_fee_dial… |       2 +-
         M gui/kivy/uix/dialogs/fee_dialog.py  |       4 ++--
         M gui/kivy/uix/screens.py             |       7 ++++++-
         M gui/kivy/uix/ui_screens/address.kv  |       6 +++---
         M gui/qt/fee_slider.py                |       6 +++---
         M gui/qt/main_window.py               |       4 ++--
         M lib/simple_config.py                |       6 +++---
         M lib/wallet.py                       |      18 +++++-------------
         M setup.py                            |      19 ++++++-------------
       
       18 files changed, 67 insertions(+), 88 deletions(-)
       ---
   DIR diff --git a/.travis.yml b/.travis.yml
       t@@ -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:
   DIR diff --git a/contrib/build-osx/make_osx b/contrib/build-osx/make_osx
       t@@ -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
       t@@ -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
       t@@ -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..."
   DIR diff --git a/contrib/build-wine/prepare-wine.sh b/contrib/build-wine/prepare-wine.sh
       t@@ -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
       t@@ -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"
   DIR diff --git a/contrib/deterministic-build/requirements-binaries.txt b/contrib/deterministic-build/requirements-binaries.txt
       t@@ -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
   DIR diff --git a/contrib/freeze_packages.sh b/contrib/freeze_packages.sh
       t@@ -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"
   DIR diff --git a/contrib/requirements/requirements-binaries.txt b/contrib/requirements/requirements-binaries.txt
       t@@ -0,0 +1,3 @@
       +PyQt5
       +pycryptodomex
       +websocket-client
       +\ No newline at end of file
   DIR diff --git a/requirements-hw.txt b/contrib/requirements/requirements-hw.txt
   DIR diff --git a/requirements_travis.txt b/contrib/requirements/requirements-travis.txt
   DIR diff --git a/contrib/requirements/requirements.txt b/contrib/requirements/requirements.txt
       t@@ -0,0 +1,9 @@
       +pyaes>=0.1a1
       +ecdsa>=0.9
       +pbkdf2
       +requests
       +qrcode
       +protobuf
       +dnspython
       +jsonrpclib-pelix
       +PySocks>=1.6.6
   DIR diff --git a/gui/kivy/uix/dialogs/bump_fee_dialog.py b/gui/kivy/uix/dialogs/bump_fee_dialog.py
       t@@ -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()
   DIR diff --git a/gui/kivy/uix/dialogs/fee_dialog.py b/gui/kivy/uix/dialogs/fee_dialog.py
       t@@ -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()
   DIR diff --git a/gui/kivy/uix/screens.py b/gui/kivy/uix/screens.py
       t@@ -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()
   DIR diff --git a/gui/kivy/uix/ui_screens/address.kv b/gui/kivy/uix/ui_screens/address.kv
       t@@ -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()
       t@@ -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
   DIR diff --git a/gui/qt/fee_slider.py b/gui/qt/fee_slider.py
       t@@ -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)
       t@@ -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
       t@@ -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)
   DIR diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
       t@@ -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)
       t@@ -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()
   DIR diff --git a/lib/simple_config.py b/lib/simple_config.py
       t@@ -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)
       t@@ -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.
   DIR diff --git a/lib/wallet.py b/lib/wallet.py
       t@@ -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
       t@@ -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
        
       t@@ -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)
   DIR diff --git a/setup.py b/setup.py
       t@@ -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')
       t@@ -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()
       t@@ -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,
            },