diff --git a/jmclient/jmclient/yieldgenerator.py b/jmclient/jmclient/yieldgenerator.py index 7395af8..6214d45 100644 --- a/jmclient/jmclient/yieldgenerator.py +++ b/jmclient/jmclient/yieldgenerator.py @@ -17,7 +17,6 @@ from .wallet_utils import open_test_wallet_maybe, get_wallet_path jlog = get_log() -MAX_MIX_DEPTH = 5 class YieldGenerator(Maker): """A maker for the purposes of generating a yield from held @@ -77,12 +76,11 @@ class YieldGeneratorBasic(YieldGenerator): super(YieldGeneratorBasic,self).__init__(wallet) def create_my_orders(self): - mix_balance = self.wallet.get_balance_by_mixdepth(verbose=False) + mix_balance = self.get_available_mixdepths() if len([b for m, b in iteritems(mix_balance) if b > 0]) == 0: jlog.error('do not have any coins left') return [] - # print mix_balance max_mix = max(mix_balance, key=mix_balance.get) f = '0' if self.ordertype in ('reloffer', 'swreloffer'): @@ -113,23 +111,24 @@ class YieldGeneratorBasic(YieldGenerator): def oid_to_order(self, offer, amount): total_amount = amount + offer["txfee"] - mix_balance = self.wallet.get_balance_by_mixdepth() - max_mix = max(mix_balance, key=mix_balance.get) + mix_balance = self.get_available_mixdepths() - filtered_mix_balance = [m - for m in iteritems(mix_balance) - if m[1] >= total_amount] + filtered_mix_balance = {m: b + for m, b in iteritems(mix_balance) + if b >= total_amount} if not filtered_mix_balance: return None, None, None jlog.debug('mix depths that have enough = ' + str(filtered_mix_balance)) - filtered_mix_balance = sorted(filtered_mix_balance, key=lambda x: x[0]) - mixdepth = filtered_mix_balance[0][0] + mixdepth = self.select_input_mixdepth(filtered_mix_balance, offer, amount) + if mixdepth is None: + return None, None, None jlog.info('filling offer, mixdepth=' + str(mixdepth) + ', amount=' + str(amount)) - # mixdepth is the chosen depth we'll be spending from - cj_addr = self.wallet.get_internal_addr( - (mixdepth + 1) % (self.wallet.mixdepth + 1), - jm_single().bc_interface) + cj_addr = self.select_output_address(mixdepth, offer, amount) + if cj_addr is None: + return None, None, None + jlog.info('sending output to address=' + str(cj_addr)) + change_addr = self.wallet.get_internal_addr(mixdepth, jm_single().bc_interface) @@ -165,6 +164,28 @@ class YieldGeneratorBasic(YieldGenerator): confirm_time / 60.0, 2), '']) return self.on_tx_unconfirmed(offer, txid, None) + def get_available_mixdepths(self): + """Returns the mixdepth/balance dict from the wallet that contains + all available inputs for offers.""" + return self.wallet.get_balance_by_mixdepth(verbose=False) + + def select_input_mixdepth(self, available, offer, amount): + """Returns the mixdepth from which the given order should spend the + inputs. available is a mixdepth/balance dict of all the mixdepths + that can be chosen from, i.e. have enough balance. If there is no + suitable input, the function can return None to abort the order.""" + available = sorted(iteritems(available), key=lambda entry: entry[0]) + return available[0][0] + + def select_output_address(self, input_mixdepth, offer, amount): + """Returns the address to which the mixed output should be sent for + an order spending from the given input mixdepth. Can return None if + there is no suitable output, in which case the order is + aborted.""" + cjoutmix = (input_mixdepth + 1) % (self.wallet.mixdepth + 1) + return self.wallet.get_internal_addr(cjoutmix, jm_single().bc_interface) + + def ygmain(ygclass, txfee=1000, cjfee_a=200, cjfee_r=0.002, ordertype='swreloffer', nickserv_password='', minsize=100000, gaplimit=6): import sys diff --git a/scripts/yg-privacyenhanced.py b/scripts/yg-privacyenhanced.py index aa783a5..29ad96c 100644 --- a/scripts/yg-privacyenhanced.py +++ b/scripts/yg-privacyenhanced.py @@ -35,12 +35,10 @@ jlog = get_log() class YieldGeneratorPrivacyEnhanced(YieldGeneratorBasic): def __init__(self, wallet, offerconfig): - self.txfee, self.cjfee_a, self.cjfee_r, self.ordertype, self.minsize \ - = offerconfig super(YieldGeneratorPrivacyEnhanced, self).__init__(wallet, offerconfig) def create_my_orders(self): - mix_balance = self.wallet.get_balance_by_mixdepth() + mix_balance = self.get_available_mixdepths(verbose=False) # We publish ONLY the maximum amount and use minsize for lower bound; # leave it to oid_to_order to figure out the right depth to use. f = '0' diff --git a/scripts/yield-generator-basic.py b/scripts/yield-generator-basic.py index 9dee2d2..0b76306 100644 --- a/scripts/yield-generator-basic.py +++ b/scripts/yield-generator-basic.py @@ -3,7 +3,7 @@ from __future__ import (absolute_import, division, print_function, unicode_literals) from builtins import * # noqa: F401 -from jmbase import get_log, jmprint +from jmbase import jmprint from jmclient import YieldGeneratorBasic, ygmain """THESE SETTINGS CAN SIMPLY BE EDITED BY HAND IN THIS FILE: @@ -16,8 +16,6 @@ nickserv_password = '' max_minsize = 100000 gaplimit = 6 -jlog = get_log() - if __name__ == "__main__": ygmain(YieldGeneratorBasic, txfee=txfee, cjfee_a=cjfee_a, cjfee_r=cjfee_r, ordertype=ordertype,