tMerge pull request #2906 from SomberNight/polling_fees - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit d4b1c6616885aa69eea8716e02845e15e629d1d5 DIR parent e8b634ac4a2982fb09dd4a3ad78e1bced8d637ae HTML Author: ThomasV <thomasv@electrum.org> Date: Wed, 1 Nov 2017 20:53:01 +0100 Merge pull request #2906 from SomberNight/polling_fees Periodically poll fee estimates from server Diffstat: M lib/network.py | 13 ++++++++++--- M lib/simple_config.py | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) --- DIR diff --git a/lib/network.py b/lib/network.py t@@ -316,8 +316,7 @@ class Network(util.DaemonThread): self.queue_request('server.banner', []) self.queue_request('server.donation_address', []) self.queue_request('server.peers.subscribe', []) - for i in bitcoin.FEE_TARGETS: - self.queue_request('blockchain.estimatefee', [i]) + self.request_fee_estimates() self.queue_request('blockchain.relayfee', []) if self.interface.ping_required(): params = [ELECTRUM_VERSION, PROTOCOL_VERSION] t@@ -325,6 +324,11 @@ class Network(util.DaemonThread): for h in self.subscribed_addresses: self.queue_request('blockchain.scripthash.subscribe', [h]) + def request_fee_estimates(self): + self.config.requested_fee_estimates() + for i in bitcoin.FEE_TARGETS: + self.queue_request('blockchain.estimatefee', [i]) + def get_status_value(self, key): if key == 'status': value = self.connection_status t@@ -547,7 +551,7 @@ class Network(util.DaemonThread): if error is None and result > 0: i = params[0] fee = int(result*COIN) - self.config.fee_estimates[i] = fee + self.config.update_fee_estimates(i, fee) self.print_error("fee_estimates[%d]" % i, fee) self.notify('fee') elif method == 'blockchain.relayfee': t@@ -752,6 +756,9 @@ class Network(util.DaemonThread): self.server_retry_time = now else: self.switch_to_interface(self.default_server) + else: + 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) DIR diff --git a/lib/simple_config.py b/lib/simple_config.py t@@ -6,6 +6,7 @@ from __future__ import unicode_literals import ast import json import threading +import time import os import stat t@@ -51,6 +52,8 @@ class SimpleConfig(PrintError): self.lock = threading.RLock() self.fee_estimates = {} + self.fee_estimates_last_updated = {} + self.last_time_fee_estimates_requested = 0 # zero ensures immediate fees # The following two functions are there for dependency injection when # testing. t@@ -253,6 +256,24 @@ class SimpleConfig(PrintError): fee_rate = self.get('fee_per_kb', self.max_fee_rate()/2) return fee_rate + def update_fee_estimates(self, key, value): + self.fee_estimates[key] = value + self.fee_estimates_last_updated[key] = time.time() + + def is_fee_estimates_update_required(self): + """Checks time since last requested and updated fee estimates. + Returns True if an update should be requested. + """ + now = time.time() + prev_updates = self.fee_estimates_last_updated.values() + oldest_fee_time = min(prev_updates) if prev_updates else 0 + stale_fees = now - oldest_fee_time > 7200 + old_request = now - self.last_time_fee_estimates_requested > 60 + return stale_fees and old_request + + def requested_fee_estimates(self): + self.last_time_fee_estimates_requested = time.time() + def get_video_device(self): device = self.get("video_device", "default") if device == 'default':