Merge branch 'mainline_bitcoind' of github.com:luke-jr/electrum-server into mainline_...
[electrum-server.git] / backends / bitcoind / blockchain_processor.py
index 4f8a69a..cd169af 100644 (file)
@@ -250,14 +250,17 @@ class BlockchainProcessor(Processor):
 
     def get_mempool_transaction(self, txid):
         try:
-            raw_tx = self.bitcoind('getrawtransaction', [txid, 0, -1])
+            raw_tx = self.bitcoind('getrawtransaction', [txid, 0])
         except:
             return None
 
         vds = deserialize.BCDataStream()
         vds.write(raw_tx.decode('hex'))
-
-        return deserialize.parse_Transaction(vds, is_coinbase=False)
+        try:
+            return deserialize.parse_Transaction(vds, is_coinbase=False)
+        except:
+            print_log("ERROR: cannot parse", txid)
+            return None
 
     def get_history(self, addr, cache_only=False):
         with self.cache_lock:
@@ -457,10 +460,14 @@ class BlockchainProcessor(Processor):
         is_coinbase = True
         for raw_tx in txlist:
             tx_hash = hash_encode(Hash(raw_tx.decode('hex')))
-            tx_hashes.append(tx_hash)
             vds = deserialize.BCDataStream()
             vds.write(raw_tx.decode('hex'))
-            tx = deserialize.parse_Transaction(vds, is_coinbase)
+            try:
+                tx = deserialize.parse_Transaction(vds, is_coinbase)
+            except:
+                print_log("ERROR: cannot parse", tx_hash)
+                continue
+            tx_hashes.append(tx_hash)
             txdict[tx_hash] = tx
             is_coinbase = False
         return tx_hashes, txdict
@@ -755,8 +762,7 @@ class BlockchainProcessor(Processor):
         elif method == 'blockchain.transaction.get':
             try:
                 tx_hash = params[0]
-                height = params[1]
-                result = self.bitcoind('getrawtransaction', [tx_hash, 0, height])
+                result = self.bitcoind('getrawtransaction', [tx_hash, 0])
             except BaseException, e:
                 error = str(e) + ': ' + repr(params)
                 print_log("tx get error:", error)
@@ -776,6 +782,35 @@ class BlockchainProcessor(Processor):
         if addr not in self.watched_addresses:
             self.watched_addresses.append(addr)
 
+    def getfullblock(block_hash):
+        block = self.bitcoind('getblock', [block_hash])
+
+        rawtxreq = []
+        i = 0
+        for txid in block['tx']:
+            rawtxreq.append({
+                "method": "getrawtransaction",
+                "params": [txid],
+                "id": i,
+            })
+            i += 1
+
+        postdata = dumps(rawtxreq)
+        try:
+            respdata = urllib.urlopen(self.bitcoind_url, postdata).read()
+        except:
+            traceback.print_exc(file=sys.stdout)
+            self.shared.stop()
+
+        r = loads(respdata)
+        rawtxdata = []
+        for ir in r:
+            if r['error'] is not None:
+                raise BaseException(r['error'])
+            rawtxdata.append(r['result'])
+        block['tx'] = rawtxdata
+        return block
+
     def catch_up(self, sync=True):
         t1 = time.time()
 
@@ -791,7 +826,7 @@ class BlockchainProcessor(Processor):
             # not done..
             self.up_to_date = False
             next_block_hash = self.bitcoind('getblockhash', [self.height + 1])
-            next_block = self.bitcoind('getblock', [next_block_hash, 1])
+            next_block = self.getfullblock(next_block_hash)
 
             # fixme: this is unsafe, if we revert when the undo info is not yet written
             revert = (random.randint(1, 100) == 1) if self.is_test else False
@@ -810,7 +845,7 @@ class BlockchainProcessor(Processor):
 
             else:
                 # revert current block
-                block = self.bitcoind('getblock', [self.last_hash, 1])
+                block = self.getfullblock(self.last_hash)
                 print_log("blockchain reorg", self.height, block.get('previousblockhash'), self.last_hash)
                 self.import_block(block, self.last_hash, self.height, sync, revert=True)
                 self.pop_header()