Browse Source

Support maxcjfee settings for tumble in Qt

Also refactor tumbler offer filter callback to tumble_support
Add default values for first page of tumbler wizard (Qt)
master
Adam Gibson 9 years ago
parent
commit
cdd072eb8c
No known key found for this signature in database
GPG Key ID: B3AE09F1E9A3197A
  1. 3
      jmclient/jmclient/__init__.py
  2. 16
      jmclient/jmclient/tumble_support.py
  3. 10
      scripts/joinmarket-qt.py
  4. 34
      scripts/qtsupport.py
  5. 17
      scripts/tumbler.py

3
jmclient/jmclient/__init__.py

@ -35,7 +35,8 @@ from .schedule import (get_schedule, get_tumble_schedule, schedule_to_text,
schedule_to_text)
from .commitment_utils import get_utxo_info, validate_utxo_data, quit
from .tumble_support import (tumbler_taker_finished_update, restart_waiter,
restart_wait, get_tumble_log)
restart_wait, get_tumble_log,
tumbler_filter_orders_callback)
# Set default logging handler to avoid "No handler found" warnings.
try:

16
jmclient/jmclient/tumble_support.py

@ -168,3 +168,19 @@ def tumbler_taker_finished_update(taker, schedulefile, tumble_log, options,
taker.schedule[taker.schedule_index][5] = 1
with open(schedulefile, "wb") as f:
f.write(schedule_to_text(taker.schedule))
def tumbler_filter_orders_callback(orders_fees, cjamount, taker, options):
"""Since the tumbler does not use interactive fee checking,
we use the -x values from the command line instead.
"""
orders, total_cj_fee = orders_fees
abs_cj_fee = 1.0 * total_cj_fee / taker.n_counterparties
rel_cj_fee = abs_cj_fee / cjamount
log.info('rel/abs average fee = ' + str(rel_cj_fee) + ' / ' + str(
abs_cj_fee))
if rel_cj_fee > options['maxcjfee'][
0] and abs_cj_fee > options['maxcjfee'][1]:
log.info("Rejected fees as too high according to options, will retry.")
return "retry"
return True

10
scripts/joinmarket-qt.py

@ -53,7 +53,7 @@ from jmclient import (load_program_config, get_network, Wallet,
get_blockchain_interface_instance, sync_wallet,
RegtestBitcoinCoreInterface, tweak_tumble_schedule,
human_readable_schedule_entry, tumbler_taker_finished_update,
get_tumble_log, restart_wait)
get_tumble_log, restart_wait, tumbler_filter_orders_callback)
from qtsupport import (ScheduleWizard, warnings, config_tips, config_types,
TaskThread, QtHandler, XStream, Buttons, CloseButton,
@ -614,7 +614,9 @@ class SpendTab(QWidget):
#sync_wallet(w.wallet, fast=True)
#Decide whether to interrupt processing to sanity check the fees
if jm_single().config.get("GUI", "checktx") == "true":
if self.tumbler_options:
check_offers_callback = self.checkOffersTumbler
elif jm_single().config.get("GUI", "checktx") == "true":
check_offers_callback = self.callback_checkOffers
else:
check_offers_callback = None
@ -699,6 +701,10 @@ class SpendTab(QWidget):
self.abortTransactions()
self.taker_info_response = True
def checkOffersTumbler(self, offers_fees, cjamount):
return tumbler_filter_orders_callback(offers_fees, cjamount,
self.taker, self.tumbler_options)
def checkOffers(self):
"""Parse offers and total fee from client protocol,
allow the user to agree or decide.

34
scripts/qtsupport.py

@ -508,24 +508,29 @@ class SchDynamicPage1(QWizardPage):
sN = ['Starting mixdepth', 'Average number of counterparties',
'How many mixdepths to tumble through',
'Average wait time between transactions, in minutes',
'Average number of transactions per mixdepth']
'Average number of transactions per mixdepth',
'Max relative fee per counterparty (e.g. 0.005)',
'Max fee per counterparty, satoshis (e.g. 10000)']
#Tooltips
sH = ["The starting mixdepth can be decided from the Wallet tab; it must "
"have coins in it, but it's OK if some coins are in other mixdepths.",
"How many other participants are in each coinjoin, on average; but "
"each individual coinjoin will have a number that's slightly varied "
"from this, randomly",
"each individual coinjoin will have a number that's varied according to "
"settings on the next page",
"For example, if you start at mixdepth 1 and enter 4 here, the tumble "
"will move coins from mixdepth 1 to mixdepth 5",
"This is the time waited *after* 1 confirmation has occurred, and is "
"varied randomly.",
"Will be varied randomly, with a minimum of 1 per mixdepth"]
"Will be varied randomly, see advanced settings next page",
"A decimal fraction (e.g. 0.001 = 0.1%) (this AND next must be violated to reject",
"Integer number of satoshis (this AND previous must be violated to reject)"]
#types
sT = [int, int, int, float, int]
sT = [int, int, int, float, int, float, int]
#constraints
sMM = [(0, jm_single().config.getint("GUI", "max_mix_depth") - 1), (3, 20),
(1, 5), (0.00000001, 100.0, 8), (2, 10)]
sD = ['', '', '', '', '']
(1, 5), (0.00000001, 100.0, 8), (2, 10), (0.000001, 0.25, 6),
(0, 10000000)]
sD = ['0', '4', '4', '0.25', '3', '0.005', '10000']
for x in zip(sN, sH, sT, sD, sMM):
ql = QLabel(x[0])
ql.setToolTip(x[1])
@ -541,11 +546,13 @@ class SchDynamicPage1(QWizardPage):
layout.addWidget(x[0], i + 1, 0)
layout.addWidget(x[1], i + 1, 1, 1, 2)
self.setLayout(layout)
self.registerField("mixdepthsrc*", results[0][1])
self.registerField("makercount*", results[1][1])
self.registerField("mixdepthcount*", results[2][1])
self.registerField("timelambda*", results[3][1])
self.registerField("txcountparams*", results[4][1])
self.registerField("mixdepthsrc", results[0][1])
self.registerField("makercount", results[1][1])
self.registerField("mixdepthcount", results[2][1])
self.registerField("timelambda", results[3][1])
self.registerField("txcountparams", results[4][1])
self.registerField("maxrelfee", results[5][1])
self.registerField("maxabsfee", results[6][1])
class SchDynamicPage2(QWizardPage):
@ -692,6 +699,9 @@ class ScheduleWizard(QWizard):
self.opts['timelambda'] = float(self.field("timelambda").toString())
self.opts['waittime'] = float(self.field("waittime").toString())
self.opts['mincjamount'] = int(self.field("mincjamount").toString())
relfeeval = float(self.field("maxrelfee").toString())
absfeeval = int(self.field("maxabsfee").toString())
self.opts['maxcjfee'] = (relfeeval, absfeeval)
#needed for Taker to check:
jm_single().mincjamount = self.opts['mincjamount']
return get_tumble_schedule(self.opts, self.destaddrs)

17
scripts/tumbler.py

@ -19,7 +19,7 @@ from jmclient import (Taker, load_program_config, get_schedule,
RegtestBitcoinCoreInterface, estimate_tx_fee,
tweak_tumble_schedule, human_readable_schedule_entry,
schedule_to_text, restart_waiter, get_tumble_log,
tumbler_taker_finished_update)
tumbler_taker_finished_update, tumbler_filter_orders_callback)
from jmbase.support import get_log, debug_dump_object, get_password
from cli_options import get_tumbler_parser
@ -101,20 +101,9 @@ def main():
print("Progress logging to logs/TUMBLE.log")
def filter_orders_callback(orders_fees, cjamount):
"""Since the tumbler does not use interactive fee checking,
we use the -x values from the command line instead.
"""Decide whether to accept fees
"""
orders, total_cj_fee = orders_fees
abs_cj_fee = 1.0 * total_cj_fee / taker.n_counterparties
rel_cj_fee = abs_cj_fee / cjamount
log.info('rel/abs average fee = ' + str(rel_cj_fee) + ' / ' + str(
abs_cj_fee))
if rel_cj_fee > options['maxcjfee'][
0] and abs_cj_fee > options['maxcjfee'][1]:
log.info("Rejected fees as too high according to options, will retry.")
return "retry"
return True
return tumbler_filter_orders_callback(orders_fees, cjamount, taker, options)
def taker_finished(res, fromtx=False, waittime=0.0, txdetails=None):
"""on_finished_callback for tumbler; processing is almost entirely

Loading…
Cancel
Save