Merge pull request #3878 from SomberNight/coinchooser_output_rounding
coinchooser: make output value rounding configurable
This commit is contained in:
commit
cccf380753
|
@ -1136,7 +1136,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||||
def feerounding_onclick():
|
def feerounding_onclick():
|
||||||
text = (self.feerounding_text + '\n\n' +
|
text = (self.feerounding_text + '\n\n' +
|
||||||
_('To somewhat protect your privacy, Electrum tries to create change with similar precision to other outputs.') + ' ' +
|
_('To somewhat protect your privacy, Electrum tries to create change with similar precision to other outputs.') + ' ' +
|
||||||
_('At most 100 satoshis might be lost due to this rounding.') + '\n' +
|
_('At most 100 satoshis might be lost due to this rounding.') + ' ' +
|
||||||
|
_("You can disable this setting in '{}'.").format(_('Preferences')) + '\n' +
|
||||||
_('Also, dust is not kept as change, but added to the fee.'))
|
_('Also, dust is not kept as change, but added to the fee.'))
|
||||||
QMessageBox.information(self, 'Fee rounding', text)
|
QMessageBox.information(self, 'Fee rounding', text)
|
||||||
|
|
||||||
|
@ -2893,6 +2894,18 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||||
unconf_cb.stateChanged.connect(on_unconf)
|
unconf_cb.stateChanged.connect(on_unconf)
|
||||||
tx_widgets.append((unconf_cb, None))
|
tx_widgets.append((unconf_cb, None))
|
||||||
|
|
||||||
|
def on_outrounding(x):
|
||||||
|
self.config.set_key('coin_chooser_output_rounding', bool(x))
|
||||||
|
enable_outrounding = self.config.get('coin_chooser_output_rounding', False)
|
||||||
|
outrounding_cb = QCheckBox(_('Enable output value rounding'))
|
||||||
|
outrounding_cb.setToolTip(
|
||||||
|
_('Set the value of the change output so that it has similar precision to the other outputs.') + '\n' +
|
||||||
|
_('This might improve your privacy somewhat.') + '\n' +
|
||||||
|
_('If enabled, at most 100 satoshis might be lost due to this, per transaction.'))
|
||||||
|
outrounding_cb.setChecked(enable_outrounding)
|
||||||
|
outrounding_cb.stateChanged.connect(on_outrounding)
|
||||||
|
tx_widgets.append((outrounding_cb, None))
|
||||||
|
|
||||||
# Fiat Currency
|
# Fiat Currency
|
||||||
hist_checkbox = QCheckBox()
|
hist_checkbox = QCheckBox()
|
||||||
fiat_address_checkbox = QCheckBox()
|
fiat_address_checkbox = QCheckBox()
|
||||||
|
|
|
@ -87,6 +87,8 @@ def strip_unneeded(bkts, sufficient_funds):
|
||||||
|
|
||||||
class CoinChooserBase(PrintError):
|
class CoinChooserBase(PrintError):
|
||||||
|
|
||||||
|
enable_output_value_rounding = False
|
||||||
|
|
||||||
def keys(self, coins):
|
def keys(self, coins):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@ -135,7 +137,13 @@ class CoinChooserBase(PrintError):
|
||||||
zeroes = [trailing_zeroes(i) for i in output_amounts]
|
zeroes = [trailing_zeroes(i) for i in output_amounts]
|
||||||
min_zeroes = min(zeroes)
|
min_zeroes = min(zeroes)
|
||||||
max_zeroes = max(zeroes)
|
max_zeroes = max(zeroes)
|
||||||
zeroes = range(max(0, min_zeroes - 1), (max_zeroes + 1) + 1)
|
|
||||||
|
if n > 1:
|
||||||
|
zeroes = range(max(0, min_zeroes - 1), (max_zeroes + 1) + 1)
|
||||||
|
else:
|
||||||
|
# if there is only one change output, this will ensure that we aim
|
||||||
|
# to have one that is exactly as precise as the most precise output
|
||||||
|
zeroes = [min_zeroes]
|
||||||
|
|
||||||
# Calculate change; randomize it a bit if using more than 1 output
|
# Calculate change; randomize it a bit if using more than 1 output
|
||||||
remaining = change_amount
|
remaining = change_amount
|
||||||
|
@ -150,8 +158,10 @@ class CoinChooserBase(PrintError):
|
||||||
n -= 1
|
n -= 1
|
||||||
|
|
||||||
# Last change output. Round down to maximum precision but lose
|
# Last change output. Round down to maximum precision but lose
|
||||||
# no more than 100 satoshis to fees (2dp)
|
# no more than 10**max_dp_to_round_for_privacy
|
||||||
N = pow(10, min(2, zeroes[0]))
|
# e.g. a max of 2 decimal places means losing 100 satoshis to fees
|
||||||
|
max_dp_to_round_for_privacy = 2 if self.enable_output_value_rounding else 0
|
||||||
|
N = pow(10, min(max_dp_to_round_for_privacy, zeroes[0]))
|
||||||
amount = (remaining // N) * N
|
amount = (remaining // N) * N
|
||||||
amounts.append(amount)
|
amounts.append(amount)
|
||||||
|
|
||||||
|
@ -370,4 +380,6 @@ def get_name(config):
|
||||||
|
|
||||||
def get_coin_chooser(config):
|
def get_coin_chooser(config):
|
||||||
klass = COIN_CHOOSERS[get_name(config)]
|
klass = COIN_CHOOSERS[get_name(config)]
|
||||||
return klass()
|
coinchooser = klass()
|
||||||
|
coinchooser.enable_output_value_rounding = config.get('coin_chooser_output_rounding', False)
|
||||||
|
return coinchooser
|
||||||
|
|
Loading…
Reference in New Issue