verifier: download chunks first for efficiency
This commit is contained in:
parent
8526915420
commit
b6729b3aab
@ -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)
|
||||||
|
|||||||
@ -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…
Reference in New Issue
Block a user