diff --git a/docs/release-notes/release-notes-tumbler-improve.md b/docs/release-notes/release-notes-tumbler-improve.md new file mode 100644 index 0000000..135746b --- /dev/null +++ b/docs/release-notes/release-notes-tumbler-improve.md @@ -0,0 +1,20 @@ +copypaste this into "release-notes" when the time comes to make a new release, then delete this file + +Notable changes +=============== + +### Tumbler privacy improvements + +The tumbler algorithm has been improved with the aim to increase privacy. This affects the `tumbler.py` script and `joinmarket-qt.py` GUI. + +* At the start of the run, tumbler will now fully spend all mixdepths with coinjoin with no change address (also known as a sweep transaction) back to its own internal wallet. After these initial sweeps are done tumbler will continue with the already-existing algorithm of sending coinjoins with randomly-generated amounts. + +* Tumbler will now occasionally send a round number of bitcoins, for example `0.20000000` or `0.15000000` instead of `0.24159873`. The default probability of this happening is 25% per coinjoin. + +* The default wait time between coinjoins is increased from 30 minutes to 60 minutes. + +* The default number of coinjoin counterparties is increased from 6 to 9. + +* The default number of coinjoins per mixdepth is decreased from 4 to 2. + +For a full discription and reasoning behind the changes see: [Plan to improve the privacy of JoinMarket's tumbler script](https://gist.github.com/chris-belcher/7e92810f07328fdfdef2ce444aad0968) diff --git a/jmclient/jmclient/configure.py b/jmclient/jmclient/configure.py index 101fdb4..479bc3f 100644 --- a/jmclient/jmclient/configure.py +++ b/jmclient/jmclient/configure.py @@ -250,7 +250,7 @@ tx_broadcast = self # amount of makers which we are content with for the coinjoin to # succceed. Less makers means that the whole process will restart # after a timeout. -minimum_makers = 2 +minimum_makers = 4 ############################## #THE FOLLOWING SETTINGS ARE REQUIRED TO DEFEND AGAINST SNOOPERS. diff --git a/scripts/cli_options.py b/scripts/cli_options.py index 7fcdc63..7b0d475 100644 --- a/scripts/cli_options.py +++ b/scripts/cli_options.py @@ -269,9 +269,9 @@ def get_tumbler_parser(): action='store', dest='makercountrange', help= - 'Input the mean and spread of number of makers to use. e.g. 6 1 will be a normal distribution ' - 'with mean 6 and standard deviation 1 inclusive, default=6 1 (floats are also OK)', - default=(6, 1)) + 'Input the mean and spread of number of makers to use. e.g. 9 1 will be a normal distribution ' + 'with mean 9 and standard deviation 1 inclusive, default=9 1 (floats are also OK)', + default=(9, 1)) parser.add_option( '--minmakercount', type='int', @@ -292,17 +292,17 @@ def get_tumbler_parser(): type='float', nargs=2, dest='txcountparams', - default=(4, 1), + default=(2, 1), help= 'The number of transactions to take coins from one mixing depth to the next, it is' ' randomly chosen following a normal distribution. Should be similar to --addrask. ' - 'This option controls the parameters of the normal distribution curve. (mean, standard deviation). default=4 1') + 'This option controls the parameters of the normal distribution curve. (mean, standard deviation). default=2 1') parser.add_option( '--mintxcount', type='int', dest='mintxcount', - default=1, - help='The minimum transaction count per mixing level, default=1') + default=2, + help='The minimum transaction count per mixing level, default=2') parser.add_option( '--donateamount', type='float', @@ -315,11 +315,11 @@ def get_tumbler_parser(): '--timelambda', type='float', dest='timelambda', - default=30, + default=60, help= 'Average the number of minutes to wait between transactions. Randomly chosen ' ' following an exponential distribution, which describes the time between uncorrelated' - ' events. default=30') + ' events. default=60') parser.add_option( '--stage1-timelambda-increase', type='float', @@ -424,7 +424,7 @@ def get_sendpayment_parser(): type='int', dest='makercount', help='how many makers to coinjoin with, default random from 4 to 6', - default=random.randint(4, 6)) + default=random.randint(8, 10)) parser.add_option('-S', '--schedule-file', type='string', diff --git a/scripts/joinmarket-qt.py b/scripts/joinmarket-qt.py index 87a7038..42da0e8 100644 --- a/scripts/joinmarket-qt.py +++ b/scripts/joinmarket-qt.py @@ -136,7 +136,7 @@ def getSettingsWidgets(): sMM = ['', (2, 20), (0, jm_single().config.getint("GUI", "max_mix_depth") - 1), (0.00000001, 100.0, 8)] - sD = ['', '3', '0', ''] + sD = ['', '9', '0', ''] for x in zip(sN, sH, sT, sD, sMM): ql = QLabel(x[0]) ql.setToolTip(x[1]) diff --git a/scripts/qtsupport.py b/scripts/qtsupport.py index 6e6d2b0..9a03088 100644 --- a/scripts/qtsupport.py +++ b/scripts/qtsupport.py @@ -554,7 +554,7 @@ class SchDynamicPage1(QWizardPage): sMM = [(0, jm_single().config.getint("GUI", "max_mix_depth") - 1), (3, 20), (2, 7), (0.00000001, 100.0, 8), (2, 10), (0.000001, 0.25, 6), (0, 10000000)] - sD = ['0', '6', '4', '30.0', '4', '0.005', '10000'] + sD = ['0', '9', '4', '60.0', '2', '0.005', '10000'] for x in zip(sN, sH, sT, sD, sMM): ql = QLabel(x[0]) ql.setToolTip(x[1]) @@ -655,7 +655,7 @@ class SchFinishPage(QWizardPage): sMM = [(0.0, 10.0, 2), (0.0, 10.0, 2), (2,20), (1, 10), (100000, 100000000), (10.0, 500.0, 2), (0, 100, 1), (0.0, 1.0, 3)] + [(0, 10000)]*5 - sD = ['1.0', '1.0', '2', '1', '1000000', '20', '3', '0.25'] +\ + sD = ['1.0', '1.0', '2', '2', '1000000', '20', '3', '0.25'] +\ ['55', '15', '25', '65', '40'] for x in zip(sN, sH, sT, sD, sMM): ql = QLabel(x[0])