URI: 
       tinterface: clean-up 'step'; backwards search - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit beb37aafc5d98b1ee2269b8a4493e5b4b8886f92
   DIR parent 2a958499b635a18d39fdf9a5e354306258917ffe
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Sat, 15 Sep 2018 06:44:18 +0200
       
       interface: clean-up 'step'; backwards search
       
       Diffstat:
         M electrum/interface.py               |      71 ++++++++++++++-----------------
       
       1 file changed, 31 insertions(+), 40 deletions(-)
       ---
   DIR diff --git a/electrum/interface.py b/electrum/interface.py
       t@@ -367,7 +367,7 @@ class Interface(PrintError):
                        raise GracefulDisconnect('server tip below max checkpoint')
                    self.mark_ready()
                    async with self.network.bhi_lock:
       -                if self.blockchain.height() < header['block_height']-1:
       +                if self.blockchain.height() < height - 1:
                            _, height = await self.sync_until(height, None)
                        if self.blockchain.height() >= height and self.blockchain.check_header(header):
                            # another interface amended the blockchain
       t@@ -406,58 +406,23 @@ class Interface(PrintError):
                if chain: return 'catchup', height
                can_connect = blockchain.can_connect(header) if 'mock' not in header else header['mock']['connect'](height)
        
       -        bad_header = None
                if not can_connect:
                    self.print_error("can't connect", height)
       -            #backward
       -            bad = height
       -            bad_header = header
       -            height -= 1
       -            checkp = False
       -            if height <= constants.net.max_checkpoint():
       -                height = constants.net.max_checkpoint()
       -                checkp = True
       -
       -            header = await self.get_block_header(height, 'backward')
       +            height, header, bad, bad_header = await self._search_headers_backwards(height, header)
                    chain = blockchain.check_header(header) if 'mock' not in header else header['mock']['check'](header)
                    can_connect = blockchain.can_connect(header) if 'mock' not in header else header['mock']['connect'](height)
       -            if checkp and not (can_connect or chain):
       -                raise Exception("server chain conflicts with checkpoints. {} {}".format(can_connect, chain))
       -            while not chain and not can_connect:
       -                bad = height
       -                bad_header = header
       -                delta = self.tip - height
       -                next_height = self.tip - 2 * delta
       -                checkp = False
       -                if next_height <= constants.net.max_checkpoint():
       -                    next_height = constants.net.max_checkpoint()
       -                    checkp = True
       -                height = next_height
       -
       -                header = await self.get_block_header(height, 'backward')
       -                chain = blockchain.check_header(header) if 'mock' not in header else header['mock']['check'](header)
       -                can_connect = blockchain.can_connect(header) if 'mock' not in header else header['mock']['connect'](height)
       -                if checkp and not (can_connect or chain):
       -                    raise Exception("server chain conflicts with checkpoints. {} {}".format(can_connect, chain))
       -            self.print_error("exiting backward mode at", height)
       +            assert chain or can_connect
                if can_connect:
                    self.print_error("could connect", height)
       -            chain = blockchain.check_header(header) if 'mock' not in header else header['mock']['check'](header)
       -
       +            height += 1
                    if type(can_connect) is bool:
                        # mock
       -                height += 1
       -                if height > self.tip:
       -                    assert False
       +                assert height <= self.tip
                        return 'catchup', height
                    self.blockchain = can_connect
       -            height += 1
                    self.blockchain.save_header(header)
                    return 'catchup', height
        
       -        if not chain:
       -            raise Exception("not chain") # line 931 in 8e69174374aee87d73cd2f8005fbbe87c93eee9c's network.py
       -
                # binary
                if type(chain) in [int, bool]:
                    pass # mock
       t@@ -543,6 +508,32 @@ class Interface(PrintError):
                                height = bh + 1
                            return 'no_fork', height
        
       +    async def _search_headers_backwards(self, height, header):
       +        async def iterate():
       +            nonlocal height, header
       +            checkp = False
       +            if height <= constants.net.max_checkpoint():
       +                height = constants.net.max_checkpoint()
       +                checkp = True
       +            header = await self.get_block_header(height, 'backward')
       +            chain = blockchain.check_header(header) if 'mock' not in header else header['mock']['check'](header)
       +            can_connect = blockchain.can_connect(header) if 'mock' not in header else header['mock']['connect'](height)
       +            if chain or can_connect:
       +                return False
       +            if checkp:
       +                raise Exception("server chain conflicts with checkpoints. {} {}".format(can_connect, chain))
       +            return True
       +
       +        bad, bad_header = height, header
       +        height -= 1
       +        header = None
       +        while await iterate():
       +            bad, bad_header = height, header
       +            delta = self.tip - height
       +            height = self.tip - 2 * delta
       +        self.print_error("exiting backward mode at", height)
       +        return height, header, bad, bad_header
       +
        
        def check_cert(host, cert):
            try: