From a5426808e3afd247d4ea79096bf7c9f57072596b Mon Sep 17 00:00:00 2001 From: Kristaps Kaupe Date: Fri, 8 Oct 2021 02:27:22 +0300 Subject: [PATCH 1/2] Rename yield generator's txfee settings to txfee_contribution --- docs/YIELDGENERATOR.md | 4 +-- jmclient/jmclient/configure.py | 4 +-- jmclient/jmclient/yieldgenerator.py | 43 ++++++++++++++-------------- jmclient/test/test_yieldgenerator.py | 34 ++++++++++++---------- scripts/yg-privacyenhanced.py | 15 ++++++---- test/ygrunner.py | 15 +++++----- 6 files changed, 62 insertions(+), 53 deletions(-) diff --git a/docs/YIELDGENERATOR.md b/docs/YIELDGENERATOR.md index a071a21..5d48842 100644 --- a/docs/YIELDGENERATOR.md +++ b/docs/YIELDGENERATOR.md @@ -36,10 +36,10 @@ Open the configuration file `joinmarket.cfg` and edit the `[YIELDGENERATOR]` sec cjfee_factor = 0.1 # [satoshis, any integer] / the average transaction fee you're adding to coinjoin transactions - txfee = 100 + txfee_contribution = 100 # [fraction, 0-1] / variance around the average fee. Ex: 1000 fee, 0.2 var = fee is btw 800-1200 - txfee_factor = 0.3 + txfee_contribution_factor = 0.3 # [satoshis, any integer] / minimum size of your cj offer. Lower cj amounts will be disregarded minsize = 100000 diff --git a/jmclient/jmclient/configure.py b/jmclient/jmclient/configure.py index 76ee92e..b69d00a 100644 --- a/jmclient/jmclient/configure.py +++ b/jmclient/jmclient/configure.py @@ -403,10 +403,10 @@ cjfee_r = 0.00002 cjfee_factor = 0.1 # [satoshis, any integer] / the average transaction fee you're adding to coinjoin transactions -txfee = 100 +txfee_contribuion = 100 # [fraction, 0-1] / variance around the average fee. Ex: 1000 fee, 0.2 var = fee is btw 800-1200 -txfee_factor = 0.3 +txfee_contribution_factor = 0.3 # [satoshis, any integer] / minimum size of your cj offer. Lower cj amounts will be disregarded minsize = 100000 diff --git a/jmclient/jmclient/yieldgenerator.py b/jmclient/jmclient/yieldgenerator.py index 0483a0c..b813133 100644 --- a/jmclient/jmclient/yieldgenerator.py +++ b/jmclient/jmclient/yieldgenerator.py @@ -83,10 +83,10 @@ class YieldGeneratorBasic(YieldGenerator): thus is somewhat suboptimal in giving more information to spies. """ def __init__(self, wallet_service, offerconfig): - #note the randomizing entries are ignored in this base class: - - self.txfee, self.cjfee_a, self.cjfee_r, self.ordertype, self.minsize, \ - self.txfee_factor, self.cjfee_factor, self.size_factor = offerconfig + # note the randomizing entries are ignored in this base class: + self.txfee_contribution, self.cjfee_a, self.cjfee_r, self.ordertype,\ + self.minsize, self.txfee_contribution_factor, self.cjfee_factor,\ + self.size_factor = offerconfig super().__init__(wallet_service) @@ -103,16 +103,16 @@ class YieldGeneratorBasic(YieldGenerator): f = self.cjfee_r #minimum size bumped if necessary such that you always profit #least 50% of the miner fee - self.minsize = max(int(1.5 * self.txfee / float(self.cjfee_r)), - self.minsize) + self.minsize = max(int(1.5 * self.txfee_contribution / + float(self.cjfee_r)), self.minsize) elif self.ordertype in ('absoffer', 'swabsoffer', 'sw0absoffer'): - f = str(self.txfee + self.cjfee_a) + f = str(self.txfee_contribution + self.cjfee_a) order = {'oid': 0, 'ordertype': self.ordertype, 'minsize': self.minsize, 'maxsize': mix_balance[max_mix] - max( - jm_single().DUST_THRESHOLD, self.txfee), - 'txfee': self.txfee, + jm_single().DUST_THRESHOLD, self.txfee_contribution), + 'txfee': self.txfee_contribution, 'cjfee': f} # sanity check @@ -362,11 +362,11 @@ def ygmain(ygclass, nickserv_password='', gaplimit=6): parser.add_option('-o', '--ordertype', action='store', type='string', dest='ordertype', default=None, help='type of order; can be either reloffer or absoffer') - parser.add_option('-t', '--txfee', action='store', type='int', - dest='txfee', default=None, + parser.add_option('-t', '--txfee-contribution', action='store', type='int', + dest='txfee_contribution', default=None, help='the average transaction fee contribution you\'re adding to coinjoin transactions') - parser.add_option('-f', '--txfee-factor', action='store', type='float', - dest='txfee_factor', default=None, + parser.add_option('-f', '--txfee-contribution-factor', action='store', type='float', + dest='txfee_contribution_factor', default=None, help='variance around the average transaction fee contribution, decimal fraction') parser.add_option('-a', '--cjfee-a', action='store', type='string', dest='cjfee_a', default=None, @@ -402,21 +402,22 @@ def ygmain(ygclass, nickserv_password='', gaplimit=6): load_program_config(config_path=options["datadir"]) # As per previous note, override non-default command line settings: - for x in ["ordertype", "txfee", "txfee_factor", "cjfee_a", "cjfee_r", - "cjfee_factor", "minsize", "size_factor"]: + for x in ["ordertype", "txfee_contribution", "txfee_contribution_factor", + "cjfee_a", "cjfee_r", "cjfee_factor", "minsize", "size_factor"]: if options[x] is None: options[x] = jm_single().config.get("YIELDGENERATOR", x) wallet_name = args[0] ordertype = options["ordertype"] - txfee = int(options["txfee"]) - txfee_factor = float(options["txfee_factor"]) + txfee_contribution = int(options["txfee_contribution"]) + txfee_contribution_factor = float(options["txfee_contribution_factor"]) cjfee_factor = float(options["cjfee_factor"]) size_factor = float(options["size_factor"]) if ordertype == 'reloffer': cjfee_r = options["cjfee_r"] # minimum size is such that you always net profit at least 20% #of the miner fee - minsize = max(int(1.2 * txfee / float(cjfee_r)), int(options["minsize"])) + minsize = max(int(1.2 * txfee_contribution / float(cjfee_r)), + int(options["minsize"])) cjfee_a = None elif ordertype == 'absoffer': cjfee_a = int(options["cjfee_a"]) @@ -458,9 +459,9 @@ def ygmain(ygclass, nickserv_password='', gaplimit=6): ordertype = prefix + ordertype jlog.debug("Set the offer type string to: " + ordertype) - maker = ygclass(wallet_service, [txfee, cjfee_a, cjfee_r, - ordertype, minsize, txfee_factor, - cjfee_factor, size_factor]) + maker = ygclass(wallet_service, + [txfee_contribution, cjfee_a, cjfee_r, ordertype, minsize, + txfee_contribution_factor, cjfee_factor, size_factor]) jlog.info('starting yield generator') clientfactory = JMClientProtocolFactory(maker, proto_type="MAKER") if jm_single().config.get("SNICKER", "enabled") == "true": diff --git a/jmclient/test/test_yieldgenerator.py b/jmclient/test/test_yieldgenerator.py index 94e9f9f..27611a1 100644 --- a/jmclient/test/test_yieldgenerator.py +++ b/jmclient/test/test_yieldgenerator.py @@ -42,14 +42,15 @@ class CustomUtxoWallet(SegwitLegacyWallet): assert self.get_addr_mixdepth(u['address']) == expected -def create_yg_basic(balances, txfee=0, cjfee_a=0, cjfee_r=0, +def create_yg_basic(balances, txfee_contribution=0, cjfee_a=0, cjfee_r=0, ordertype='swabsoffer', minsize=0): """Constructs a YieldGeneratorBasic instance with a fake wallet. The wallet will have the given balances at mixdepths, and the offer params will be set as given here.""" wallet = CustomUtxoWallet(balances) - offerconfig = (txfee, cjfee_a, cjfee_r, ordertype, minsize, None, None, None) + offerconfig = (txfee_contribution, cjfee_a, cjfee_r, ordertype, minsize, + None, None, None) yg = YieldGeneratorBasic(WalletService(wallet), offerconfig) @@ -71,8 +72,8 @@ class CreateMyOrdersTests(unittest.TestCase): def test_abs_fee(self): jm_single().DUST_THRESHOLD = 10 - yg = create_yg_basic([0, 2000000, 1000000], txfee=1000, cjfee_a=10, - ordertype='swabsoffer', minsize=100000) + yg = create_yg_basic([0, 2000000, 1000000], txfee_contribution=1000, + cjfee_a=10, ordertype='swabsoffer', minsize=100000) self.assertEqual(yg.create_my_orders(), [ {'oid': 0, 'ordertype': 'swabsoffer', @@ -84,8 +85,8 @@ class CreateMyOrdersTests(unittest.TestCase): def test_rel_fee(self): jm_single().DUST_THRESHOLD = 10 - yg = create_yg_basic([0, 2000000, 1000000], txfee=1000, cjfee_r=0.1, - ordertype='sw0reloffer', minsize=10) + yg = create_yg_basic([0, 2000000, 1000000], txfee_contribution=1000, + cjfee_r=0.1, ordertype='sw0reloffer', minsize=10) self.assertEqual(yg.create_my_orders(), [ {'oid': 0, 'ordertype': 'sw0reloffer', @@ -97,8 +98,8 @@ class CreateMyOrdersTests(unittest.TestCase): def test_dust_threshold(self): jm_single().DUST_THRESHOLD = 1000 - yg = create_yg_basic([0, 2000000, 1000000], txfee=10, cjfee_a=10, - ordertype='swabsoffer', minsize=100000) + yg = create_yg_basic([0, 2000000, 1000000], txfee_contribution=10, + cjfee_a=10, ordertype='swabsoffer', minsize=100000) self.assertEqual(yg.create_my_orders(), [ {'oid': 0, 'ordertype': 'swabsoffer', @@ -110,8 +111,8 @@ class CreateMyOrdersTests(unittest.TestCase): def test_minsize_above_maxsize(self): jm_single().DUST_THRESHOLD = 10 - yg = create_yg_basic([0, 20000, 10000], txfee=1000, cjfee_a=10, - ordertype='swabsoffer', minsize=100000) + yg = create_yg_basic([0, 20000, 10000], txfee_contribution=1000, + cjfee_a=10, ordertype='swabsoffer', minsize=100000) self.assertEqual(yg.create_my_orders(), []) @@ -121,13 +122,13 @@ class OidToOrderTests(unittest.TestCase): def call_oid_to_order(self, yg, amount): """Calls oid_to_order on the given yg instance. It passes the txfee and abs fee from yg as offer.""" - offer = {'txfee': yg.txfee, + offer = {'txfee': yg.txfee_contribution, 'cjfee': str(yg.cjfee_a), 'ordertype': 'swabsoffer'} return yg.oid_to_order(offer, amount) def test_not_enough_balance(self): - yg = create_yg_basic([100], txfee=0, cjfee_a=10) + yg = create_yg_basic([100], txfee_contribution=0, cjfee_a=10) self.assertEqual(self.call_oid_to_order(yg, 1000), (None, None, None)) def test_chooses_single_utxo(self): @@ -144,7 +145,8 @@ class OidToOrderTests(unittest.TestCase): # right at the dust threshold. The wallet won't be able to find # any extra inputs, though. jm_single().DUST_THRESHOLD = 410 - yg = create_yg_basic([10, 1000, 10], txfee=100, cjfee_a=10) + yg = create_yg_basic([10, 1000, 10], txfee_contribution=100, + cjfee_a=10) self.assertEqual(self.call_oid_to_order(yg, 500), (None, None, None)) def test_extra_with_dust_threshold(self): @@ -152,7 +154,8 @@ class OidToOrderTests(unittest.TestCase): # need to include the extra_utxo from the wallet as well to get # over the threshold. jm_single().DUST_THRESHOLD = 410 - yg = create_yg_basic([10, 1000, 10], txfee=100, cjfee_a=10) + yg = create_yg_basic([10, 1000, 10], txfee_contribution=100, + cjfee_a=10) yg.wallet_service.wallet.add_utxo_at_mixdepth(1, 500) utxos, cj_addr, change_addr = self.call_oid_to_order(yg, 500) self.assertEqual(len(utxos), 2) @@ -172,7 +175,8 @@ class OfferReannouncementTests(unittest.TestCase): """Constructs a fake yg instance that has an offer with the given maxsize. Returns it together with the offer.""" jm_single().DUST_THRESHOLD = 10 - yg = create_yg_basic([100 + maxsize], txfee=100, ordertype='swabsoffer') + yg = create_yg_basic([100 + maxsize], txfee_contribution=100, + ordertype='swabsoffer') offers = yg.create_my_orders() self.assertEqual(len(offers), 1) self.assertEqual(offers[0]['maxsize'], maxsize) diff --git a/scripts/yg-privacyenhanced.py b/scripts/yg-privacyenhanced.py index be6f142..d87bf55 100755 --- a/scripts/yg-privacyenhanced.py +++ b/scripts/yg-privacyenhanced.py @@ -53,21 +53,24 @@ class YieldGeneratorPrivacyEnhanced(YieldGeneratorBasic): if self.ordertype in ['swreloffer', 'sw0reloffer']: f = self.cjfee_r elif self.ordertype in ['swabsoffer', 'sw0absoffer']: - f = str(self.txfee + self.cjfee_a) + f = str(self.txfee_contribution + self.cjfee_a) mix_balance = dict([(m, b) for m, b in iteritems(mix_balance) if b > self.minsize]) if len(mix_balance) == 0: jlog.error('You do not have the minimum required amount of coins' ' to be a maker: ' + str(self.minsize) + \ - '\nTry setting txfee to zero and/or lowering the minsize.') + '\nTry setting txfee_contribution to zero and/or ' + 'lowering the minsize.') return [] max_mix = max(mix_balance, key=mix_balance.get) # randomizing the different values - randomize_txfee = int(random.uniform(self.txfee * (1 - float(self.txfee_factor)), - self.txfee * (1 + float(self.txfee_factor)))) - randomize_minsize = int(random.uniform(self.minsize * (1 - float(self.size_factor)), - self.minsize * (1 + float(self.size_factor)))) + randomize_txfee = int(random.uniform( + self.txfee_contribution * (1 - float(self.txfee_contribution_factor)), + self.txfee_contribution * (1 + float(self.txfee_contribution_factor)))) + randomize_minsize = int(random.uniform( + self.minsize * (1 - float(self.size_factor)), + self.minsize * (1 + float(self.size_factor)))) if randomize_minsize < jm_single().DUST_THRESHOLD: jlog.warn("Minsize was randomized to below dust; resetting to dust " "threshold: " + amount_to_str(jm_single().DUST_THRESHOLD)) diff --git a/test/ygrunner.py b/test/ygrunner.py index 75411dc..861ac15 100644 --- a/test/ygrunner.py +++ b/test/ygrunner.py @@ -134,19 +134,20 @@ def test_start_ygs(setup_ygrunner, num_ygs, wallet_structures, fb_indices, # As per previous note, override non-default command line settings: options = {} - for x in ["ordertype", "txfee", "txfee_factor", "cjfee_a", "cjfee_r", - "cjfee_factor", "minsize", "size_factor"]: + for x in ["ordertype", "txfee_contribution", "txfee_contribution_factor", + "cjfee_a", "cjfee_r", "cjfee_factor", "minsize", "size_factor"]: options[x] = jm_single().config.get("YIELDGENERATOR", x) ordertype = options["ordertype"] - txfee = int(options["txfee"]) - txfee_factor = float(options["txfee_factor"]) + txfee_contribution = int(options["txfee_contribution"]) + txfee_contribution_factor = float(options["txfee_contribution_factor"]) cjfee_factor = float(options["cjfee_factor"]) size_factor = float(options["size_factor"]) if ordertype == 'reloffer': cjfee_r = options["cjfee_r"] # minimum size is such that you always net profit at least 20% #of the miner fee - minsize = max(int(1.2 * txfee / float(cjfee_r)), int(options["minsize"])) + minsize = max(int(1.2 * txfee_contribution / float(cjfee_r)), + int(options["minsize"])) cjfee_a = None elif ordertype == 'absoffer': cjfee_a = int(options["cjfee_a"]) @@ -173,8 +174,8 @@ def test_start_ygs(setup_ygrunner, num_ygs, wallet_structures, fb_indices, else: ygclass = MaliciousYieldGenerator for i in range(num_ygs): - cfg = [txfee, cjfee_a, cjfee_r, ordertype, minsize, txfee_factor, - cjfee_factor, size_factor] + cfg = [txfee_contribution, cjfee_a, cjfee_r, ordertype, minsize, + txfee_contribution_factor, cjfee_factor, size_factor] wallet_service_yg = wallet_services[i]["wallet"] wallet_service_yg.startService() From c2729c0c0cf99597f7527911c1611644b61f4ab8 Mon Sep 17 00:00:00 2001 From: Kristaps Kaupe Date: Sat, 16 Oct 2021 15:01:10 +0300 Subject: [PATCH 2/2] fix typo --- jmclient/jmclient/configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jmclient/jmclient/configure.py b/jmclient/jmclient/configure.py index b69d00a..d94e499 100644 --- a/jmclient/jmclient/configure.py +++ b/jmclient/jmclient/configure.py @@ -403,7 +403,7 @@ cjfee_r = 0.00002 cjfee_factor = 0.1 # [satoshis, any integer] / the average transaction fee you're adding to coinjoin transactions -txfee_contribuion = 100 +txfee_contribution = 100 # [fraction, 0-1] / variance around the average fee. Ex: 1000 fee, 0.2 var = fee is btw 800-1200 txfee_contribution_factor = 0.3