URI: 
       tblockchain fixes - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit cf84068fdb0bcdf92bc6946fd6990bd3fd9da722
   DIR parent 8834ed9714f207bec41e4f8fa7ae26ff25a1c1f6
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Sat, 15 Jul 2017 13:51:40 +0200
       
       blockchain fixes
       
       Diffstat:
         M lib/blockchain.py                   |      28 ++++++++++++++++++----------
         M lib/network.py                      |      19 +++++++++++++------
       
       2 files changed, 31 insertions(+), 16 deletions(-)
       ---
   DIR diff --git a/lib/blockchain.py b/lib/blockchain.py
       t@@ -65,19 +65,27 @@ class Blockchain(util.PrintError):
        
            '''Manages blockchain headers and their verification'''
        
       -    def __init__(self, config, filename, fork_point):
       +    def __init__(self, config, filename):
                self.config = config
                self.filename = filename
                self.catch_up = None # interface catching up
       -        if fork_point is None:
       -            self.is_saved = True
       -            self.checkpoint = int(filename[16:]) if filename.startswith('blockchain_fork_') else 0
       -        else:
       -            self.is_saved = False
       -            self.checkpoint = fork_point
       +        self.is_saved = True
       +        self.checkpoint = int(filename[16:]) if filename.startswith('blockchain_fork_') else 0
                self.headers = []
                self.set_local_height()
        
       +    def fork(parent, fork_point):
       +        self = Blockchain(parent.config, parent.filename)
       +        self.is_saved = False
       +        if parent.is_saved:
       +            self.checkpoint = fork_point
       +        else:
       +            if fork_point > parent.checkpoint:
       +                self.headers = parent.headers[0: fork_point - parent.checkpoint]
       +            else:
       +                self.headers = []
       +        return self
       +
            def height(self):
                if self.headers:
                    return self.checkpoint + len(self.headers) - 1
       t@@ -122,7 +130,7 @@ class Blockchain(util.PrintError):
        
            def save_chunk(self, index, chunk):
                if not self.is_saved:
       -            self.fork_and_save()
       +            self.save()
                filename = self.path()
                with open(filename, 'rb+') as f:
                    f.seek(index * 2016 * 80)
       t@@ -130,7 +138,7 @@ class Blockchain(util.PrintError):
                    h = f.write(chunk)
                self.set_local_height()
        
       -    def fork_and_save(self):
       +    def save(self):
                import shutil
                self.print_error("save fork")
                height = self.checkpoint
       t@@ -152,7 +160,7 @@ class Blockchain(util.PrintError):
                    assert height == self.checkpoint + len(self.headers)
                    self.headers.append(header)
                    if len(self.headers) > 10:
       -                self.fork_and_save()
       +                self.save()
                    return
                self.write_header(header)
        
   DIR diff --git a/lib/network.py b/lib/network.py
       t@@ -206,10 +206,10 @@ class Network(util.DaemonThread):
                util.DaemonThread.__init__(self)
                self.config = SimpleConfig(config) if type(config) == type({}) else config
                self.num_server = 10 if not self.config.get('oneserver') else 0
       -        self.blockchains = { 0:Blockchain(self.config, 'blockchain_headers', None) }
       +        self.blockchains = { 0:Blockchain(self.config, 'blockchain_headers') }
                for x in os.listdir(self.config.path):
                    if x.startswith('blockchain_fork_'):
       -                b = Blockchain(self.config, x, None)
       +                b = Blockchain(self.config, x)
                        self.blockchains[b.checkpoint] = b
                self.print_error("blockchains", self.blockchains.keys())
                self.blockchain_index = config.get('blockchain_index', 0)
       t@@ -864,12 +864,17 @@ class Network(util.DaemonThread):
                        next_height = (interface.bad + interface.good) // 2
                    else:
                        interface.print_error("can connect at %d"% interface.good)
       -                interface.blockchain = Blockchain(self.config, interface.blockchain.filename, interface.good)
       -                interface.blockchain.catch_up = interface.server
       -                self.blockchains[interface.good] = interface.blockchain
       -                interface.print_error("catching up with new chain")
       +                b = self.blockchains.get(interface.good)
       +                if b is None:
       +                    b = interface.blockchain.fork(interface.good)
       +                    b.catch_up = interface.server
       +                    interface.print_error("catching up with new chain")
       +                    self.blockchains[interface.good] = b
                        interface.mode = 'catch_up'
                        next_height = interface.good
       +                interface.blockchain = b
       +                # todo: garbage collect blockchain objects
       +                self.notify('updated')
        
                elif interface.mode == 'catch_up':
                    if can_connect:
       t@@ -906,6 +911,8 @@ class Network(util.DaemonThread):
                        self.request_chunk(interface, next_height // 2016)
                    else:
                        self.request_header(interface, next_height)
       +        # refresh network dialog
       +        self.notify('interfaces')
        
            def maintain_requests(self):
                for interface in self.interfaces.values():