URI: 
       tfix a race condition in synchronizer - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit de4fe9db693b0bdf2f97ce558552d0068fb977d9
   DIR parent 2f408e5d07ca8ae142751998e844109a1d5ba0da
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Thu,  5 Apr 2018 08:32:02 +0200
       
       fix a race condition in synchronizer
       
       wallet.synchronizer gets assigned a newly constructed Synchronizer instance.
       Synchronizer in tx_response refers to the value of wallet.synchronizer.
       If the wallet has a missing txn, there could be a race condition that synchronizer asks for a txn and we get the callback from the network WHILE the constructor is still running, in which case wallet.synchronizer would still be None and we would consider the callback "orphan", and the wallet would get "stuck" synchronizing.
       
       Diffstat:
         M lib/synchronizer.py                 |       9 ++++++---
       
       1 file changed, 6 insertions(+), 3 deletions(-)
       ---
   DIR diff --git a/lib/synchronizer.py b/lib/synchronizer.py
       t@@ -50,6 +50,8 @@ class Synchronizer(ThreadJob):
                self.requested_histories = {}
                self.requested_addrs = set()
                self.lock = Lock()
       +
       +        self.initialized = False
                self.initialize()
        
            def parse_response(self, response):
       t@@ -84,7 +86,7 @@ class Synchronizer(ThreadJob):
                return bh2u(hashlib.sha256(status.encode('ascii')).digest())
        
            def on_address_status(self, response):
       -        if self.wallet.synchronizer is None:
       +        if self.wallet.synchronizer is None and self.initialized:
                    return  # we have been killed, this was just an orphan callback
                params, result = self.parse_response(response)
                if not params:
       t@@ -100,7 +102,7 @@ class Synchronizer(ThreadJob):
                    self.requested_addrs.remove(addr)
        
            def on_address_history(self, response):
       -        if self.wallet.synchronizer is None:
       +        if self.wallet.synchronizer is None and self.initialized:
                    return  # we have been killed, this was just an orphan callback
                params, result = self.parse_response(response)
                if not params:
       t@@ -131,7 +133,7 @@ class Synchronizer(ThreadJob):
                self.requested_histories.pop(addr)
        
            def tx_response(self, response):
       -        if self.wallet.synchronizer is None:
       +        if self.wallet.synchronizer is None and self.initialized:
                    return  # we have been killed, this was just an orphan callback
                params, result = self.parse_response(response)
                if not params:
       t@@ -183,6 +185,7 @@ class Synchronizer(ThreadJob):
                if self.requested_tx:
                    self.print_error("missing tx", self.requested_tx)
                self.subscribe_to_addresses(set(self.wallet.get_addresses()))
       +        self.initialized = True
        
            def run(self):
                '''Called from the network proxy thread main loop.'''