diff --git a/jmclient/jmclient/schedule.py b/jmclient/jmclient/schedule.py index a0375b7..ebb5992 100644 --- a/jmclient/jmclient/schedule.py +++ b/jmclient/jmclient/schedule.py @@ -134,7 +134,7 @@ def get_tumble_schedule(options, destaddrs): t['makercount'], t['destination'], t['wait'], 0]) return schedule -def tweak_tumble_schedule(options, schedule, last_completed): +def tweak_tumble_schedule(options, schedule, last_completed, destaddrs=[]): """If a tx in a schedule failed for some reason, and we want to make a best effort to complete the schedule, we can tweak the failed entry to improve the odds of success on re-try. @@ -145,6 +145,8 @@ def tweak_tumble_schedule(options, schedule, last_completed): """ new_schedule = copy.deepcopy(schedule) altered = new_schedule[last_completed + 1] + if not altered[3] in destaddrs: + altered[3] = "INTERNAL" #For sweeps, we'll try with a lower number of counterparties if we can. #Note that this is usually counterproductive for non-sweeps, which fall #back and so benefit in reliability from *higher* counterparty numbers. diff --git a/jmclient/jmclient/taker.py b/jmclient/jmclient/taker.py index f130d83..04091fb 100644 --- a/jmclient/jmclient/taker.py +++ b/jmclient/jmclient/taker.py @@ -29,7 +29,8 @@ class Taker(object): schedule, order_chooser=weighted_order_choose, sign_method=None, - callbacks=None): + callbacks=None, + tdestaddrs=[]): """Schedule must be a list of tuples: (see sample_schedule_for_testnet for explanation of syntax, also schedule.py module in this directory), which will be a sequence of joins to do. @@ -79,6 +80,7 @@ class Taker(object): self.waiting_for_conf = False self.txid = None self.schedule_index = -1 + self.tdestaddrs = tdestaddrs #allow custom wallet-based clients to use their own signing code; #currently only setting "wallet" is allowed, calls wallet.sign_tx(tx) self.sign_method = sign_method diff --git a/jmclient/jmclient/tumble_support.py b/jmclient/jmclient/tumble_support.py index c484a36..4c52d1b 100644 --- a/jmclient/jmclient/tumble_support.py +++ b/jmclient/jmclient/tumble_support.py @@ -118,6 +118,7 @@ def tumbler_taker_finished_update(taker, schedulefile, tumble_log, options, 'Address ' + destaddr + ' invalid. ' + errormsg + ' try again') jm_single().debug_silence[0] = False taker.schedule[taker.schedule_index+1][3] = destaddr + taker.tdestaddrs.append(destaddr) waiting_message = "Waiting for: " + str(waittime) + " minutes." tumble_log.info(waiting_message) @@ -138,7 +139,8 @@ def tumbler_taker_finished_update(taker, schedulefile, tumble_log, options, " failed after timeout, trying again") taker.schedule_index -= 1 taker.schedule = tweak_tumble_schedule(options, taker.schedule, - taker.schedule_index) + taker.schedule_index, + taker.tdestaddrs) tumble_log.info("We tweaked the schedule, the new schedule is:") tumble_log.info(pprint.pformat(taker.schedule)) else: diff --git a/scripts/joinmarket-qt.py b/scripts/joinmarket-qt.py index 536d727..4afcef0 100644 --- a/scripts/joinmarket-qt.py +++ b/scripts/joinmarket-qt.py @@ -328,6 +328,7 @@ class SpendTab(QWidget): self.spendstate.schedule_name = wizard.get_name() self.updateSchedView() self.tumbler_options = wizard.opts + self.tumbler_destaddrs = wizard.get_destaddrs() self.sch_startButton.setEnabled(True) def selectSchedule(self): @@ -556,8 +557,9 @@ class SpendTab(QWidget): log.debug('starting coinjoin ..') - w.statusBar().showMessage("Syncing wallet ...") - sync_wallet(w.wallet, fast=True) + #DON'T sync wallet since unless cache is updated, will forget index + #w.statusBar().showMessage("Syncing wallet ...") + #sync_wallet(w.wallet, fast=True) #Decide whether to interrupt processing to sanity check the fees if jm_single().config.get("GUI", "checktx") == "true": @@ -565,12 +567,14 @@ class SpendTab(QWidget): else: check_offers_callback = None + destaddrs = self.tumbler_destaddrs if self.tumbler_options else [] self.taker = Taker(w.wallet, self.spendstate.loaded_schedule, order_chooser=weighted_order_choose, callbacks=[check_offers_callback, self.callback_takerInfo, - self.callback_takerFinished]) + self.callback_takerFinished], + tdestaddrs=destaddrs) if ignored_makers: self.taker.ignored_makers.extend(ignored_makers) if not self.clientfactory: @@ -708,7 +712,7 @@ class SpendTab(QWidget): self.giveUp() def startNextTransaction(self): - sync_wallet(w.wallet, fast=True) + #sync_wallet(w.wallet, fast=True) self.clientfactory.getClient().clientStart() def takerFinished(self): @@ -810,6 +814,7 @@ class SpendTab(QWidget): self.qtw.setTabEnabled(1, True) self.spendstate.reset() self.tumbler_options = None + self.tumbler_destaddrs = None w.statusBar().showMessage("Transaction aborted.") def cleanUp(self): @@ -844,6 +849,7 @@ class SpendTab(QWidget): self.qtw.setTabEnabled(1, True) self.spendstate.reset() self.tumbler_options = None + self.tumbler_destaddrs = None def validateSettings(self): valid, errmsg = validate_address(self.widgets[0][1].text()) diff --git a/scripts/qtsupport.py b/scripts/qtsupport.py index ec5c3ed..6bae93f 100644 --- a/scripts/qtsupport.py +++ b/scripts/qtsupport.py @@ -659,8 +659,11 @@ class ScheduleWizard(QWizard): return "TUMBLE.schedule" #return self.field("schedfilename").toString() + def get_destaddrs(self): + return self.destaddrs + def get_schedule(self): - destaddrs = [str(x) for x in [self.field("destaddr0").toString(), + self.destaddrs = [str(x) for x in [self.field("destaddr0").toString(), self.field("destaddr1").toString(), self.field("destaddr2").toString()]] self.opts = {} @@ -680,4 +683,4 @@ class ScheduleWizard(QWizard): self.opts['mincjamount'] = int(self.field("mincjamount").toString()) #needed for Taker to check: jm_single().mincjamount = self.opts['mincjamount'] - return get_tumble_schedule(self.opts, destaddrs) + return get_tumble_schedule(self.opts, self.destaddrs) diff --git a/scripts/tumbler.py b/scripts/tumbler.py index 3731a0c..26bc13b 100644 --- a/scripts/tumbler.py +++ b/scripts/tumbler.py @@ -138,7 +138,8 @@ def main(): taker = Taker(wallet, schedule, order_chooser=weighted_order_choose, - callbacks=(filter_orders_callback, None, taker_finished)) + callbacks=(filter_orders_callback, None, taker_finished), + tdestaddrs=destaddrs) clientfactory = JMTakerClientProtocolFactory(taker) nodaemon = jm_single().config.getint("DAEMON", "no_daemon") daemon = True if nodaemon == 1 else False