fee estimates: use median if auto-connect
This commit is contained in:
@@ -36,6 +36,7 @@ import itertools
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
import aiorpcx
|
import aiorpcx
|
||||||
|
from aiorpcx import TaskGroup
|
||||||
from aiorpcx import RPCSession, Notification, NetAddress, NewlineFramer
|
from aiorpcx import RPCSession, Notification, NetAddress, NewlineFramer
|
||||||
from aiorpcx.curio import timeout_after, TaskTimeout
|
from aiorpcx.curio import timeout_after, TaskTimeout
|
||||||
from aiorpcx.jsonrpc import JSONRPC, CodeMessageError
|
from aiorpcx.jsonrpc import JSONRPC, CodeMessageError
|
||||||
@@ -249,6 +250,7 @@ class Interface(Logger):
|
|||||||
|
|
||||||
self.tip_header = None
|
self.tip_header = None
|
||||||
self.tip = 0
|
self.tip = 0
|
||||||
|
self.fee_estimates_eta = {}
|
||||||
|
|
||||||
# Dump network messages (only for this interface). Set at runtime from the console.
|
# Dump network messages (only for this interface). Set at runtime from the console.
|
||||||
self.debug = False
|
self.debug = False
|
||||||
@@ -491,6 +493,7 @@ class Interface(Logger):
|
|||||||
try:
|
try:
|
||||||
async with self.taskgroup as group:
|
async with self.taskgroup as group:
|
||||||
await group.spawn(self.ping)
|
await group.spawn(self.ping)
|
||||||
|
await group.spawn(self.request_fee_estimates)
|
||||||
await group.spawn(self.run_fetch_blocks)
|
await group.spawn(self.run_fetch_blocks)
|
||||||
await group.spawn(self.monitor_connection)
|
await group.spawn(self.monitor_connection)
|
||||||
except aiorpcx.jsonrpc.RPCError as e:
|
except aiorpcx.jsonrpc.RPCError as e:
|
||||||
@@ -511,6 +514,21 @@ class Interface(Logger):
|
|||||||
await asyncio.sleep(300)
|
await asyncio.sleep(300)
|
||||||
await self.session.send_request('server.ping')
|
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):
|
async def close(self):
|
||||||
if self.session:
|
if self.session:
|
||||||
await self.session.close()
|
await self.session.close()
|
||||||
|
|||||||
@@ -458,24 +458,11 @@ class Network(Logger):
|
|||||||
|
|
||||||
async def _request_fee_estimates(self, interface):
|
async def _request_fee_estimates(self, interface):
|
||||||
session = interface.session
|
session = interface.session
|
||||||
from .simple_config import FEE_ETA_TARGETS
|
|
||||||
self.config.requested_fee_estimates()
|
self.config.requested_fee_estimates()
|
||||||
async with TaskGroup() as group:
|
histogram = await session.send_request('mempool.get_fee_histogram')
|
||||||
histogram_task = await group.spawn(session.send_request('mempool.get_fee_histogram'))
|
self.config.mempool_fees = 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()
|
|
||||||
self.logger.info(f'fee_histogram {histogram}')
|
self.logger.info(f'fee_histogram {histogram}')
|
||||||
self.notify('fee_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):
|
def get_status_value(self, key):
|
||||||
if key == 'status':
|
if key == 'status':
|
||||||
@@ -516,6 +503,28 @@ class Network(Logger):
|
|||||||
with self.interfaces_lock:
|
with self.interfaces_lock:
|
||||||
return list(self.interfaces)
|
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
|
@with_recent_servers_lock
|
||||||
def get_servers(self):
|
def get_servers(self):
|
||||||
# note: order of sources when adding servers here is crucial!
|
# note: order of sources when adding servers here is crucial!
|
||||||
|
|||||||
Reference in New Issue
Block a user