Add fee slider class with network callback.
This commit is contained in:
@@ -58,7 +58,9 @@ def set_testnet():
|
||||
################################## transactions
|
||||
|
||||
FEE_STEP = 10000
|
||||
RECOMMENDED_FEE = 50000
|
||||
MAX_FEE_RATE = 100000
|
||||
FEE_TARGETS = [25, 10, 5, 2]
|
||||
|
||||
COINBASE_MATURITY = 100
|
||||
COIN = 100000000
|
||||
|
||||
|
||||
@@ -37,13 +37,12 @@ import socket
|
||||
import json
|
||||
|
||||
import util
|
||||
import bitcoin
|
||||
from bitcoin import *
|
||||
from interface import Connection, Interface
|
||||
from blockchain import Blockchain
|
||||
from version import ELECTRUM_VERSION, PROTOCOL_VERSION
|
||||
|
||||
FEE_TARGETS = [25, 10, 5, 2]
|
||||
|
||||
DEFAULT_PORTS = {'t':'50001', 's':'50002'}
|
||||
|
||||
DEFAULT_SERVERS = {
|
||||
@@ -202,7 +201,6 @@ class Network(util.DaemonThread):
|
||||
|
||||
self.banner = ''
|
||||
self.donation_address = ''
|
||||
self.fee_estimates = {}
|
||||
self.relay_fee = None
|
||||
self.heights = {}
|
||||
self.merkle_roots = {}
|
||||
@@ -326,7 +324,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 FEE_TARGETS:
|
||||
for i in bitcoin.FEE_TARGETS:
|
||||
self.queue_request('blockchain.estimatefee', [i])
|
||||
self.queue_request('blockchain.relayfee', [])
|
||||
|
||||
@@ -336,7 +334,7 @@ class Network(util.DaemonThread):
|
||||
elif key == 'banner':
|
||||
value = self.banner
|
||||
elif key == 'fee':
|
||||
value = self.fee_estimates
|
||||
value = self.config.fee_estimates
|
||||
elif key == 'updated':
|
||||
value = (self.get_local_height(), self.get_server_height())
|
||||
elif key == 'servers':
|
||||
@@ -345,28 +343,6 @@ class Network(util.DaemonThread):
|
||||
value = self.get_interfaces()
|
||||
return value
|
||||
|
||||
def dynfee(self, i):
|
||||
from bitcoin import RECOMMENDED_FEE
|
||||
if i < 4:
|
||||
j = FEE_TARGETS[i]
|
||||
fee = self.fee_estimates.get(j)
|
||||
else:
|
||||
assert i == 4
|
||||
fee = self.fee_estimates.get(2)
|
||||
if fee is not None:
|
||||
fee += fee/2
|
||||
if fee is not None:
|
||||
fee = min(10*RECOMMENDED_FEE, fee)
|
||||
return fee
|
||||
|
||||
def reverse_dynfee(self, fee_per_kb):
|
||||
import operator
|
||||
dist = map(lambda x: (x[0], abs(x[1] - fee_per_kb)), self.fee_estimates.items())
|
||||
min_target, min_value = min(dist, key=operator.itemgetter(1))
|
||||
if fee_per_kb < self.fee_estimates.get(25)/2:
|
||||
min_target = -1
|
||||
return min_target
|
||||
|
||||
def notify(self, key):
|
||||
if key in ['status', 'updated']:
|
||||
self.trigger_callback(key)
|
||||
@@ -550,7 +526,7 @@ class Network(util.DaemonThread):
|
||||
elif method == 'blockchain.estimatefee':
|
||||
if error is None:
|
||||
i = params[0]
|
||||
self.fee_estimates[i] = int(result * COIN)
|
||||
self.config.fee_estimates[i] = int(result * COIN)
|
||||
self.notify('fee')
|
||||
elif method == 'blockchain.relayfee':
|
||||
if error is None:
|
||||
|
||||
@@ -6,6 +6,8 @@ import os
|
||||
from copy import deepcopy
|
||||
from util import user_dir, print_error, print_msg, print_stderr, PrintError
|
||||
|
||||
from bitcoin import MAX_FEE_RATE, FEE_TARGETS
|
||||
|
||||
SYSTEM_CONFIG_PATH = "/etc/electrum.conf"
|
||||
|
||||
config = None
|
||||
@@ -40,6 +42,8 @@ class SimpleConfig(PrintError):
|
||||
# a thread-safe way.
|
||||
self.lock = threading.RLock()
|
||||
|
||||
self.fee_estimates = {}
|
||||
|
||||
# The following two functions are there for dependency injection when
|
||||
# testing.
|
||||
if read_system_config_function is None:
|
||||
@@ -190,6 +194,43 @@ class SimpleConfig(PrintError):
|
||||
path = wallet.storage.path
|
||||
self.set_key('gui_last_wallet', path)
|
||||
|
||||
def max_fee_rate(self):
|
||||
return self.get('max_fee_rate', MAX_FEE_RATE)
|
||||
|
||||
def dynfee(self, i):
|
||||
if i < 4:
|
||||
j = FEE_TARGETS[i]
|
||||
fee = self.fee_estimates.get(j)
|
||||
else:
|
||||
assert i == 4
|
||||
fee = self.fee_estimates.get(2)
|
||||
if fee is not None:
|
||||
fee += fee/2
|
||||
if fee is not None:
|
||||
fee = min(5*MAX_FEE_RATE, fee)
|
||||
return fee
|
||||
|
||||
def reverse_dynfee(self, fee_per_kb):
|
||||
import operator
|
||||
dist = map(lambda x: (x[0], abs(x[1] - fee_per_kb)), self.fee_estimates.items())
|
||||
min_target, min_value = min(dist, key=operator.itemgetter(1))
|
||||
if fee_per_kb < self.fee_estimates.get(25)/2:
|
||||
min_target = -1
|
||||
return min_target
|
||||
|
||||
def has_fee_estimates(self):
|
||||
return len(self.fee_estimates)==4
|
||||
|
||||
def is_dynfee(self):
|
||||
return self.get('dynamic_fees') and self.has_fee_estimates()
|
||||
|
||||
def fee_per_kb(self):
|
||||
dyn = self.is_dynfee()
|
||||
if dyn:
|
||||
fee_rate = self.dynfee(self.get('fee_level', 2))
|
||||
else:
|
||||
fee_rate = self.get('fee_per_kb', self.max_fee_rate()/2)
|
||||
return fee_rate
|
||||
|
||||
def read_system_config(path=SYSTEM_CONFIG_PATH):
|
||||
"""Parse and return the system config settings in /etc/electrum.conf."""
|
||||
|
||||
@@ -754,16 +754,6 @@ class Abstract_Wallet(PrintError):
|
||||
return ', '.join(labels)
|
||||
return ''
|
||||
|
||||
def fee_per_kb(self, config):
|
||||
b = config.get('dynamic_fees', True)
|
||||
i = config.get('fee_level', 2)
|
||||
if b and self.network and self.network.dynfee(i):
|
||||
return self.network.dynfee(i)
|
||||
else:
|
||||
fee_per_kb = config.get('fee_per_kb', RECOMMENDED_FEE)
|
||||
coeff = {0:0.3, 1:0.5, 2:1, 3:1.5, 4:2}
|
||||
return fee_per_kb * coeff[i]
|
||||
|
||||
def get_tx_status(self, tx_hash, height, conf, timestamp):
|
||||
from util import format_time
|
||||
if conf == 0:
|
||||
@@ -772,9 +762,9 @@ class Abstract_Wallet(PrintError):
|
||||
return 3, 'unknown'
|
||||
is_final = tx and tx.is_final()
|
||||
fee = self.tx_fees.get(tx_hash)
|
||||
if fee and self.network and self.network.dynfee(0):
|
||||
if fee and self.network and self.network.config.has_fee_estimates():
|
||||
size = len(tx.raw)/2
|
||||
low_fee = int(self.network.dynfee(0)*size/1000)
|
||||
low_fee = int(self.network.config.dynfee(0)*size/1000)
|
||||
is_lowfee = fee < low_fee * 0.5
|
||||
else:
|
||||
is_lowfee = False
|
||||
@@ -873,7 +863,7 @@ class Abstract_Wallet(PrintError):
|
||||
return tx
|
||||
|
||||
def estimate_fee(self, config, size):
|
||||
fee = int(self.fee_per_kb(config) * size / 1000.)
|
||||
fee = int(config.fee_per_kb() * size / 1000.)
|
||||
return fee
|
||||
|
||||
def mktx(self, outputs, password, config, fee=None, change_addr=None, domain=None):
|
||||
|
||||
Reference in New Issue
Block a user