mirror of
https://github.com/JoinMarket-Org/joinmarket-clientserver.git
synced 2026-08-20 13:37:23 +02:00
Remove mixdepthsrc from options, more tests
This commit is contained in:
parent
7ffc74762e
commit
d0bf888971
4 changed files with 49 additions and 30 deletions
|
|
@ -275,14 +275,6 @@ def get_tumbler_parser():
|
|||
' be configured to ask for more address mid-run, giving the user'
|
||||
' a chance to click `Generate New Deposit Address` on whatever service'
|
||||
' they are using.')
|
||||
parser.add_option(
|
||||
'-m',
|
||||
'--mixdepthsource',
|
||||
type='int',
|
||||
dest='mixdepthsrc',
|
||||
help=
|
||||
'Mixing depth to start tumble process from. default=0.',
|
||||
default=0)
|
||||
parser.add_option('--restart',
|
||||
action='store_true',
|
||||
dest='restart',
|
||||
|
|
@ -398,9 +390,7 @@ def get_tumbler_parser():
|
|||
type='int',
|
||||
dest='amtmixdepths',
|
||||
help='number of mixdepths ever used in wallet, '
|
||||
'only to be used if mixdepths higher than '
|
||||
'mixdepthsrc + number of mixdepths to tumble '
|
||||
'have been used.',
|
||||
'will soon be deprecated.',
|
||||
default=-1)
|
||||
parser.add_option(
|
||||
'--rounding-chance',
|
||||
|
|
|
|||
|
|
@ -17,6 +17,12 @@ from .support import rand_exp_array, rand_norm_array, rand_weighted_choice
|
|||
|
||||
NO_ROUNDING = 16 #max btc significant figures not including LN
|
||||
|
||||
class ScheduleGenerationError(Exception):
|
||||
pass
|
||||
|
||||
class ScheduleGenerationErrorNoFunds(ScheduleGenerationError):
|
||||
pass
|
||||
|
||||
def get_schedule(filename):
|
||||
with open(filename, "rb") as f:
|
||||
schedule = []
|
||||
|
|
@ -84,15 +90,11 @@ def get_amount_fractions(count):
|
|||
|
||||
def get_tumble_schedule(options, destaddrs, mixdepth_balance_dict,
|
||||
max_mixdepth_in_wallet=4):
|
||||
"""for the general intent and design of the tumbler algo, see the docs in
|
||||
joinmarket-org/joinmarket.
|
||||
Alterations:
|
||||
Donation removed for now.
|
||||
"""
|
||||
Default final setting for "amount_fraction" is zero, for each mixdepth.
|
||||
This is because we now use a general "schedule" syntax for both tumbler and
|
||||
any other taker algo; it interprets floats as fractions and integers as satoshis,
|
||||
and zero as sweep (as before).
|
||||
This is a modified version of tumbler.py/generate_tumbler_tx()
|
||||
Args:
|
||||
* options - as specified in scripts/tumbler.py and taken from cli_options.py
|
||||
* destaddrs - a list of valid address strings for the destination of funds
|
||||
|
|
@ -136,7 +138,10 @@ def get_tumble_schedule(options, destaddrs, mixdepth_balance_dict,
|
|||
'rounding': NO_ROUNDING
|
||||
}
|
||||
tx_list.append(tx)
|
||||
lowest_nonempty_mixdepth = min([x for x, y in nonempty_mixdepths.items() if y == 1])
|
||||
try:
|
||||
lowest_nonempty_mixdepth = min([x for x, y in nonempty_mixdepths.items() if y == 1])
|
||||
except ValueError:
|
||||
raise ScheduleGenerationErrorNoFunds
|
||||
### stage 2 coinjoins, which create a number of random-amount coinjoins from each mixdepth
|
||||
for m, txcount in enumerate(txcounts):
|
||||
if options['mixdepthcount'] - options['addrcount'] <= m and m < \
|
||||
|
|
@ -163,8 +168,8 @@ def get_tumble_schedule(options, destaddrs, mixdepth_balance_dict,
|
|||
rounding = rand_weighted_choice(len(weight_prob), weight_prob) + 1
|
||||
tx = {'amount_fraction': amount_fraction,
|
||||
'wait': round(wait, 2),
|
||||
'srcmixdepth': (lowest_nonempty_mixdepth + m + options[
|
||||
'mixdepthsrc']) % (max_mixdepth_in_wallet + 1),
|
||||
'srcmixdepth': (lowest_nonempty_mixdepth + m) % (
|
||||
max_mixdepth_in_wallet + 1),
|
||||
'makercount': makercount,
|
||||
'destination': 'INTERNAL',
|
||||
'rounding': rounding
|
||||
|
|
@ -176,8 +181,8 @@ def get_tumble_schedule(options, destaddrs, mixdepth_balance_dict,
|
|||
addrask = options['addrcount'] - len(destaddrs)
|
||||
external_dest_addrs = ['addrask'] * addrask + destaddrs[::-1]
|
||||
for mix_offset in range(options['addrcount']):
|
||||
srcmix = (lowest_nonempty_mixdepth + options['mixdepthsrc']
|
||||
+ options['mixdepthcount'] - mix_offset - 1) % (max_mixdepth_in_wallet + 1)
|
||||
srcmix = (lowest_nonempty_mixdepth + options['mixdepthcount']
|
||||
- mix_offset - 1) % (max_mixdepth_in_wallet + 1)
|
||||
for tx in reversed(tx_list):
|
||||
if tx['srcmixdepth'] == srcmix:
|
||||
tx['destination'] = external_dest_addrs[mix_offset]
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@ class Options(object):
|
|||
|
||||
def get_options():
|
||||
options = Options()
|
||||
options.mixdepthsrc = 0
|
||||
options.mixdepthcount = 4
|
||||
options.txcountparams = (18, 3)
|
||||
options.minmakercount = 2
|
||||
|
|
@ -90,6 +89,13 @@ def get_options():
|
|||
"mifCWfmygxKhsP3qM3HZi3ZjBEJu7m39h8",
|
||||
"mnTn9KVQQT9zy9R4E2ZGzWPK4EfcEcV9Y5"], (3,2), 8,
|
||||
{2:1, 3: 1}),
|
||||
#slightly larger version
|
||||
(["mzzAYbtPpANxpNVGCVBAhZYzrxyZtoix7i",
|
||||
"mifCWfmygxKhsP3qM3HZi3ZjBEJu7m39h8",
|
||||
"mnTn9KVQQT9zy9R4E2ZGzWPK4EfcEcV9Y5",
|
||||
"bcrt1qcnv26w889eum5sekz5h8we45rxnr4sj5k08phv",
|
||||
"bcrt1qgs0t239gj2kqgnsrvetvsv2qdva8y3j74cta4d"], (4,3), 8,
|
||||
{0:2, 1: 1, 3: 1, 4: 1}),
|
||||
])
|
||||
def test_tumble_schedule(destaddrs, txcparams, mixdepthcount, mixdepthbal):
|
||||
# note that these tests are currently only leaving the default
|
||||
|
|
@ -97,6 +103,7 @@ def test_tumble_schedule(destaddrs, txcparams, mixdepthcount, mixdepthbal):
|
|||
# and will fail if this is changed:
|
||||
wallet_total_mixdepths = 5
|
||||
options = get_options()
|
||||
options['addrcount'] = len(destaddrs)
|
||||
options['mixdepthcount'] = mixdepthcount
|
||||
options['txcountparams'] = txcparams
|
||||
schedule = get_tumble_schedule(options, destaddrs, mixdepthbal)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ from jmclient import Taker, load_program_config, get_schedule,\
|
|||
get_tumble_log, tumbler_taker_finished_update, check_regtest, \
|
||||
tumbler_filter_orders_callback, validate_address, get_tumbler_parser, \
|
||||
get_max_cj_fee_values
|
||||
from jmclient.wallet_utils import DEFAULT_MIXDEPTH
|
||||
from jmclient.schedule import ScheduleGenerationErrorNoFunds
|
||||
|
||||
from jmbase.support import get_log, jmprint, EXIT_SUCCESS, \
|
||||
EXIT_FAILURE, EXIT_ARGERROR
|
||||
|
|
@ -38,11 +40,17 @@ def main():
|
|||
|
||||
#Load the wallet
|
||||
wallet_name = args[0]
|
||||
max_mix_depth = options['mixdepthsrc'] + options['mixdepthcount']
|
||||
if options['amtmixdepths'] > max_mix_depth:
|
||||
# as of #1324 the concept of a max_mix_depth distinct from
|
||||
# the normal wallet value (4) no longer applies, since the
|
||||
# tumbler cycles; but we keep the `amtmixdepths` option for now,
|
||||
# deprecating it later.
|
||||
if options['amtmixdepths'] > DEFAULT_MIXDEPTH:
|
||||
max_mix_depth = options['amtmixdepths']
|
||||
else:
|
||||
max_mix_depth = DEFAULT_MIXDEPTH
|
||||
wallet_path = get_wallet_path(wallet_name, None)
|
||||
wallet = open_test_wallet_maybe(wallet_path, wallet_name, max_mix_depth, wallet_password_stdin=options_org.wallet_password_stdin)
|
||||
wallet = open_test_wallet_maybe(wallet_path, wallet_name, max_mix_depth,
|
||||
wallet_password_stdin=options_org.wallet_password_stdin)
|
||||
wallet_service = WalletService(wallet)
|
||||
if wallet_service.rpc_error:
|
||||
sys.exit(EXIT_FAILURE)
|
||||
|
|
@ -109,8 +117,12 @@ def main():
|
|||
tumble_log.info("TUMBLE RESTARTING")
|
||||
else:
|
||||
#Create a new schedule from scratch
|
||||
schedule = get_tumble_schedule(options, destaddrs,
|
||||
wallet.get_balance_by_mixdepth(), wallet_service.mixdepth)
|
||||
try:
|
||||
schedule = get_tumble_schedule(options, destaddrs,
|
||||
wallet.get_balance_by_mixdepth(), wallet_service.mixdepth)
|
||||
except ScheduleGenerationErrorNoFunds:
|
||||
jmprint("No funds in wallet to tumble.", "error")
|
||||
sys.exit(EXIT_FAILURE)
|
||||
tumble_log.info("TUMBLE STARTING")
|
||||
with open(os.path.join(logsdir, options['schedulefile']), "wb") as f:
|
||||
f.write(schedule_to_text(schedule))
|
||||
|
|
@ -133,10 +145,15 @@ def main():
|
|||
involved_parties = len(schedule) # own participation in each CJ
|
||||
for item in schedule:
|
||||
involved_parties += item[2] # number of total tumble counterparties
|
||||
# calculating total coins that will be included in the tumble;
|
||||
# in almost all cases all coins (unfrozen) in wallet will be tumbled,
|
||||
# though it's technically possible with a very small mixdepthcount, to start
|
||||
# at say m0, and only go through to 2 or 3, such that coins in 4 are untouched
|
||||
# in phase 2 (after having been swept in phase 1).
|
||||
used_mixdepths = set()
|
||||
[used_mixdepths.add(x[0]) for x in schedule]
|
||||
total_tumble_amount = int(0)
|
||||
max_mix_to_tumble = min(options['mixdepthsrc']+options['mixdepthcount'], \
|
||||
max_mix_depth)
|
||||
for i in range(options['mixdepthsrc'], max_mix_to_tumble):
|
||||
for i in used_mixdepths:
|
||||
total_tumble_amount += wallet_service.get_balance_by_mixdepth()[i]
|
||||
if total_tumble_amount == 0:
|
||||
raise ValueError("No confirmed coins in the selected mixdepth(s). Quitting")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue