commit c8e67e2bd07efe042703bc1368d499c5e555f854
parent cc9032c9ea79a2f44e0b251699838102f7181b66
Author: ThomasV <thomasv@electrum.org>
Date: Sat, 13 Jan 2018 17:09:25 +0100
fix #3635
Diffstat:
3 files changed, 18 insertions(+), 23 deletions(-)
diff --git a/lib/blockchain.py b/lib/blockchain.py
@@ -181,7 +181,7 @@ class Blockchain(util.PrintError):
if d < 0:
chunk = chunk[-d:]
d = 0
- self.write(chunk, d)
+ self.write(chunk, d, index > len(self.checkpoints))
self.swap_with_parent()
def swap_with_parent(self):
@@ -218,11 +218,11 @@ class Blockchain(util.PrintError):
blockchains[self.checkpoint] = self
blockchains[parent.checkpoint] = parent
- def write(self, data, offset):
+ def write(self, data, offset, truncate=True):
filename = self.path()
with self.lock:
with open(filename, 'rb+') as f:
- if offset != self._size*80:
+ if truncate and offset != self._size*80:
f.seek(offset)
f.truncate()
f.seek(offset)
@@ -263,7 +263,7 @@ class Blockchain(util.PrintError):
elif height == 0:
return bitcoin.NetworkConstants.GENESIS
elif height < len(self.checkpoints) * 2016:
- assert (height+1) % 2016 == 0
+ assert (height+1) % 2016 == 0, height
index = height // 2016
h, t = self.checkpoints[index]
return h
diff --git a/lib/network.py b/lib/network.py
@@ -218,6 +218,7 @@ class Network(util.DaemonThread):
self.interfaces = {}
self.auto_connect = self.config.get('auto_connect', True)
self.connecting = set()
+ self.requested_chunks = set()
self.socket_queue = queue.Queue()
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():
self.request_fee_estimates()
- def request_chunk(self, interface, idx):
- interface.print_error("requesting chunk %d" % idx)
- self.queue_request('blockchain.block.get_chunk', [idx], interface)
- interface.request = idx
- interface.req_time = time.time()
+ def request_chunk(self, interface, index):
+ if index in self.requested_chunks:
+ return
+ interface.print_error("requesting chunk %d" % index)
+ self.requested_chunks.add(index)
+ self.queue_request('blockchain.block.get_chunk', [index], interface)
def on_get_chunk(self, interface, response):
'''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:
interface.print_error(error or 'bad response')
return
- # Ignore unsolicited chunks
index = params[0]
- if interface.request != index:
+ # Ignore unsolicited chunks
+ if index not in self.requested_chunks:
return
+ self.requested_chunks.remove(index)
connect = interface.blockchain.connect_chunk(index, result)
- # If not finished, get the next chunk
if not connect:
self.connection_down(interface.server)
return
+ # If not finished, get the next chunk
if interface.blockchain.height() < interface.tip:
self.request_chunk(interface, index+1)
else:
- interface.request = None
interface.mode = 'default'
interface.print_error('catch up done', interface.blockchain.height())
interface.blockchain.catch_up = None
diff --git a/lib/verifier.py b/lib/verifier.py
@@ -34,7 +34,6 @@ class SPV(ThreadJob):
# Keyed by tx hash. Value is None if the merkle branch was
# requested, and the merkle root once it has been verified
self.merkle_roots = {}
- self.requested_chunks = {}
def run(self):
lh = self.network.get_local_height()
@@ -43,15 +42,9 @@ class SPV(ThreadJob):
# do not request merkle branch before headers are available
if (tx_height > 0) and (tx_height <= lh):
header = self.network.blockchain().read_header(tx_height)
- 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)
+ if header is None and self.network.interface:
+ index = tx_height // 2016
+ self.network.request_chunk(self.network.interface, index)
else:
if tx_hash not in self.merkle_roots:
request = ('blockchain.transaction.get_merkle',