This commit is contained in:
ThomasV 2018-01-13 17:09:25 +01:00
parent cc9032c9ea
commit c8e67e2bd0
3 changed files with 18 additions and 23 deletions

View file

@ -181,7 +181,7 @@ class Blockchain(util.PrintError):
if d < 0: if d < 0:
chunk = chunk[-d:] chunk = chunk[-d:]
d = 0 d = 0
self.write(chunk, d) self.write(chunk, d, index > len(self.checkpoints))
self.swap_with_parent() self.swap_with_parent()
def swap_with_parent(self): def swap_with_parent(self):
@ -218,11 +218,11 @@ class Blockchain(util.PrintError):
blockchains[self.checkpoint] = self blockchains[self.checkpoint] = self
blockchains[parent.checkpoint] = parent blockchains[parent.checkpoint] = parent
def write(self, data, offset): def write(self, data, offset, truncate=True):
filename = self.path() filename = self.path()
with self.lock: with self.lock:
with open(filename, 'rb+') as f: with open(filename, 'rb+') as f:
if offset != self._size*80: if truncate and offset != self._size*80:
f.seek(offset) f.seek(offset)
f.truncate() f.truncate()
f.seek(offset) f.seek(offset)
@ -263,7 +263,7 @@ class Blockchain(util.PrintError):
elif height == 0: elif height == 0:
return bitcoin.NetworkConstants.GENESIS return bitcoin.NetworkConstants.GENESIS
elif height < len(self.checkpoints) * 2016: elif height < len(self.checkpoints) * 2016:
assert (height+1) % 2016 == 0 assert (height+1) % 2016 == 0, height
index = height // 2016 index = height // 2016
h, t = self.checkpoints[index] h, t = self.checkpoints[index]
return h return h

View file

@ -218,6 +218,7 @@ class Network(util.DaemonThread):
self.interfaces = {} self.interfaces = {}
self.auto_connect = self.config.get('auto_connect', True) self.auto_connect = self.config.get('auto_connect', True)
self.connecting = set() self.connecting = set()
self.requested_chunks = set()
self.socket_queue = queue.Queue() self.socket_queue = queue.Queue()
self.start_network(self.protocol, deserialize_proxy(self.config.get('proxy'))) self.start_network(self.protocol, deserialize_proxy(self.config.get('proxy')))
@ -754,11 +755,12 @@ class Network(util.DaemonThread):
if self.config.is_fee_estimates_update_required(): if self.config.is_fee_estimates_update_required():
self.request_fee_estimates() self.request_fee_estimates()
def request_chunk(self, interface, idx): def request_chunk(self, interface, index):
interface.print_error("requesting chunk %d" % idx) if index in self.requested_chunks:
self.queue_request('blockchain.block.get_chunk', [idx], interface) return
interface.request = idx interface.print_error("requesting chunk %d" % index)
interface.req_time = time.time() self.requested_chunks.add(index)
self.queue_request('blockchain.block.get_chunk', [index], interface)
def on_get_chunk(self, interface, response): def on_get_chunk(self, interface, response):
'''Handle receiving a chunk of block headers''' '''Handle receiving a chunk of block headers'''
@ -768,19 +770,19 @@ class Network(util.DaemonThread):
if result is None or params is None or error is not None: if result is None or params is None or error is not None:
interface.print_error(error or 'bad response') interface.print_error(error or 'bad response')
return return
# Ignore unsolicited chunks
index = params[0] index = params[0]
if interface.request != index: # Ignore unsolicited chunks
if index not in self.requested_chunks:
return return
self.requested_chunks.remove(index)
connect = interface.blockchain.connect_chunk(index, result) connect = interface.blockchain.connect_chunk(index, result)
# If not finished, get the next chunk
if not connect: if not connect:
self.connection_down(interface.server) self.connection_down(interface.server)
return return
# If not finished, get the next chunk
if interface.blockchain.height() < interface.tip: if interface.blockchain.height() < interface.tip:
self.request_chunk(interface, index+1) self.request_chunk(interface, index+1)
else: else:
interface.request = None
interface.mode = 'default' interface.mode = 'default'
interface.print_error('catch up done', interface.blockchain.height()) interface.print_error('catch up done', interface.blockchain.height())
interface.blockchain.catch_up = None interface.blockchain.catch_up = None

View file

@ -34,7 +34,6 @@ class SPV(ThreadJob):
# Keyed by tx hash. Value is None if the merkle branch was # Keyed by tx hash. Value is None if the merkle branch was
# requested, and the merkle root once it has been verified # requested, and the merkle root once it has been verified
self.merkle_roots = {} self.merkle_roots = {}
self.requested_chunks = {}
def run(self): def run(self):
lh = self.network.get_local_height() lh = self.network.get_local_height()
@ -43,14 +42,8 @@ class SPV(ThreadJob):
# do not request merkle branch before headers are available # do not request merkle branch before headers are available
if (tx_height > 0) and (tx_height <= lh): if (tx_height > 0) and (tx_height <= lh):
header = self.network.blockchain().read_header(tx_height) header = self.network.blockchain().read_header(tx_height)
if header is None and self.network.interface:
index = tx_height // 2016 index = tx_height // 2016
#print(index, header)
if header is None:
if index not in self.requested_chunks and self.network.interface:
print("requesting chunk", index)
#request = ('blockchain.block.get_chunk', [index])
#self.network.send([request], self.verify_merkle)
self.requested_chunks[index] = None
self.network.request_chunk(self.network.interface, index) self.network.request_chunk(self.network.interface, index)
else: else:
if tx_hash not in self.merkle_roots: if tx_hash not in self.merkle_roots: