URI: 
       tcheck that histories and transactions are consistent - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 62be41161bbc20bbfe085db9d24b3aec9b66348b
   DIR parent a48a971ae63b32ce94c1236c05d34d1b25219a84
  HTML Author: ThomasV <thomasv@gitorious>
       Date:   Wed,  7 Nov 2012 20:25:23 +0100
       
       check that histories and transactions are consistent
       
       Diffstat:
         M lib/wallet.py                       |      82 ++++++++++++++++++++++++++-----
       
       1 file changed, 70 insertions(+), 12 deletions(-)
       ---
   DIR diff --git a/lib/wallet.py b/lib/wallet.py
       t@@ -538,17 +538,26 @@ class Wallet:
        
        
        
       -    def receive_tx_callback(self, tx_hash, d):
       -        #print "updating history for", addr
       -        #with self.lock:
       -        self.transactions[tx_hash] = d
       +    def receive_tx_callback(self, tx_hash, tx):
       +
       +        if not self.check_new_tx(tx_hash, tx):
       +            print "error: transaction not consistent with history", tx_hash
       +            return
       +
       +        with self.lock:
       +            self.transactions[tx_hash] = tx
       +
                self.update_tx_outputs(tx_hash)
        
                self.save()
        
        
            def receive_history_callback(self, addr, hist):
       -        #print "updating history for", addr
       +
       +        if not self.check_new_history(addr, hist):
       +            print "error: history check failed", tx_hash
       +            return
       +            
                with self.lock:
                    self.history[addr] = hist
                    self.save()
       t@@ -557,6 +566,7 @@ class Wallet:
                            self.verifier.add(tx_hash)
        
        
       +
            def get_tx_history(self):
                with self.lock:
                    lines = self.transactions.values()
       t@@ -896,6 +906,53 @@ class Wallet:
        
        
        
       +    def is_addr_in_tx(self, addr, tx):
       +        found = False
       +        for txin in tx.get('inputs'):
       +            if addr == txin.get('address'): 
       +                found = True
       +                break
       +        for txout in tx.get('outputs'):
       +            if addr == txout.get('address'): 
       +                found = True
       +                break
       +        return found
       +
       +
       +    def check_new_history(self, addr, hist):
       +        # - check that all tx in hist are relevant
       +        for tx_hash, height in hist:
       +            tx = self.transactions.get(tx_hash)
       +            if not tx: continue
       +            if not self.is_addr_in_tx(addr,tx):
       +                return False
       +
       +        # todo: check that we are not "orphaning" a transaction
       +        # if we are, reject tx if unconfirmed, else reject the server
       +
       +        return True
       +
       +
       +
       +    def check_new_tx(self, tx_hash, tx):
       +        # 1 check that tx is referenced in addr_history. 
       +        addresses = []
       +        for addr, hist in self.history.items():
       +            for txh, height in hist:
       +                if txh == tx_hash: 
       +                    addresses.append(addr)
       +
       +        if not addresses:
       +            return False
       +
       +        # 2 check that referencing addresses are in the tx
       +        for addr in addresses:
       +            if not self.is_addr_in_tx(addr, tx):
       +                return False
       +
       +        return True
       +
       +
        
        
        class WalletSynchronizer(threading.Thread):
       t@@ -915,19 +972,20 @@ class WalletSynchronizer(threading.Thread):
                new_addresses = self.wallet.synchronize()
                if new_addresses:
                    self.subscribe_to_addresses(new_addresses)
       +            self.wallet.up_to_date = False
       +            return
                    
       -        if self.interface.is_up_to_date('synchronizer'):
       -            if not self.wallet.up_to_date:
       -                self.wallet.up_to_date = True
       -                self.was_updated = True
       -                self.wallet.up_to_date_event.set()
       -        else:
       +        if not self.interface.is_up_to_date('synchronizer'):
                    if self.wallet.up_to_date:
                        self.wallet.up_to_date = False
                        self.was_updated = True
       +            return
        
       +        self.wallet.up_to_date = True
       +        self.was_updated = True
       +        self.wallet.up_to_date_event.set()
        
       -
       +    
            def subscribe_to_addresses(self, addresses):
                messages = []
                for addr in addresses: