diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py index a9fa088..f80cf47 100644 --- a/basicswap/basicswap.py +++ b/basicswap/basicswap.py @@ -42,7 +42,6 @@ from .util import ( LockedCoinError, TemporaryError, InactiveCoin, - format_amount, format_timestamp, DeserialiseNum, zeroIfNone, @@ -6584,16 +6583,18 @@ class BasicSwap(BaseApp): try: walletinfo = ci.getWalletInfo() - scale = chainparams[coin]['decimal_places'] rv = { 'deposit_address': self.getCachedAddressForCoin(coin), - 'balance': format_amount(make_int(walletinfo['balance'], scale), scale), - 'unconfirmed': format_amount(make_int(walletinfo.get('unconfirmed_balance'), scale), scale), + 'balance': ci.format_amount(walletinfo['balance'], conv_int=True), + 'unconfirmed': ci.format_amount(walletinfo['unconfirmed_balance'], conv_int=True), 'expected_seed': ci.knownWalletSeed(), 'encrypted': walletinfo['encrypted'], 'locked': walletinfo['locked'], } + if 'immature_balance' in walletinfo: + rv['immature'] = ci.format_amount(walletinfo['immature_balance'], conv_int=True) + if 'locked_utxos' in walletinfo: rv['locked_utxos'] = walletinfo['locked_utxos'] @@ -6611,7 +6612,6 @@ class BasicSwap(BaseApp): rv['mweb_address'] = self.getCachedStealthAddressForCoin(Coins.LTC_MWEB) rv['mweb_balance'] = walletinfo['mweb_balance'] rv['mweb_pending'] = walletinfo['mweb_unconfirmed'] + walletinfo['mweb_immature'] - rv['mweb_pending'] = walletinfo['mweb_unconfirmed'] + walletinfo['mweb_immature'] return rv except Exception as e: diff --git a/basicswap/rpc.py b/basicswap/rpc.py index 782d770..8ac5561 100644 --- a/basicswap/rpc.py +++ b/basicswap/rpc.py @@ -23,10 +23,7 @@ from .util import jsonDecimal def waitForRPC(rpc_func, expect_wallet=True, max_tries=7): for i in range(max_tries + 1): try: - if expect_wallet: - rpc_func('getwalletinfo') - else: - rpc_func('getblockchaininfo') + rpc_func('getwalletinfo' if expect_wallet else 'getblockchaininfo') return except Exception as ex: if i < max_tries: diff --git a/basicswap/templates/wallet.html b/basicswap/templates/wallet.html index b23042e..d807f14 100644 --- a/basicswap/templates/wallet.html +++ b/basicswap/templates/wallet.html @@ -141,7 +141,7 @@ {{ w.name }} Balance: - {{ w.balance }} {{ w.ticker }} (){% if w.unconfirmed %} Unconfirmed: +{{ w.unconfirmed }} {{ w.ticker }}{% endif %} + {{ w.balance }} {{ w.ticker }} (){% if w.pending %} Pending: +{{ w.pending }} {{ w.ticker }}{% endif %} {% if w.cid == '1' %} {# PART #} diff --git a/basicswap/templates/wallets.html b/basicswap/templates/wallets.html index ffd6214..a79c265 100644 --- a/basicswap/templates/wallets.html +++ b/basicswap/templates/wallets.html @@ -48,9 +48,9 @@
- {% for w in wallets %} - {% if w.havedata %} - {% if w.error %}

Error: {{ w.error }}

+ {% for w in wallets %} + {% if w.havedata %} + {% if w.error %}

Error: {{ w.error }}

{% else %}
@@ -76,13 +76,13 @@

{{ w.ticker }} USD value:

- {% if w.unconfirmed %} + {% if w.pending %}
-

Unconfirmed:

- +{{ w.unconfirmed }} {{ w.ticker }} +

Pending:

+ +{{ w.pending }} {{ w.ticker }}
-

Unconfirmed USD value:

+

Pending USD value:

{% endif %} @@ -413,4 +413,4 @@ window.onload = async () => { }; - \ No newline at end of file + diff --git a/basicswap/ui/page_wallet.py b/basicswap/ui/page_wallet.py index b8f2cf3..861f1c4 100644 --- a/basicswap/ui/page_wallet.py +++ b/basicswap/ui/page_wallet.py @@ -48,8 +48,14 @@ def format_wallet_data(swap_client, ci, w): wf['balance_all'] = float(w['balance']) + float(w['unconfirmed']) if 'lastupdated' in w: wf['lastupdated'] = format_timestamp(w['lastupdated']) + + pending: int = 0 if 'unconfirmed' in w and float(w['unconfirmed']) > 0.0: - wf['unconfirmed'] = w['unconfirmed'] + pending += ci.make_int(w['unconfirmed']) + if 'immature' in w and float(w['immature']) > 0.0: + pending += ci.make_int(w['immature']) + if pending > 0.0: + wf['pending'] = ci.format_amount(pending) if ci.coin_type() == Coins.PART: wf['stealth_address'] = w.get('stealth_address', '?') diff --git a/doc/release-notes.md b/doc/release-notes.md index 78bcbe3..bcf95c3 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -17,6 +17,7 @@ - Add settings in basicswap.json to set Monero rpc timeouts - `rpctimeout`, `walletrpctimeout` and `walletrpctimeoutlong` in the Monero section of basicswap.json. - `wallet_update_timeout` in basicswap.json to set how long the wallet ui page waits for an rpc response. +- ui: Renamed unconfirmed balance to pending and include immature balance in pending. 0.12.6 diff --git a/tests/basicswap/extended/test_xmr_persistent.py b/tests/basicswap/extended/test_xmr_persistent.py index 9adb951..c2db834 100644 --- a/tests/basicswap/extended/test_xmr_persistent.py +++ b/tests/basicswap/extended/test_xmr_persistent.py @@ -38,6 +38,7 @@ from basicswap.rpc import ( from tests.basicswap.common import ( BASE_RPC_PORT, BTC_BASE_RPC_PORT, + LTC_BASE_RPC_PORT, ) from tests.basicswap.util import ( make_boolean, @@ -59,6 +60,7 @@ UI_PORT = 12700 + PORT_OFS PARTICL_RPC_PORT_BASE = int(os.getenv('PARTICL_RPC_PORT_BASE', BASE_RPC_PORT)) BITCOIN_RPC_PORT_BASE = int(os.getenv('BITCOIN_RPC_PORT_BASE', BTC_BASE_RPC_PORT)) +LITECOIN_RPC_PORT_BASE = int(os.getenv('LITECOIN_RPC_PORT_BASE', LTC_BASE_RPC_PORT)) XMR_BASE_RPC_PORT = int(os.getenv('XMR_BASE_RPC_PORT', XMR_BASE_RPC_PORT)) TEST_COINS_LIST = os.getenv('TEST_COINS_LIST', 'bitcoin,monero') @@ -81,6 +83,11 @@ def callbtcrpc(node_id, method, params=[], wallet=None, base_rpc_port=BITCOIN_RP return callrpc(base_rpc_port + node_id, auth, method, params, wallet) +def callltcrpc(node_id, method, params=[], wallet=None, base_rpc_port=LITECOIN_RPC_PORT_BASE + PORT_OFS): + auth = 'test_ltc_{0}:test_ltc_pwd_{0}'.format(node_id) + return callrpc(base_rpc_port + node_id, auth, method, params, wallet) + + def updateThread(cls): while not cls.delay_event.is_set(): try: @@ -167,11 +174,28 @@ class Test(unittest.TestCase): logging.info('XMR blocks: %d', callrpc_xmr(XMR_BASE_RPC_PORT + 1, 'get_block_count', auth=xmr_auth)['count']) self.btc_addr = callbtcrpc(0, 'getnewaddress', ['mining_addr', 'bech32']) - num_blocks = 500 # Mine enough to activate segwit - if callbtcrpc(0, 'getblockchaininfo')['blocks'] < num_blocks: + num_blocks: int = 500 # Mine enough to activate segwit + if callbtcrpc(0, 'getblockcount') < num_blocks: logging.info('Mining %d Bitcoin blocks to %s', num_blocks, self.btc_addr) callbtcrpc(0, 'generatetoaddress', [num_blocks, self.btc_addr]) - logging.info('BTC blocks: %d', callbtcrpc(0, 'getblockchaininfo')['blocks']) + logging.info('BTC blocks: %d', callbtcrpc(0, 'getblockcount')) + + if 'litecoin' in TEST_COINS_LIST: + self.ltc_addr = callltcrpc(0, 'getnewaddress', ['mining_addr'], wallet='wallet.dat') + num_blocks: int = 431 + have_blocks: int = callltcrpc(0, 'getblockcount') + if have_blocks < 500: + logging.info('Mining %d Litecoin blocks to %s', num_blocks, self.ltc_addr) + callltcrpc(0, 'generatetoaddress', [num_blocks - have_blocks, self.ltc_addr], wallet='wallet.dat') + + # https://github.com/litecoin-project/litecoin/issues/807 + # Block 432 is when MWEB activates. It requires a peg-in. You'll need to generate an mweb address and send some coins to it. Then it will allow you to mine the next block. + mweb_addr = callltcrpc(0, 'getnewaddress', ['mweb_addr', 'mweb'], wallet='mweb') + callltcrpc(0, 'sendtoaddress', [mweb_addr, 1.0], wallet='wallet.dat') + num_blocks = 69 + + have_blocks: int = callltcrpc(0, 'getblockcount') + callltcrpc(0, 'generatetoaddress', [500 - have_blocks, self.ltc_addr], wallet='wallet.dat') # Lower output split threshold for more stakeable outputs for i in range(NUM_NODES): diff --git a/tests/basicswap/test_btc_xmr.py b/tests/basicswap/test_btc_xmr.py index d17ea9b..cc14cf5 100644 --- a/tests/basicswap/test_btc_xmr.py +++ b/tests/basicswap/test_btc_xmr.py @@ -575,7 +575,7 @@ class BasicSwapTest(TestFunctions): swap_clients = self.swap_clients ci = self.swap_clients[0].ci(self.test_coin_from) - self.check_softfork_active('bip66') + self.check_softfork_active('csv') script = CScript([3, OP_CHECKSEQUENCEVERIFY, ]) diff --git a/tests/basicswap/test_ltc_xmr.py b/tests/basicswap/test_ltc_xmr.py index c894977..6b2508c 100644 --- a/tests/basicswap/test_ltc_xmr.py +++ b/tests/basicswap/test_ltc_xmr.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -# Copyright (c) 2021-2023 tecnovert +# Copyright (c) 2021-2024 tecnovert # Distributed under the MIT software license, see the accompanying # file LICENSE or http://www.opensource.org/licenses/mit-license.php. @@ -27,7 +27,8 @@ from tests.basicswap.common import ( TEST_HTTP_PORT, LTC_BASE_RPC_PORT, ) -from .test_btc_xmr import BasicSwapTest, test_delay_event, callnoderpc +from .test_btc_xmr import BasicSwapTest, test_delay_event +from .test_xmr import pause_event logger = logging.getLogger() @@ -38,13 +39,6 @@ class TestLTC(BasicSwapTest): start_ltc_nodes = True base_rpc_port = LTC_BASE_RPC_PORT - @classmethod - def prepareExtraCoins(cls): - logging.info('Mining {} chain to height 1352 to activate CVS (BIP66)'.format(cls.test_coin_from.name)) - chain_height = callnoderpc(0, 'getblockcount', base_rpc_port=LTC_BASE_RPC_PORT) - num_blocks: int = 1352 - chain_height - callnoderpc(0, 'generatetoaddress', [num_blocks, cls.ltc_addr], base_rpc_port=LTC_BASE_RPC_PORT) - def mineBlock(self, num_blocks=1): self.callnoderpc('generatetoaddress', [num_blocks, self.ltc_addr]) @@ -137,7 +131,24 @@ class TestLTC(BasicSwapTest): addr_info1 = ci1.rpc_wallet('getaddressinfo', [mweb_addr_1,]) assert (addr_info1['ismweb'] is True) - txid = ci0.rpc_wallet('sendtoaddress', [mweb_addr_0, 10.0]) + trusted_before = ci0.rpc_wallet('getbalances')['mine']['trusted'] + ci0.rpc_wallet('sendtoaddress', [mweb_addr_0, 10.0]) + assert (trusted_before - float(ci0.rpc_wallet('getbalances')['mine']['trusted']) < 0.1) + + try: + pause_event.clear() # Stop mining + ci0.rpc_wallet('sendtoaddress', [mweb_addr_1, 10.0]) + + found_unconfirmed: bool = False + for i in range(20): + test_delay_event.wait(1) + ltc_wallet = read_json_api(TEST_HTTP_PORT + 1, 'wallets/ltc') + if float(ltc_wallet['unconfirmed']) == 10.0: + found_unconfirmed = True + break + finally: + pause_event.set() + assert (found_unconfirmed) self.mineBlock()