Browse Source

fee estimates: use median if auto-connect

hard-fail-on-bad-server-string
ThomasV 5 years ago
parent
commit
133d74adfb
  1. 18
      electrum/interface.py
  2. 39
      electrum/network.py

18
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()

39
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!

Loading…
Cancel
Save