From a1bcf8d4b957ff60f16730b6e15538ccff62a21e Mon Sep 17 00:00:00 2001 From: tecnovert Date: Sat, 17 Feb 2024 00:01:28 +0200 Subject: [PATCH] api: Add validateamount command --- basicswap/js_server.py | 28 ++++++++++++++++++++++++ basicswap/ui/page_offers.py | 4 +++- basicswap/util/__init__.py | 4 ++-- scripts/createoffers.py | 7 +++++- tests/basicswap/extended/test_scripts.py | 2 +- tests/basicswap/test_run.py | 9 ++++++++ 6 files changed, 49 insertions(+), 5 deletions(-) diff --git a/basicswap/js_server.py b/basicswap/js_server.py index d137fe3..aeb8b43 100644 --- a/basicswap/js_server.py +++ b/basicswap/js_server.py @@ -632,6 +632,33 @@ def js_automationstrategies(self, url_split, post_string: str, is_json: bool) -> return bytes(json.dumps(rv), 'UTF-8') +def js_validateamount(self, url_split, post_string: str, is_json: bool) -> bytes: + swap_client = self.server.swap_client + swap_client.checkSystemStatus() + + post_data = getFormData(post_string, is_json) + + ticker_str = post_data['coin'] + amount = post_data['amount'] + round_method = post_data.get('method', 'none') + + valid_round_methods = ('roundoff', 'rounddown', 'none') + if round_method not in valid_round_methods: + raise ValueError(f'Unknown rounding method, must be one of {valid_round_methods}') + + coin_type = tickerToCoinId(ticker_str) + ci = swap_client.ci(coin_type) + + r = 0 + if round_method == 'roundoff': + r = 1 + elif round_method == 'rounddown': + r = -1 + + output_amount = ci.format_amount(amount, conv_int=True, r=r) + return bytes(json.dumps(output_amount), 'UTF-8') + + def js_vacuumdb(self, url_split, post_string, is_json) -> bytes: swap_client = self.server.swap_client swap_client.checkSystemStatus() @@ -747,6 +774,7 @@ pages = { 'notifications': js_notifications, 'identities': js_identities, 'automationstrategies': js_automationstrategies, + 'validateamount': js_validateamount, 'vacuumdb': js_vacuumdb, 'getcoinseed': js_getcoinseed, 'setpassword': js_setpassword, diff --git a/basicswap/ui/page_offers.py b/basicswap/ui/page_offers.py index eef935c..a1e37c8 100644 --- a/basicswap/ui/page_offers.py +++ b/basicswap/ui/page_offers.py @@ -250,7 +250,9 @@ def parseOfferFormData(swap_client, form_data, page_data, options={}): page_data['to_fee_override'] = ci_to.format_amount(ci_to.make_int(to_fee_override, r=1)) parsed_data['to_fee_override'] = page_data['to_fee_override'] except Exception as e: - print('Error setting fee', str(e)) # Expected if missing fields + # Error is expected if missing fields + if swap_client.debug is True: + swap_client.log.warning(f'parseOfferFormData failed to set fee: Error {e}') return parsed_data, errors diff --git a/basicswap/util/__init__.py b/basicswap/util/__init__.py index f2fca91..542c8bd 100644 --- a/basicswap/util/__init__.py +++ b/basicswap/util/__init__.py @@ -106,7 +106,7 @@ def float_to_str(f: float) -> str: return format(d1, 'f') -def make_int(v, scale: int = 8, r: int = 0) -> int: # r = 0, no rounding, fail, r > 0 round up, r < 0 floor +def make_int(v, scale: int = 8, r: int = 0) -> int: # r = 0, no rounding (fail), r > 0 round off, r < 0 floor if isinstance(v, float): v = float_to_str(v) elif isinstance(v, int): @@ -132,7 +132,7 @@ def make_int(v, scale: int = 8, r: int = 0) -> int: # r = 0, no rounding, fail, if r == 0: raise ValueError('Mantissa too long') if r > 0: - # Round up + # Round off if int(c) > 4: rv += 1 break diff --git a/scripts/createoffers.py b/scripts/createoffers.py index 7fd12aa..a6d6da0 100755 --- a/scripts/createoffers.py +++ b/scripts/createoffers.py @@ -463,6 +463,7 @@ def main(): print(f'Not bidding on offer {offer_id}, too many failed bids ({failed_sent_bids}).') continue + validateamount: bool = False max_coin_from_balance = bid_template.get('max_coin_from_balance', -1) if max_coin_from_balance > 0: wallet_from = read_json_api_wallet('wallets/{}'.format(coin_from_data['ticker'])) @@ -472,6 +473,7 @@ def main(): if total_balance_from + bid_amount > max_coin_from_balance: if can_adjust_amount and max_coin_from_balance - total_balance_from > min_swap_amount: bid_amount = max_coin_from_balance - total_balance_from + validateamount = True print(f'Reduced bid amount to {bid_amount}') else: if args.debug: @@ -493,8 +495,9 @@ def main(): adjusted_bid_amount = adjusted_swap_amount_to / offer_rate if adjusted_bid_amount > min_swap_amount: - print(f'Reduced bid amount to {bid_amount}') bid_amount = adjusted_bid_amount + validateamount = True + print(f'Reduced bid amount to {bid_amount}') swap_amount_to = adjusted_bid_amount * offer_rate if total_balance_to - swap_amount_to < min_coin_to_balance: @@ -502,6 +505,8 @@ def main(): print(f'Bid amount would exceed minimum coin to wallet total for offer {offer_id}') continue + if validateamount: + bid_amount = read_json_api('validateamount', {'coin': coin_from_data['ticker'], 'amount': bid_amount, 'method': 'rounddown'}) bid_data = { 'offer_id': offer['offer_id'], 'amount_from': bid_amount} diff --git a/tests/basicswap/extended/test_scripts.py b/tests/basicswap/extended/test_scripts.py index 4b4ec9d..2837f09 100644 --- a/tests/basicswap/extended/test_scripts.py +++ b/tests/basicswap/extended/test_scripts.py @@ -507,7 +507,7 @@ class Test(unittest.TestCase): possible_bids = get_possible_bids(rv_stdout) possible_bids = get_possible_bids(rv_stdout) assert (len(possible_bids) == 1) - assert (float(possible_bids[0]['amount_from'] < 20.0)) + assert (float(possible_bids[0]['amount_from']) < 20.0) logging.info('Adding mock data to node1 db for tests') rows = [] diff --git a/tests/basicswap/test_run.py b/tests/basicswap/test_run.py index 57c0a99..0c88c48 100644 --- a/tests/basicswap/test_run.py +++ b/tests/basicswap/test_run.py @@ -185,6 +185,15 @@ class Test(BaseTest): rv = read_json_api(1800, 'wallets/part') assert ('locked_utxos' in rv) + rv = read_json_api(1800, 'validateamount', {'coin': 'part', 'amount': 0.000000015}) + assert ('Mantissa too long' in rv['error']) + + rv = read_json_api(1800, 'validateamount', {'coin': 'part', 'amount': 0.000000015, 'method': 'roundoff'}) + assert (rv == '0.00000002') + + rv = read_json_api(1800, 'validateamount', {'coin': 'part', 'amount': 0.000000015, 'method': 'rounddown'}) + assert (rv == '0.00000001') + def test_004_validateSwapType(self): logging.info('---------- Test validateSwapType')