Browse Source

Output values on "Not enough funds" exception

master
Kristaps Kaupe 5 years ago
parent
commit
43368e1f9e
No known key found for this signature in database
GPG Key ID: D47B1B4232B55437
  1. 2
      jmclient/jmclient/__init__.py
  2. 23
      jmclient/jmclient/support.py
  3. 5
      jmclient/test/test_taker.py

2
jmclient/jmclient/__init__.py

@ -7,7 +7,7 @@ from .support import (calc_cj_fee, choose_sweep_orders, choose_orders,
rand_weighted_choice, select, rand_weighted_choice, select,
select_gradual, select_greedy, select_greediest, select_gradual, select_greedy, select_greediest,
get_random_bytes, random_under_max_order_choose, get_random_bytes, random_under_max_order_choose,
select_one_utxo) select_one_utxo, NotEnoughFundsException)
from .jsonrpc import JsonRpcError, JsonRpcConnectionError, JsonRpc from .jsonrpc import JsonRpcError, JsonRpcConnectionError, JsonRpc
from .old_mnemonic import mn_decode, mn_encode from .old_mnemonic import mn_decode, mn_encode
from .taker import Taker from .taker import Taker

23
jmclient/jmclient/support.py

@ -10,6 +10,14 @@ ORDER_KEYS = ['counterparty', 'oid', 'ordertype', 'minsize', 'maxsize', 'txfee',
log = get_log() log = get_log()
class NotEnoughFundsException(RuntimeError):
def __init__(self, want, has):
super().__init__("Not enough funds, " +
str(want) + " vs. " + str(has) + ".")
""" """
Random functions - replacing some NumPy features Random functions - replacing some NumPy features
NOTE THESE ARE NEITHER CRYPTOGRAPHICALLY SECURE NOTE THESE ARE NEITHER CRYPTOGRAPHICALLY SECURE
@ -17,7 +25,6 @@ NOR PERFORMANT NOR HIGH PRECISION!
Only for sampling purposes Only for sampling purposes
""" """
def get_random_bytes(num_bytes, cryptographically_secure=False): def get_random_bytes(num_bytes, cryptographically_secure=False):
if cryptographically_secure: if cryptographically_secure:
# uses os.urandom if available # uses os.urandom if available
@ -78,9 +85,10 @@ def select(unspent, value):
tv += low[i]["value"] tv += low[i]["value"]
i += 1 i += 1
if tv < value: if tv < value:
raise Exception("Not enough funds") raise NotEnoughFundsException(value, tv)
return low[:i] return low[:i]
def select_gradual(unspent, value): def select_gradual(unspent, value):
""" """
UTXO selection algorithm for gradual dust reduction UTXO selection algorithm for gradual dust reduction
@ -94,7 +102,7 @@ def select_gradual(unspent, value):
lowsum = reduce(lambda x, y: x + y, map(key, low), 0) lowsum = reduce(lambda x, y: x + y, map(key, low), 0)
if value > lowsum: if value > lowsum:
if len(high) == 0: if len(high) == 0:
raise Exception('Not enough funds') raise NotEnoughFundsException(value, lowsum)
else: else:
return [high[0]] return [high[0]]
else: else:
@ -129,11 +137,11 @@ def select_greedy(unspent, value):
if value > 0: # no, that drops us below the target if value > 0: # no, that drops us below the target
picked += [utxo] # so we need this one too picked += [utxo] # so we need this one too
value -= key(utxo) # 'backtrack' the counter value -= key(utxo) # 'backtrack' the counter
picked_sum = sum(key(u) for u in picked)
if len(picked) > 0: if len(picked) > 0:
if len(picked) < len(utxos) or sum( if len(picked) < len(utxos) or picked_sum >= original_value:
key(u) for u in picked) >= original_value:
return picked return picked
raise Exception('Not enough funds') # if all else fails, we do too raise NotEnoughFundsException(original_value, picked_sum) # if all else fails, we do too
def select_greediest(unspent, value): def select_greediest(unspent, value):
@ -149,7 +157,7 @@ def select_greediest(unspent, value):
lowsum = reduce(lambda x, y: x + y, map(key, low), 0) lowsum = reduce(lambda x, y: x + y, map(key, low), 0)
if value > lowsum: if value > lowsum:
if len(high) == 0: if len(high) == 0:
raise Exception('Not enough funds') raise NotEnoughFundsException(value, lowsum)
else: else:
return [high[0]] return [high[0]]
else: else:
@ -159,6 +167,7 @@ def select_greediest(unspent, value):
end += 1 end += 1
return low[0:end] return low[0:end]
def select_one_utxo(unspent, value): def select_one_utxo(unspent, value):
key = lambda u: u['value'] key = lambda u: u['value']
return [random.choice([u for u in unspent if key(u) >= value])] return [random.choice([u for u in unspent if key(u) >= value])]

5
jmclient/test/test_taker.py

@ -13,7 +13,8 @@ from base64 import b64encode
from jmbase import utxostr_to_utxo, hextobin from jmbase import utxostr_to_utxo, hextobin
from jmclient import load_test_config, jm_single, set_commitment_file,\ from jmclient import load_test_config, jm_single, set_commitment_file,\
get_commitment_file, SegwitLegacyWallet, Taker, VolatileStorage,\ get_commitment_file, SegwitLegacyWallet, Taker, VolatileStorage,\
get_network, WalletService, NO_ROUNDING, BTC_P2PKH get_network, WalletService, NO_ROUNDING, BTC_P2PKH,\
NotEnoughFundsException
from taker_test_data import t_utxos_by_mixdepth, t_orderbook,\ from taker_test_data import t_utxos_by_mixdepth, t_orderbook,\
t_maker_response, t_chosen_orders, t_dummy_ext t_maker_response, t_chosen_orders, t_dummy_ext
from commontest import default_max_cj_fee from commontest import default_max_cj_fee
@ -57,7 +58,7 @@ class DummyWallet(SegwitLegacyWallet):
def select_utxos(self, mixdepth, amount, utxo_filter=None, select_fn=None, def select_utxos(self, mixdepth, amount, utxo_filter=None, select_fn=None,
maxheight=None, includeaddr=False): maxheight=None, includeaddr=False):
if amount > self.get_balance_by_mixdepth()[mixdepth]: if amount > self.get_balance_by_mixdepth()[mixdepth]:
raise Exception("Not enough funds") raise NotEnoughFundsException(amount, self.get_balance_by_mixdepth()[mixdepth])
# comment as for get_utxos_by_mixdepth: # comment as for get_utxos_by_mixdepth:
retval = {} retval = {}
for k, v in t_utxos_by_mixdepth[mixdepth].items(): for k, v in t_utxos_by_mixdepth[mixdepth].items():

Loading…
Cancel
Save