Merge branch 'feez'
This commit is contained in:
commit
59ed5932a8
|
@ -0,0 +1,43 @@
|
||||||
|
from electrum.i18n import _
|
||||||
|
|
||||||
|
import PyQt4
|
||||||
|
from PyQt4.QtGui import *
|
||||||
|
from PyQt4.QtCore import *
|
||||||
|
import PyQt4.QtCore as QtCore
|
||||||
|
|
||||||
|
class FeeSlider(QSlider):
|
||||||
|
|
||||||
|
def __init__(self, window, config, callback):
|
||||||
|
QSlider.__init__(self, Qt.Horizontal)
|
||||||
|
self.config = config
|
||||||
|
self.fee_step = self.config.max_fee_rate() / 10
|
||||||
|
self.window = window
|
||||||
|
self.callback = callback
|
||||||
|
self.setToolTip('')
|
||||||
|
self.update()
|
||||||
|
self.valueChanged.connect(self.moved)
|
||||||
|
|
||||||
|
def moved(self, pos):
|
||||||
|
from electrum.util import fee_levels
|
||||||
|
dyn = self.config.is_dynfee()
|
||||||
|
fee_rate = self.config.dynfee(pos) if dyn else pos * self.fee_step
|
||||||
|
rate_str = self.window.format_amount(fee_rate) + ' ' + self.window.base_unit() + '/kB'
|
||||||
|
if dyn:
|
||||||
|
tooltip = fee_levels[pos] + '\n' + rate_str
|
||||||
|
else:
|
||||||
|
tooltip = rate_str
|
||||||
|
if self.config.has_fee_estimates():
|
||||||
|
i = self.config.reverse_dynfee(fee_rate)
|
||||||
|
tooltip += '\n' + (_('low fee') if i < 0 else 'Within %d blocks'%i)
|
||||||
|
QToolTip.showText(QCursor.pos(), tooltip, self)
|
||||||
|
self.callback(dyn, pos, fee_rate)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
if self.config.is_dynfee():
|
||||||
|
self.setRange(0, 4)
|
||||||
|
self.setValue(self.config.get('fee_level', 2))
|
||||||
|
else:
|
||||||
|
self.setRange(1, 10)
|
||||||
|
fee_rate = self.config.fee_per_kb()
|
||||||
|
pos = min(fee_rate / self.fee_step, 10)
|
||||||
|
self.setValue(pos)
|
|
@ -59,7 +59,7 @@ from network_dialog import NetworkDialog
|
||||||
from qrcodewidget import QRCodeWidget, QRDialog
|
from qrcodewidget import QRCodeWidget, QRDialog
|
||||||
from qrtextedit import ShowQRTextEdit
|
from qrtextedit import ShowQRTextEdit
|
||||||
from transaction_dialog import show_transaction
|
from transaction_dialog import show_transaction
|
||||||
|
from fee_slider import FeeSlider
|
||||||
|
|
||||||
|
|
||||||
from electrum import ELECTRUM_VERSION
|
from electrum import ELECTRUM_VERSION
|
||||||
|
@ -161,7 +161,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||||
if self.network:
|
if self.network:
|
||||||
self.connect(self, QtCore.SIGNAL('network'), self.on_network_qt)
|
self.connect(self, QtCore.SIGNAL('network'), self.on_network_qt)
|
||||||
interests = ['updated', 'new_transaction', 'status',
|
interests = ['updated', 'new_transaction', 'status',
|
||||||
'banner', 'verified']
|
'banner', 'verified', 'fee']
|
||||||
# To avoid leaking references to "self" that prevent the
|
# To avoid leaking references to "self" that prevent the
|
||||||
# window from being GC-ed when closed, callbacks should be
|
# window from being GC-ed when closed, callbacks should be
|
||||||
# methods of this class only, and specifically not be
|
# methods of this class only, and specifically not be
|
||||||
|
@ -169,12 +169,13 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||||
self.network.register_callback(self.on_network, interests)
|
self.network.register_callback(self.on_network, interests)
|
||||||
# set initial message
|
# set initial message
|
||||||
self.console.showMessage(self.network.banner)
|
self.console.showMessage(self.network.banner)
|
||||||
|
|
||||||
self.network.register_callback(self.on_quotes, ['on_quotes'])
|
self.network.register_callback(self.on_quotes, ['on_quotes'])
|
||||||
self.network.register_callback(self.on_history, ['on_history'])
|
self.network.register_callback(self.on_history, ['on_history'])
|
||||||
self.connect(self, SIGNAL('new_fx_quotes'), self.on_fx_quotes)
|
self.connect(self, SIGNAL('new_fx_quotes'), self.on_fx_quotes)
|
||||||
self.connect(self, SIGNAL('new_fx_history'), self.on_fx_history)
|
self.connect(self, SIGNAL('new_fx_history'), self.on_fx_history)
|
||||||
|
|
||||||
|
# update fee slider in case we missed the callback
|
||||||
|
self.fee_slider.update()
|
||||||
self.load_wallet(wallet)
|
self.load_wallet(wallet)
|
||||||
self.connect_slots(gui_object.timer)
|
self.connect_slots(gui_object.timer)
|
||||||
self.fetch_alias()
|
self.fetch_alias()
|
||||||
|
@ -259,7 +260,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||||
self.need_update.set()
|
self.need_update.set()
|
||||||
elif event == 'new_transaction':
|
elif event == 'new_transaction':
|
||||||
self.tx_notifications.append(args[0])
|
self.tx_notifications.append(args[0])
|
||||||
elif event in ['status', 'banner', 'verified']:
|
elif event in ['status', 'banner', 'verified', 'fee']:
|
||||||
# Handle in GUI thread
|
# Handle in GUI thread
|
||||||
self.emit(QtCore.SIGNAL('network'), event, *args)
|
self.emit(QtCore.SIGNAL('network'), event, *args)
|
||||||
else:
|
else:
|
||||||
|
@ -273,6 +274,9 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||||
self.console.showMessage(args[0])
|
self.console.showMessage(args[0])
|
||||||
elif event == 'verified':
|
elif event == 'verified':
|
||||||
self.history_list.update_item(*args)
|
self.history_list.update_item(*args)
|
||||||
|
elif event == 'fee':
|
||||||
|
if self.config.is_dynfee():
|
||||||
|
self.fee_slider.update()
|
||||||
else:
|
else:
|
||||||
self.print_error("unexpected network_qt signal:", event, args)
|
self.print_error("unexpected network_qt signal:", event, args)
|
||||||
|
|
||||||
|
@ -996,13 +1000,19 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||||
+ _('A suggested fee is automatically added to this field. You may override it. The suggested fee increases with the size of the transaction.')
|
+ _('A suggested fee is automatically added to this field. You may override it. The suggested fee increases with the size of the transaction.')
|
||||||
self.fee_e_label = HelpLabel(_('Fee'), msg)
|
self.fee_e_label = HelpLabel(_('Fee'), msg)
|
||||||
|
|
||||||
fee_cb = lambda x: self.spend_max() if self.is_max else self.update_fee()
|
def fee_cb(dyn, pos, fee_rate):
|
||||||
self.fee_slider = self.create_fee_slider(self, fee_cb)
|
if dyn:
|
||||||
self.fee_slider.setValue(self.config.get('fee_level', 2))
|
self.config.set_key('fee_level', pos, False)
|
||||||
|
else:
|
||||||
|
self.config.set_key('fee_per_kb', fee_rate, False)
|
||||||
|
self.spend_max() if self.is_max else self.update_fee()
|
||||||
|
|
||||||
|
self.fee_slider = FeeSlider(self, self.config, fee_cb)
|
||||||
self.fee_slider.setFixedWidth(140)
|
self.fee_slider.setFixedWidth(140)
|
||||||
|
|
||||||
self.fee_e = BTCAmountEdit(self.get_decimal_point)
|
self.fee_e = BTCAmountEdit(self.get_decimal_point)
|
||||||
self.fee_e.setVisible(self.config.get('show_fee', False))
|
if not self.config.get('show_fee', False):
|
||||||
|
self.fee_e.setVisible(False)
|
||||||
self.fee_e.textEdited.connect(self.update_fee)
|
self.fee_e.textEdited.connect(self.update_fee)
|
||||||
# This is so that when the user blanks the fee and moves on,
|
# This is so that when the user blanks the fee and moves on,
|
||||||
# we go back to auto-calculate mode and put a fee back.
|
# we go back to auto-calculate mode and put a fee back.
|
||||||
|
@ -1275,9 +1285,9 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||||
if extra_fee:
|
if extra_fee:
|
||||||
msg.append( _("Additional fees") + ": " + self.format_amount_and_units(extra_fee) )
|
msg.append( _("Additional fees") + ": " + self.format_amount_and_units(extra_fee) )
|
||||||
|
|
||||||
confirm_rate = self.config.get('confirm_fee', 200000)
|
confirm_rate = 2 * self.config.max_fee_rate()
|
||||||
if tx.get_fee() > confirm_rate * tx.estimated_size() / 1000:
|
if tx.get_fee() > confirm_rate * tx.estimated_size() / 1000:
|
||||||
msg.append(_('Warning')+ ': ' + _("The fee for this transaction seems unusually high."))
|
msg.append(_('Warning') + ': ' + _("The fee for this transaction seems unusually high."))
|
||||||
|
|
||||||
if self.wallet.has_password():
|
if self.wallet.has_password():
|
||||||
msg.append("")
|
msg.append("")
|
||||||
|
@ -2370,28 +2380,14 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||||
nz.valueChanged.connect(on_nz)
|
nz.valueChanged.connect(on_nz)
|
||||||
gui_widgets.append((nz_label, nz))
|
gui_widgets.append((nz_label, nz))
|
||||||
|
|
||||||
dynfee_cb = QCheckBox(_('Use static fees'))
|
dynfee_cb = QCheckBox(_('Use dynamic fees'))
|
||||||
dynfee_cb.setChecked(not self.config.get('dynamic_fees', True))
|
dynfee_cb.setChecked(self.config.get('dynamic_fees', True))
|
||||||
dynfee_cb.setToolTip(_("Do not use fees recommended by the server."))
|
dynfee_cb.setToolTip(_("Use fees recommended by the server."))
|
||||||
fee_e = BTCkBEdit(self.get_decimal_point)
|
|
||||||
def on_fee(is_done):
|
|
||||||
if self.config.get('dynamic_fees', True):
|
|
||||||
return
|
|
||||||
v = fee_e.get_amount() or 0
|
|
||||||
self.config.set_key('fee_per_kb', v, is_done)
|
|
||||||
self.update_fee()
|
|
||||||
def update_feeperkb():
|
|
||||||
fee_e.setAmount(self.config.get('fee_per_kb', bitcoin.RECOMMENDED_FEE))
|
|
||||||
b = self.config.get('dynamic_fees', True)
|
|
||||||
fee_e.setEnabled(not b)
|
|
||||||
def on_dynfee(x):
|
def on_dynfee(x):
|
||||||
self.config.set_key('dynamic_fees', x != Qt.Checked)
|
self.config.set_key('dynamic_fees', x == Qt.Checked)
|
||||||
update_feeperkb()
|
self.fee_slider.update()
|
||||||
fee_e.editingFinished.connect(lambda: on_fee(True))
|
|
||||||
fee_e.textEdited.connect(lambda: on_fee(False))
|
|
||||||
dynfee_cb.stateChanged.connect(on_dynfee)
|
dynfee_cb.stateChanged.connect(on_dynfee)
|
||||||
update_feeperkb()
|
fee_widgets.append((dynfee_cb, None))
|
||||||
fee_widgets.append((dynfee_cb, fee_e))
|
|
||||||
|
|
||||||
feebox_cb = QCheckBox(_('Edit fees manually'))
|
feebox_cb = QCheckBox(_('Edit fees manually'))
|
||||||
feebox_cb.setChecked(self.config.get('show_fee', False))
|
feebox_cb.setChecked(self.config.get('show_fee', False))
|
||||||
|
@ -2767,25 +2763,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||||
vbox.addLayout(Buttons(CloseButton(d)))
|
vbox.addLayout(Buttons(CloseButton(d)))
|
||||||
d.exec_()
|
d.exec_()
|
||||||
|
|
||||||
def create_fee_slider(self, parent, callback):
|
|
||||||
from electrum.util import fee_levels
|
|
||||||
from electrum.bitcoin import FEE_STEP, RECOMMENDED_FEE
|
|
||||||
fee_slider = QSlider(Qt.Horizontal, parent)
|
|
||||||
def slider_moved():
|
|
||||||
pos = fee_slider.sliderPosition()
|
|
||||||
self.config.set_key('fee_level', pos, False)
|
|
||||||
is_dyn = self.config.get('dynamic_fees') and self.network and self.network.dynfee(pos)
|
|
||||||
fee_rate = self.wallet.fee_per_kb(self.config)
|
|
||||||
tooltip = fee_levels[pos] + '\n' if is_dyn else ''
|
|
||||||
tooltip += self.format_amount(fee_rate) + ' ' + self.base_unit() + '/kB'
|
|
||||||
QToolTip.showText(QCursor.pos(), tooltip, self.fee_slider)
|
|
||||||
callback(fee_rate)
|
|
||||||
|
|
||||||
fee_slider.setRange(0, 4)
|
|
||||||
fee_slider.setToolTip('')
|
|
||||||
fee_slider.setValue(self.config.get('fee_level', 2))
|
|
||||||
fee_slider.valueChanged.connect(slider_moved)
|
|
||||||
return fee_slider
|
|
||||||
|
|
||||||
def bump_fee_dialog(self, tx):
|
def bump_fee_dialog(self, tx):
|
||||||
is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx)
|
is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx)
|
||||||
|
@ -2799,12 +2776,11 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||||
fee_e.setAmount(fee * 1.5)
|
fee_e.setAmount(fee * 1.5)
|
||||||
vbox.addWidget(fee_e)
|
vbox.addWidget(fee_e)
|
||||||
|
|
||||||
def on_rate(fee_rate):
|
def on_rate(dyn, pos, fee_rate):
|
||||||
fee = fee_rate * tx_size / 1000
|
fee = fee_rate * tx_size / 1000
|
||||||
fee_e.setAmount(fee)
|
fee_e.setAmount(fee)
|
||||||
fee_slider = self.create_fee_slider(d, on_rate)
|
fee_slider = FeeSlider(self, self.config, on_rate)
|
||||||
vbox.addWidget(fee_slider)
|
vbox.addWidget(fee_slider)
|
||||||
|
|
||||||
cb = QCheckBox(_('Final'))
|
cb = QCheckBox(_('Final'))
|
||||||
vbox.addWidget(cb)
|
vbox.addWidget(cb)
|
||||||
vbox.addLayout(Buttons(CancelButton(d), OkButton(d)))
|
vbox.addLayout(Buttons(CancelButton(d), OkButton(d)))
|
||||||
|
|
|
@ -58,7 +58,9 @@ def set_testnet():
|
||||||
################################## transactions
|
################################## transactions
|
||||||
|
|
||||||
FEE_STEP = 10000
|
FEE_STEP = 10000
|
||||||
RECOMMENDED_FEE = 50000
|
MAX_FEE_RATE = 100000
|
||||||
|
FEE_TARGETS = [25, 10, 5, 2]
|
||||||
|
|
||||||
COINBASE_MATURITY = 100
|
COINBASE_MATURITY = 100
|
||||||
COIN = 100000000
|
COIN = 100000000
|
||||||
|
|
||||||
|
|
|
@ -37,13 +37,12 @@ import socket
|
||||||
import json
|
import json
|
||||||
|
|
||||||
import util
|
import util
|
||||||
|
import bitcoin
|
||||||
from bitcoin import *
|
from bitcoin import *
|
||||||
from interface import Connection, Interface
|
from interface import Connection, Interface
|
||||||
from blockchain import Blockchain
|
from blockchain import Blockchain
|
||||||
from version import ELECTRUM_VERSION, PROTOCOL_VERSION
|
from version import ELECTRUM_VERSION, PROTOCOL_VERSION
|
||||||
|
|
||||||
FEE_TARGETS = [25, 10, 5, 2]
|
|
||||||
|
|
||||||
DEFAULT_PORTS = {'t':'50001', 's':'50002'}
|
DEFAULT_PORTS = {'t':'50001', 's':'50002'}
|
||||||
|
|
||||||
DEFAULT_SERVERS = {
|
DEFAULT_SERVERS = {
|
||||||
|
@ -202,7 +201,6 @@ class Network(util.DaemonThread):
|
||||||
|
|
||||||
self.banner = ''
|
self.banner = ''
|
||||||
self.donation_address = ''
|
self.donation_address = ''
|
||||||
self.fee_estimates = {}
|
|
||||||
self.relay_fee = None
|
self.relay_fee = None
|
||||||
self.heights = {}
|
self.heights = {}
|
||||||
self.merkle_roots = {}
|
self.merkle_roots = {}
|
||||||
|
@ -326,7 +324,7 @@ class Network(util.DaemonThread):
|
||||||
self.queue_request('server.banner', [])
|
self.queue_request('server.banner', [])
|
||||||
self.queue_request('server.donation_address', [])
|
self.queue_request('server.donation_address', [])
|
||||||
self.queue_request('server.peers.subscribe', [])
|
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.estimatefee', [i])
|
||||||
self.queue_request('blockchain.relayfee', [])
|
self.queue_request('blockchain.relayfee', [])
|
||||||
|
|
||||||
|
@ -336,7 +334,7 @@ class Network(util.DaemonThread):
|
||||||
elif key == 'banner':
|
elif key == 'banner':
|
||||||
value = self.banner
|
value = self.banner
|
||||||
elif key == 'fee':
|
elif key == 'fee':
|
||||||
value = self.fee_estimates
|
value = self.config.fee_estimates
|
||||||
elif key == 'updated':
|
elif key == 'updated':
|
||||||
value = (self.get_local_height(), self.get_server_height())
|
value = (self.get_local_height(), self.get_server_height())
|
||||||
elif key == 'servers':
|
elif key == 'servers':
|
||||||
|
@ -345,28 +343,6 @@ class Network(util.DaemonThread):
|
||||||
value = self.get_interfaces()
|
value = self.get_interfaces()
|
||||||
return value
|
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):
|
def notify(self, key):
|
||||||
if key in ['status', 'updated']:
|
if key in ['status', 'updated']:
|
||||||
self.trigger_callback(key)
|
self.trigger_callback(key)
|
||||||
|
@ -550,7 +526,7 @@ class Network(util.DaemonThread):
|
||||||
elif method == 'blockchain.estimatefee':
|
elif method == 'blockchain.estimatefee':
|
||||||
if error is None:
|
if error is None:
|
||||||
i = params[0]
|
i = params[0]
|
||||||
self.fee_estimates[i] = int(result * COIN)
|
self.config.fee_estimates[i] = int(result * COIN)
|
||||||
self.notify('fee')
|
self.notify('fee')
|
||||||
elif method == 'blockchain.relayfee':
|
elif method == 'blockchain.relayfee':
|
||||||
if error is None:
|
if error is None:
|
||||||
|
|
|
@ -6,6 +6,8 @@ import os
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from util import user_dir, print_error, print_msg, print_stderr, PrintError
|
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"
|
SYSTEM_CONFIG_PATH = "/etc/electrum.conf"
|
||||||
|
|
||||||
config = None
|
config = None
|
||||||
|
@ -40,6 +42,8 @@ class SimpleConfig(PrintError):
|
||||||
# a thread-safe way.
|
# a thread-safe way.
|
||||||
self.lock = threading.RLock()
|
self.lock = threading.RLock()
|
||||||
|
|
||||||
|
self.fee_estimates = {}
|
||||||
|
|
||||||
# The following two functions are there for dependency injection when
|
# The following two functions are there for dependency injection when
|
||||||
# testing.
|
# testing.
|
||||||
if read_system_config_function is None:
|
if read_system_config_function is None:
|
||||||
|
@ -190,6 +194,43 @@ class SimpleConfig(PrintError):
|
||||||
path = wallet.storage.path
|
path = wallet.storage.path
|
||||||
self.set_key('gui_last_wallet', 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):
|
def read_system_config(path=SYSTEM_CONFIG_PATH):
|
||||||
"""Parse and return the system config settings in /etc/electrum.conf."""
|
"""Parse and return the system config settings in /etc/electrum.conf."""
|
||||||
|
|
|
@ -754,16 +754,6 @@ class Abstract_Wallet(PrintError):
|
||||||
return ', '.join(labels)
|
return ', '.join(labels)
|
||||||
return ''
|
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):
|
def get_tx_status(self, tx_hash, height, conf, timestamp):
|
||||||
from util import format_time
|
from util import format_time
|
||||||
if conf == 0:
|
if conf == 0:
|
||||||
|
@ -772,9 +762,9 @@ class Abstract_Wallet(PrintError):
|
||||||
return 3, 'unknown'
|
return 3, 'unknown'
|
||||||
is_final = tx and tx.is_final()
|
is_final = tx and tx.is_final()
|
||||||
fee = self.tx_fees.get(tx_hash)
|
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
|
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
|
is_lowfee = fee < low_fee * 0.5
|
||||||
else:
|
else:
|
||||||
is_lowfee = False
|
is_lowfee = False
|
||||||
|
@ -873,7 +863,7 @@ class Abstract_Wallet(PrintError):
|
||||||
return tx
|
return tx
|
||||||
|
|
||||||
def estimate_fee(self, config, size):
|
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
|
return fee
|
||||||
|
|
||||||
def mktx(self, outputs, password, config, fee=None, change_addr=None, domain=None):
|
def mktx(self, outputs, password, config, fee=None, change_addr=None, domain=None):
|
||||||
|
|
Loading…
Reference in New Issue