ui: Rename unconfirmed balance to pending, include immature balance.

2024-05-20_merge
tecnovert 11 months ago
parent 1f810fab6b
commit 6e4feb33d7
No known key found for this signature in database
GPG Key ID: 8ED6D8750C4E3F93
  1. 10
      basicswap/basicswap.py
  2. 5
      basicswap/rpc.py
  3. 2
      basicswap/templates/wallet.html
  4. 8
      basicswap/templates/wallets.html
  5. 8
      basicswap/ui/page_wallet.py
  6. 1
      doc/release-notes.md
  7. 30
      tests/basicswap/extended/test_xmr_persistent.py
  8. 2
      tests/basicswap/test_btc_xmr.py
  9. 31
      tests/basicswap/test_ltc_xmr.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:

@ -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:

@ -141,7 +141,7 @@
<img class="h-7" src="/static/images/coins/{{ w.name }}.png" alt="{{ w.name }}">
</span>Balance:
</td>
<td class="py-3 px-6 bold coinname-value" data-coinname="{{ w.name }}">{{ w.balance }} {{ w.ticker }} (<span class="usd-value"></span>){% if w.unconfirmed %} <span class="inline-block py-1 px-2 rounded-full bg-green-100 text-green-500 dark:bg-gray-500 dark:text-green-500">Unconfirmed: +{{ w.unconfirmed }} {{ w.ticker }}</span>{% endif %}</td>
<td class="py-3 px-6 bold coinname-value" data-coinname="{{ w.name }}">{{ w.balance }} {{ w.ticker }} (<span class="usd-value"></span>){% if w.pending %} <span class="inline-block py-1 px-2 rounded-full bg-green-100 text-green-500 dark:bg-gray-500 dark:text-green-500">Pending: +{{ w.pending }} {{ w.ticker }}</span>{% endif %}</td>
</tr>
{% if w.cid == '1' %} {# PART #}
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">

@ -76,13 +76,13 @@
<h4 class="text-xs font-medium dark:text-white">{{ w.ticker }} USD value:</h4>
<div class="bold inline-block py-1 px-2 rounded-full bg-blue-100 text-xs text-black-500 dark:bg-gray-500 dark:text-gray-200 usd-value"></div>
</div>
{% if w.unconfirmed %}
{% if w.pending %}
<div class="flex mb-2 justify-between items-center">
<h4 class="text-xs font-bold text-green-500 dark:text-green-500">Unconfirmed:</h4>
<span class="bold inline-block py-1 px-2 rounded-full bg-green-100 text-xs text-green-500 dark:bg-gray-500 dark:text-green-500 coinname-value" data-coinname="{{ w.name }}">+{{ w.unconfirmed }} {{ w.ticker }}</span>
<h4 class="text-xs font-bold text-green-500 dark:text-green-500">Pending:</h4>
<span class="bold inline-block py-1 px-2 rounded-full bg-green-100 text-xs text-green-500 dark:bg-gray-500 dark:text-green-500 coinname-value" data-coinname="{{ w.name }}">+{{ w.pending }} {{ w.ticker }}</span>
</div>
<div class="flex mb-2 justify-between items-center">
<h4 class="text-xs font-bold text-green-500 dark:text-green-500">Unconfirmed USD value:</h4>
<h4 class="text-xs font-bold text-green-500 dark:text-green-500">Pending USD value:</h4>
<div class="bold inline-block py-1 px-2 rounded-full bg-green-100 text-xs text-green-500 dark:bg-gray-500 dark:text-green-500 usd-value"></div>
</div>
{% endif %}

@ -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', '?')

@ -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

@ -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):

@ -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, ])

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

Loading…
Cancel
Save