tverifier: download chunks first for efficiency - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit b6729b3aab916d6569750619d1595bfe7ed633f6 DIR parent 8526915420436d13e1da07e66db20a9f8de6c75a HTML Author: thomasv <thomasv@gitorious> Date: Fri, 26 Oct 2012 15:08:12 +0200 verifier: download chunks first for efficiency Diffstat: M lib/verifier.py | 63 ++++++++++++++++--------------- M scripts/merchant.py | 10 +++++++++- 2 files changed, 42 insertions(+), 31 deletions(-) --- DIR diff --git a/lib/verifier.py b/lib/verifier.py t@@ -59,7 +59,7 @@ class WalletVerifier(threading.Thread): requested_merkle = [] requested_chunks = [] requested_headers = [] - pending_headers_changed = False + all_chunks = False # subscribe to block headers self.interface.send([ ('blockchain.headers.subscribe',[])], 'verifier') t@@ -67,14 +67,17 @@ class WalletVerifier(threading.Thread): while True: # request missing chunks max_index = (self.height+1)/2016 - if not requested_chunks: + if not all_chunks and self.height and not requested_chunks: for i in range(0, max_index + 1): # test if we can read the first header of the chunk if self.read_header(i*2016): continue - print "requesting chunk", i + # print "requesting chunk", i self.interface.send([ ('blockchain.block.get_chunk',[i])], 'verifier') requested_chunks.append(i) break + else: + all_chunks = True + print "all chunks" # request missing tx merkle for tx in self.transactions: t@@ -84,6 +87,25 @@ class WalletVerifier(threading.Thread): self.request_merkle(tx) #break + + # process pending headers + if self.pending_headers and all_chunks: + done = [] + for header in self.pending_headers: + if self.verify_header(header): + done.append(header) + else: + # request previous header + i = header.get('block_height') - 1 + if i not in requested_headers: + print "requesting header", i + self.interface.send([ ('blockchain.block.get_header',[i])], 'verifier') + requested_headers.append(i) + # no point continuing + break + for header in done: self.pending_headers.remove(header) + self.interface.trigger_callback('updated') + try: r = self.interface.get_response('verifier',timeout=1) except Queue.Empty: t@@ -105,37 +127,18 @@ class WalletVerifier(threading.Thread): self.verify_chunk(index, result) requested_chunks.remove(index) - elif method == 'blockchain.headers.subscribe': - self.height = result.get('block_height') - self.pending_headers.append(result) - pending_headers_changed = True + elif method in ['blockchain.headers.subscribe', 'blockchain.block.get_header']: - elif method == 'blockchain.block.get_header': - height = result.get('block_height') - requested_headers.remove(height) self.pending_headers.append(result) - pending_headers_changed = True - - # process pending headers - if pending_headers_changed: + if method == 'blockchain.block.get_header': + requested_headers.remove(result.get('block_height')) + else: + self.height = result.get('block_height') + self.pending_headers.sort(key=lambda x: x.get('block_height')) # print "pending headers", map(lambda x: x.get('block_height'), self.pending_headers) - done = [] - for header in self.pending_headers: - if self.verify_header(header): - done.append(header) - else: - # request previous header - i = header.get('block_height') - 1 - if i not in requested_headers: - print "requesting header", i - self.interface.send([ ('blockchain.block.get_header',[i])], 'verifier') - requested_headers.append(i) - # no point continuing - break - for header in done: self.pending_headers.remove(header) - pending_headers_changed = False + self.interface.trigger_callback('updated') t@@ -159,7 +162,7 @@ class WalletVerifier(threading.Thread): data = hexdata.decode('hex') height = index*2016 num = len(data)/80 - print "validate_chunk", index, num + print "validating headers", height, num if index == 0: previous_hash = ("0"*64) DIR diff --git a/scripts/merchant.py b/scripts/merchant.py t@@ -21,7 +21,7 @@ import time, thread, sys, socket, os import urllib2,json import MySQLdb as mdb import Queue -from electrum import Wallet, Interface +from electrum import Wallet, Interface, WalletVerifier import ConfigParser config = ConfigParser.ConfigParser() t@@ -76,7 +76,11 @@ def electrum_output_thread(out_queue): h = r.get('result') if h is None: continue + for item in h: + tx_hash = item.get('tx_hash') + verifier.add(tx_hash) + v = item['value'] if v<0: continue if item['height']: t@@ -90,6 +94,9 @@ def electrum_output_thread(out_queue): if s>=amount: out_queue.put( ('payment',addr) ) + elif method == 'blockchain.numblocks.subscribe': + pass + stopping = False t@@ -158,6 +165,7 @@ if __name__ == '__main__': interface = Interface({'server':"%s:%d:t"%(electrum_server, 50001)}) interface.start() + interface.send([('blockchain.numblocks.subscribe',[])]) verifier = WalletVerifier(interface, config) verifier.start()