electrum

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

commit 6afc11208d49c429ddd6572bfd3d7204f33fe6c8
parent 853b6169ed20eea9a910c8d691903320f6bedfb2
Author: ThomasV <thomasv@electrum.org>
Date:   Thu, 20 Apr 2017 10:59:30 +0200

spv: keep track of header requests made by each interface

Diffstat:
Mlib/network.py | 35+++++++++++++++++++----------------
1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/lib/network.py b/lib/network.py @@ -205,8 +205,6 @@ class Network(util.DaemonThread): self.config = SimpleConfig(config) if type(config) == type({}) else config self.num_server = 8 if not self.config.get('oneserver') else 0 self.blockchain = Blockchain(self.config, self) - # A deque of interface header requests, processed left-to-right - self.bc_requests = deque() # Server for addresses and transactions self.default_server = self.config.get('server') # Sanitize default server @@ -692,8 +690,11 @@ class Network(util.DaemonThread): def new_interface(self, server, socket): self.add_recent_server(server) - self.interfaces[server] = interface = Interface(server, socket) + interface = Interface(server, socket) + # A deque of interface header requests, processed left-to-right + interface.bc_requests = deque() interface.failed_checkpoint = False + self.interfaces[server] = interface self.queue_request('blockchain.block.get_header', [self.blockchain.checkpoint_height], interface) self.queue_request('blockchain.headers.subscribe', [], interface) if server == self.default_server: @@ -753,15 +754,15 @@ class Network(util.DaemonThread): if response.get('error'): interface.print_error(response.get('error')) return - if self.bc_requests: - req_if, data = self.bc_requests[0] + if interface.bc_requests: + data = interface.bc_requests[0] req_idx = data.get('chunk_idx') # Ignore unsolicited chunks - if req_if == interface and req_idx == response['params'][0]: + if req_idx == response['params'][0]: idx = self.blockchain.connect_chunk(req_idx, response['result']) # If not finished, get the next chunk if idx < 0 or self.get_local_height() >= data['if_height']: - self.bc_requests.popleft() + interface.bc_requests.popleft() self.notify('updated') else: self.request_chunk(interface, data, idx) @@ -787,18 +788,18 @@ class Network(util.DaemonThread): return if self.blockchain.downloading_headers: return - if self.bc_requests: - req_if, data = self.bc_requests[0] + if interface.bc_requests: + data = interface.bc_requests[0] req_height = data.get('header_height', -1) # Ignore unsolicited headers - if req_if == interface and req_height == response['params'][0]: + if req_height == response['params'][0]: if interface.failed_checkpoint: - self.bc_requests.popleft() + interface.bc_requests.popleft() return next_height = self.blockchain.connect_header(data['chain'], response['result']) # If not finished, get the next header if next_height in [True, False]: - self.bc_requests.popleft() + interface.bc_requests.popleft() if next_height: self.switch_lagging_interface(interface.server) self.notify('updated') @@ -827,8 +828,10 @@ class Network(util.DaemonThread): '''Work through each interface that has notified us of a new header. Send it requests if it is ahead of our blockchain object. ''' - while self.bc_requests: - interface, data = self.bc_requests.popleft() + for interface in self.interfaces.values(): + if not interface.bc_requests: + continue + data = interface.bc_requests.popleft() # If the connection was lost move on if not interface in self.interfaces.values(): continue @@ -843,7 +846,7 @@ class Network(util.DaemonThread): self.connection_down(interface.server) continue # Put updated request state back at head of deque - self.bc_requests.appendleft((interface, data)) + interface.bc_requests.appendleft(data) break def wait_on_sockets(self): @@ -885,7 +888,7 @@ class Network(util.DaemonThread): self.headers[i.server] = header # Queue this interface's height for asynchronous catch-up - self.bc_requests.append((i, {'if_height': height})) + i.bc_requests.append({'if_height': height}) if i == self.interface: self.switch_lagging_interface()