commit 133d74adfb4f5d0401caf50943473b129784b8ae
parent 5bac2fea986d27d0e2aa26fe29987e7d24233f88
Author: ThomasV <thomasv@electrum.org>
Date: Thu, 12 Mar 2020 14:38:35 +0100
fee estimates: use median if auto-connect
Diffstat:
2 files changed, 42 insertions(+), 15 deletions(-)
diff --git a/electrum/interface.py b/electrum/interface.py
@@ -36,6 +36,7 @@ import itertools
import logging
import aiorpcx
+from aiorpcx import TaskGroup
from aiorpcx import RPCSession, Notification, NetAddress, NewlineFramer
from aiorpcx.curio import timeout_after, TaskTimeout
from aiorpcx.jsonrpc import JSONRPC, CodeMessageError
@@ -249,6 +250,7 @@ class Interface(Logger):
self.tip_header = None
self.tip = 0
+ self.fee_estimates_eta = {}
# Dump network messages (only for this interface). Set at runtime from the console.
self.debug = False
@@ -491,6 +493,7 @@ class Interface(Logger):
try:
async with self.taskgroup as group:
await group.spawn(self.ping)
+ await group.spawn(self.request_fee_estimates)
await group.spawn(self.run_fetch_blocks)
await group.spawn(self.monitor_connection)
except aiorpcx.jsonrpc.RPCError as e:
@@ -511,6 +514,21 @@ class Interface(Logger):
await asyncio.sleep(300)
await self.session.send_request('server.ping')
+ async def request_fee_estimates(self):
+ from .simple_config import FEE_ETA_TARGETS
+ from .bitcoin import COIN
+ while True:
+ async with TaskGroup() as group:
+ fee_tasks = []
+ for i in FEE_ETA_TARGETS:
+ fee_tasks.append((i, await group.spawn(self.session.send_request('blockchain.estimatefee', [i]))))
+ for nblock_target, task in fee_tasks:
+ fee = int(task.result() * COIN)
+ if fee < 0: continue
+ self.fee_estimates_eta[nblock_target] = fee
+ self.network.update_fee_estimates()
+ await asyncio.sleep(60)
+
async def close(self):
if self.session:
await self.session.close()
diff --git a/electrum/network.py b/electrum/network.py
@@ -458,24 +458,11 @@ class Network(Logger):
async def _request_fee_estimates(self, interface):
session = interface.session
- from .simple_config import FEE_ETA_TARGETS
self.config.requested_fee_estimates()
- async with TaskGroup() as group:
- histogram_task = await group.spawn(session.send_request('mempool.get_fee_histogram'))
- fee_tasks = []
- for i in FEE_ETA_TARGETS:
- fee_tasks.append((i, await group.spawn(session.send_request('blockchain.estimatefee', [i]))))
- self.config.mempool_fees = histogram = histogram_task.result()
+ histogram = await session.send_request('mempool.get_fee_histogram')
+ self.config.mempool_fees = histogram
self.logger.info(f'fee_histogram {histogram}')
self.notify('fee_histogram')
- fee_estimates_eta = {}
- for nblock_target, task in fee_tasks:
- fee = int(task.result() * COIN)
- fee_estimates_eta[nblock_target] = fee
- if fee < 0: continue
- self.config.update_fee_estimates(nblock_target, fee)
- self.logger.info(f'fee_estimates {fee_estimates_eta}')
- self.notify('fee')
def get_status_value(self, key):
if key == 'status':
@@ -516,6 +503,28 @@ class Network(Logger):
with self.interfaces_lock:
return list(self.interfaces)
+ def get_fee_estimates(self):
+ from statistics import median
+ from .simple_config import FEE_ETA_TARGETS
+ if self.auto_connect:
+ with self.interfaces_lock:
+ out = {}
+ for n in FEE_ETA_TARGETS:
+ try:
+ out[n] = int(median(filter(None, [i.fee_estimates_eta.get(n) for i in self.interfaces.values()])))
+ except:
+ continue
+ return out
+ else:
+ return self.interface.fee_estimates_eta
+
+ def update_fee_estimates(self):
+ e = self.get_fee_estimates()
+ for nblock_target, fee in e.items():
+ self.config.update_fee_estimates(nblock_target, fee)
+ self.logger.info(f'fee_estimates {e}')
+ self.notify('fee')
+
@with_recent_servers_lock
def get_servers(self):
# note: order of sources when adding servers here is crucial!