Browse Source

verifier: download chunks first for efficiency

283
thomasv 13 years ago
parent
commit
b6729b3aab
  1. 63
      lib/verifier.py
  2. 10
      scripts/merchant.py

63
lib/verifier.py

@ -59,7 +59,7 @@ class WalletVerifier(threading.Thread):
requested_merkle = [] requested_merkle = []
requested_chunks = [] requested_chunks = []
requested_headers = [] requested_headers = []
pending_headers_changed = False all_chunks = False
# subscribe to block headers # subscribe to block headers
self.interface.send([ ('blockchain.headers.subscribe',[])], 'verifier') self.interface.send([ ('blockchain.headers.subscribe',[])], 'verifier')
@ -67,14 +67,17 @@ class WalletVerifier(threading.Thread):
while True: while True:
# request missing chunks # request missing chunks
max_index = (self.height+1)/2016 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): for i in range(0, max_index + 1):
# test if we can read the first header of the chunk # test if we can read the first header of the chunk
if self.read_header(i*2016): continue if self.read_header(i*2016): continue
print "requesting chunk", i # print "requesting chunk", i
self.interface.send([ ('blockchain.block.get_chunk',[i])], 'verifier') self.interface.send([ ('blockchain.block.get_chunk',[i])], 'verifier')
requested_chunks.append(i) requested_chunks.append(i)
break break
else:
all_chunks = True
print "all chunks"
# request missing tx merkle # request missing tx merkle
for tx in self.transactions: for tx in self.transactions:
@ -84,6 +87,25 @@ class WalletVerifier(threading.Thread):
self.request_merkle(tx) self.request_merkle(tx)
#break #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: try:
r = self.interface.get_response('verifier',timeout=1) r = self.interface.get_response('verifier',timeout=1)
except Queue.Empty: except Queue.Empty:
@ -105,37 +127,18 @@ class WalletVerifier(threading.Thread):
self.verify_chunk(index, result) self.verify_chunk(index, result)
requested_chunks.remove(index) requested_chunks.remove(index)
elif method == 'blockchain.headers.subscribe': elif method in ['blockchain.headers.subscribe', 'blockchain.block.get_header']:
self.height = result.get('block_height')
self.pending_headers.append(result)
pending_headers_changed = True
elif method == 'blockchain.block.get_header':
height = result.get('block_height')
requested_headers.remove(height)
self.pending_headers.append(result) self.pending_headers.append(result)
pending_headers_changed = True if method == 'blockchain.block.get_header':
requested_headers.remove(result.get('block_height'))
# process pending headers else:
if pending_headers_changed: self.height = result.get('block_height')
self.pending_headers.sort(key=lambda x: x.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) # 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') self.interface.trigger_callback('updated')
@ -159,7 +162,7 @@ class WalletVerifier(threading.Thread):
data = hexdata.decode('hex') data = hexdata.decode('hex')
height = index*2016 height = index*2016
num = len(data)/80 num = len(data)/80
print "validate_chunk", index, num print "validating headers", height, num
if index == 0: if index == 0:
previous_hash = ("0"*64) previous_hash = ("0"*64)

10
scripts/merchant.py

@ -21,7 +21,7 @@ import time, thread, sys, socket, os
import urllib2,json import urllib2,json
import MySQLdb as mdb import MySQLdb as mdb
import Queue import Queue
from electrum import Wallet, Interface from electrum import Wallet, Interface, WalletVerifier
import ConfigParser import ConfigParser
config = ConfigParser.ConfigParser() config = ConfigParser.ConfigParser()
@ -76,7 +76,11 @@ def electrum_output_thread(out_queue):
h = r.get('result') h = r.get('result')
if h is None: if h is None:
continue continue
for item in h: for item in h:
tx_hash = item.get('tx_hash')
verifier.add(tx_hash)
v = item['value'] v = item['value']
if v<0: continue if v<0: continue
if item['height']: if item['height']:
@ -90,6 +94,9 @@ def electrum_output_thread(out_queue):
if s>=amount: if s>=amount:
out_queue.put( ('payment',addr) ) out_queue.put( ('payment',addr) )
elif method == 'blockchain.numblocks.subscribe':
pass
stopping = False stopping = False
@ -158,6 +165,7 @@ if __name__ == '__main__':
interface = Interface({'server':"%s:%d:t"%(electrum_server, 50001)}) interface = Interface({'server':"%s:%d:t"%(electrum_server, 50001)})
interface.start() interface.start()
interface.send([('blockchain.numblocks.subscribe',[])])
verifier = WalletVerifier(interface, config) verifier = WalletVerifier(interface, config)
verifier.start() verifier.start()

Loading…
Cancel
Save