Browse Source

Merge #1035: Rename yield generator's txfee settings to txfee_contribution

c2729c0 fix typo (Kristaps Kaupe)
a542680 Rename yield generator's txfee settings to txfee_contribution (Kristaps Kaupe)
master
Adam Gibson 4 years ago
parent
commit
ebd04648a9
No known key found for this signature in database
GPG Key ID: 141001A1AF77F20B
  1. 4
      docs/YIELDGENERATOR.md
  2. 4
      jmclient/jmclient/configure.py
  3. 43
      jmclient/jmclient/yieldgenerator.py
  4. 34
      jmclient/test/test_yieldgenerator.py
  5. 15
      scripts/yg-privacyenhanced.py
  6. 15
      test/ygrunner.py

4
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

4
jmclient/jmclient/configure.py

@ -410,10 +410,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_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

43
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":

34
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)

15
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))

15
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()

Loading…
Cancel
Save