diff --git a/lib/network.py b/lib/network.py index b1beaced..c5493e30 100644 --- a/lib/network.py +++ b/lib/network.py @@ -168,6 +168,7 @@ class Network(util.DaemonThread): self.utxo_roots = {} # callbacks passed with subscriptions self.subscriptions = defaultdict(list) + self.sub_cache = {} # callbacks set by the GUI self.callbacks = defaultdict(list) @@ -275,6 +276,7 @@ class Network(util.DaemonThread): def send_subscriptions(self): self.print_error('sending subscriptions to', self.interface.server, len(self.unanswered_requests), len(self.subscribed_addresses)) + self.sub_cache.clear() # Resend unanswered requests requests = self.unanswered_requests.values() self.unanswered_requests = {} @@ -462,6 +464,7 @@ class Network(util.DaemonThread): error = response.get('error') result = response.get('result') method = response.get('method') + params = response.get('params') # We handle some responses; return the rest to the client. if method == 'server.version': @@ -486,9 +489,11 @@ class Network(util.DaemonThread): self.on_get_chunk(interface, response) elif method == 'blockchain.block.get_header': self.on_get_header(interface, response) - else: - params = response['params'] - callbacks = self.subscriptions.get(repr((method, params)), []) + + elif method.endswith('.subscribe'): + k = repr((method, params)) + self.sub_cache[k] = response + callbacks = self.subscriptions.get(k, []) for callback in callbacks: callback(response) @@ -496,7 +501,6 @@ class Network(util.DaemonThread): responses = interface.get_responses() for request, response in responses: - callback = None if request: method, params, message_id = request # client requests go through self.send() with a @@ -505,7 +509,6 @@ class Network(util.DaemonThread): client_req = self.unanswered_requests.pop(message_id, None) if client_req: assert interface == self.interface - # Copy the request method and params to the response response['method'] = method response['params'] = params @@ -534,14 +537,23 @@ class Network(util.DaemonThread): '''Messages is a list of (method, params) tuples''' with self.lock: subs = filter(lambda (m,v): m.endswith('.subscribe'), messages) - for method, params in subs: - k = repr((method, params)) - l = self.subscriptions.get(k, []) - if callback not in l: - l.append(callback) - self.subscriptions[k] = l - - self.pending_sends += messages + for message in messages: + method, params = message + if method.endswith('.subscribe'): + k = repr((method, params)) + l = self.subscriptions.get(k, []) + if callback not in l: + l.append(callback) + self.subscriptions[k] = l + # check cached response + r = self.sub_cache.get(k) + if r is not None: + util.print_error("cache hit", k) + callback(r) + else: + self.pending_sends.append(message) + else: + self.pending_sends.append(message) def process_pending_sends(self):