URI: 
       tblockchain.py: fix: chunks in checkpoint region were not getting saved if we were on a fork - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 2a9f5db5769e52958bc3c4f94ca53d58a8baf9d7
   DIR parent 531cdeffa9abbbbfdc4f2326dd6af252ace1b0d9
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Fri,  3 Aug 2018 19:06:23 +0200
       
       blockchain.py: fix: chunks in checkpoint region were not getting saved if we were on a fork
       
       Diffstat:
         M electrum/blockchain.py              |      35 +++++++++++++++++++++++++-------
       
       1 file changed, 28 insertions(+), 7 deletions(-)
       ---
   DIR diff --git a/electrum/blockchain.py b/electrum/blockchain.py
       t@@ -115,10 +115,17 @@ class Blockchain(util.PrintError):
                self.forkpoint = forkpoint
                self.checkpoints = constants.net.CHECKPOINTS
                self.parent_id = parent_id
       -        self.lock = threading.Lock()
       +        assert parent_id != forkpoint
       +        self.lock = threading.RLock()
                with self.lock:
                    self.update_size()
        
       +    def with_lock(func):
       +        def func_wrapper(self, *args, **kwargs):
       +            with self.lock:
       +                return func(self, *args, **kwargs)
       +        return func_wrapper
       +
            def parent(self):
                return blockchains[self.parent_id]
        
       t@@ -186,15 +193,27 @@ class Blockchain(util.PrintError):
                filename = 'blockchain_headers' if self.parent_id is None else os.path.join('forks', 'fork_%d_%d'%(self.parent_id, self.forkpoint))
                return os.path.join(d, filename)
        
       +    @with_lock
            def save_chunk(self, index, chunk):
       -        d = (index * 2016 - self.forkpoint) * 80
       -        if d < 0:
       -            chunk = chunk[-d:]
       -            d = 0
       -        truncate = index >= len(self.checkpoints)
       -        self.write(chunk, d, truncate)
       +        chunk_within_checkpoint_region = index < len(self.checkpoints)
       +        # chunks in checkpoint region are the responsibility of the 'main chain'
       +        if chunk_within_checkpoint_region and self.parent_id is not None:
       +            main_chain = blockchains[0]
       +            main_chain.save_chunk(index, chunk)
       +            return
       +
       +        delta_height = (index * 2016 - self.forkpoint)
       +        delta_bytes = delta_height * 80
       +        # if this chunk contains our forkpoint, only save the part after forkpoint
       +        # (the part before is the responsibility of the parent)
       +        if delta_bytes < 0:
       +            chunk = chunk[-delta_bytes:]
       +            delta_bytes = 0
       +        truncate = not chunk_within_checkpoint_region
       +        self.write(chunk, delta_bytes, truncate)
                self.swap_with_parent()
        
       +    @with_lock
            def swap_with_parent(self):
                if self.parent_id is None:
                    return
       t@@ -253,9 +272,11 @@ class Blockchain(util.PrintError):
                        os.fsync(f.fileno())
                    self.update_size()
        
       +    @with_lock
            def save_header(self, header):
                delta = header.get('block_height') - self.forkpoint
                data = bfh(serialize_header(header))
       +        # headers are only _appended_ to the end:
                assert delta == self.size()
                assert len(data) == 80
                self.write(data, delta*80)