electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit c8e67e2bd07efe042703bc1368d499c5e555f854
parent cc9032c9ea79a2f44e0b251699838102f7181b66
Author: ThomasV <thomasv@electrum.org>
Date:   Sat, 13 Jan 2018 17:09:25 +0100

fix #3635

Diffstat:
Mlib/blockchain.py | 8++++----
Mlib/network.py | 20+++++++++++---------
Mlib/verifier.py | 13+++----------
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',