fix server crash due to orphaned block in header file
[electrum-server.git] / backends / bitcoind / blockchain_processor.py
index 644e74e..7f65aa6 100644 (file)
@@ -65,7 +65,7 @@ class BlockchainProcessor(Processor):
                 self.bitcoind('getinfo')
                 break
             except:
-                print_log('cannot contact bitcoind...')
+                print_log('cannot contact novacoind...')
                 time.sleep(5)
                 continue
 
@@ -113,7 +113,7 @@ class BlockchainProcessor(Processor):
         try:
             respdata = urllib.urlopen(self.bitcoind_url, postdata).read()
         except:
-            print_log("error calling bitcoind")
+            print_log("error calling novacoind")
             traceback.print_exc(file=sys.stdout)
             self.shared.stop()
 
@@ -158,10 +158,17 @@ class BlockchainProcessor(Processor):
 
         try:
             while height < db_height:
-                height = height + 1
+                height += 1
                 header = self.get_header(height)
                 if height > 1:
-                    assert prev_hash == header.get('prev_block_hash')
+                    if prev_hash != header.get('prev_block_hash'):
+                        # The prev_hash block is orphaned, go back
+                        print_log("reorganizing, a block in file is orphaned:", prev_hash)
+                        # Go to the parent of the orphaned block
+                        height -= 2
+                        prev_hash = self.hash_header(self.read_header(height))
+                        continue
+
                 self.write_header(header, sync=False)
                 prev_hash = self.hash_header(header)
                 if (height % 1000) == 0:
@@ -235,7 +242,7 @@ class BlockchainProcessor(Processor):
         vds = deserialize.BCDataStream()
         vds.write(raw_tx.decode('hex'))
         try:
-            return deserialize.parse_Transaction(vds, is_coinbase=False, is_coinstake=False)
+            return deserialize.parse_Transaction(vds, is_coinbase=False)
         except:
             print_log("ERROR: cannot parse", txid)
             return None
@@ -356,23 +363,18 @@ class BlockchainProcessor(Processor):
 
 
     def deserialize_block(self, block):
-        is_stake_block = False
         txlist = block.get('tx')
-        if "proof-of-stake" in block.get('flags'): # scan block flags list for
-            is_stake_block = True                  #    "proof-of-stake" substring
 
         tx_hashes = []  # ordered txids
         txdict = {}     # deserialized tx
 
-        for i in xrange(len(txlist)):
-            if is_stake_block and i == 0: # skip coinbase for
-                continue                  #     stake block
-            tx_hash = hash_encode(Hash(txlist[i].decode('hex')))
+        for i, raw_tx in enumerate(txlist):
+            tx_hash = hash_encode(Hash(raw_tx.decode('hex')))
             vds = deserialize.BCDataStream()
-            vds.write(txlist[i].decode('hex'))
+            vds.write(raw_tx.decode('hex'))
             try:
-                tx = deserialize.parse_Transaction(vds, i == 0, is_stake_block and i == 1) # first transaction is always coinbase
-            except:                                                                        # second transaction is coinstake if we have a stake block
+                tx = deserialize.parse_Transaction(vds, i == 0) # first transaction is always coinbase
+            except:
                 print_log("ERROR: cannot parse", tx_hash)
                 continue
             tx_hashes.append(tx_hash)