1
0

allow fractional feerates (#4324)

This commit is contained in:
ghost43
2018-05-09 19:30:18 +02:00
committed by GitHub
parent 3337af0734
commit dae187bada
4 changed files with 52 additions and 22 deletions

View File

@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
from decimal import Decimal
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import (QLineEdit, QStyle, QStyleOptionFrame)
from decimal import Decimal
from electrum.util import format_satoshis_plain, decimal_point_to_base_unit_name
from electrum.util import format_satoshis_plain, decimal_point_to_base_unit_name, FEERATE_PRECISION
class MyLineEdit(QLineEdit):
@@ -19,7 +20,7 @@ class MyLineEdit(QLineEdit):
class AmountEdit(MyLineEdit):
shortcut = pyqtSignal()
def __init__(self, base_unit, is_int = False, parent=None):
def __init__(self, base_unit, is_int=False, parent=None):
QLineEdit.__init__(self, parent)
# This seems sufficient for hundred-BTC amounts with 8 decimals
self.setFixedWidth(140)
@@ -28,10 +29,14 @@ class AmountEdit(MyLineEdit):
self.is_int = is_int
self.is_shortcut = False
self.help_palette = QPalette()
self.extra_precision = 0
def decimal_point(self):
return 8
def max_precision(self):
return self.decimal_point() + self.extra_precision
def numbify(self):
text = self.text().strip()
if text == '!':
@@ -45,7 +50,7 @@ class AmountEdit(MyLineEdit):
if '.' in s:
p = s.find('.')
s = s.replace('.','')
s = s[:p] + '.' + s[p:p+self.decimal_point()]
s = s[:p] + '.' + s[p:p+self.max_precision()]
self.setText(s)
# setText sets Modified to False. Instead we want to remember
# if updates were because of user modification.
@@ -75,7 +80,7 @@ class AmountEdit(MyLineEdit):
class BTCAmountEdit(AmountEdit):
def __init__(self, decimal_point, is_int = False, parent=None):
def __init__(self, decimal_point, is_int=False, parent=None):
AmountEdit.__init__(self, self._base_unit, is_int, parent)
self.decimal_point = decimal_point
@@ -87,8 +92,15 @@ class BTCAmountEdit(AmountEdit):
x = Decimal(str(self.text()))
except:
return None
p = pow(10, self.decimal_point())
return int( p * x )
# scale it to max allowed precision, make it an int
power = pow(10, self.max_precision())
max_prec_amount = int(power * x)
# if the max precision is simply what unit conversion allows, just return
if self.max_precision() == self.decimal_point():
return max_prec_amount
# otherwise, scale it back to the expected unit
amount = Decimal(max_prec_amount) / pow(10, self.max_precision()-self.decimal_point())
return Decimal(amount) if not self.is_int else int(amount)
def setAmount(self, amount):
if amount is None:
@@ -98,6 +110,11 @@ class BTCAmountEdit(AmountEdit):
class FeerateEdit(BTCAmountEdit):
def __init__(self, decimal_point, is_int=False, parent=None):
super().__init__(decimal_point, is_int, parent)
self.extra_precision = FEERATE_PRECISION
def _base_unit(self):
return 'sat/byte'

View File

@@ -49,7 +49,7 @@ from electrum.util import (format_time, format_satoshis, format_fee_satoshis,
UserCancelled, NoDynamicFeeEstimates, profiler,
export_meta, import_meta, bh2u, bfh, InvalidPassword,
base_units, base_units_list, base_unit_name_to_decimal_point,
decimal_point_to_base_unit_name)
decimal_point_to_base_unit_name, quantize_feerate)
from electrum import Transaction
from electrum import util, bitcoin, commands, coinchooser
from electrum import paymentrequest
@@ -1102,7 +1102,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.config.set_key('fee_per_kb', fee_rate, False)
if fee_rate:
self.feerate_e.setAmount(fee_rate // 1000)
fee_rate = Decimal(fee_rate)
self.feerate_e.setAmount(quantize_feerate(fee_rate / 1000))
else:
self.feerate_e.setAmount(None)
self.fee_e.setModified(False)
@@ -1334,12 +1335,12 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
if freeze_feerate or self.fee_slider.is_active():
displayed_feerate = self.feerate_e.get_amount()
if displayed_feerate:
displayed_feerate = displayed_feerate // 1000
displayed_feerate = quantize_feerate(displayed_feerate / 1000)
else:
# fallback to actual fee
displayed_feerate = fee // size if fee is not None else None
displayed_feerate = quantize_feerate(fee / size) if fee is not None else None
self.feerate_e.setAmount(displayed_feerate)
displayed_fee = displayed_feerate * size if displayed_feerate is not None else None
displayed_fee = round(displayed_feerate * size) if displayed_feerate is not None else None
self.fee_e.setAmount(displayed_fee)
else:
if freeze_fee:
@@ -1349,14 +1350,14 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
displayed_fee = fee
self.fee_e.setAmount(displayed_fee)
displayed_fee = displayed_fee if displayed_fee else 0
displayed_feerate = displayed_fee // size if displayed_fee is not None else None
displayed_feerate = quantize_feerate(displayed_fee / size) if displayed_fee is not None else None
self.feerate_e.setAmount(displayed_feerate)
# show/hide fee rounding icon
feerounding = (fee - displayed_fee) if fee else 0
self.set_feerounding_text(feerounding)
self.set_feerounding_text(int(feerounding))
self.feerounding_icon.setToolTip(self.feerounding_text)
self.feerounding_icon.setVisible(bool(feerounding))
self.feerounding_icon.setVisible(abs(feerounding) >= 1)
if self.is_max:
amount = tx.output_value()