Merge pull request #2881 from lbryio/wallet_sync_status

add `wallet_syncing` to `status`, which is set to true when processing transaction updates
This commit is contained in:
Jack Robison 2020-03-26 15:28:20 -04:00 committed by GitHub
commit 15eb5d47eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 10 deletions

View file

@ -1326,7 +1326,11 @@ class Daemon(metaclass=JSONRPCServerType):
Dictionary of wallet status information.
"""
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
return {'is_encrypted': wallet.is_encrypted, 'is_locked': wallet.is_locked}
return {
'is_encrypted': wallet.is_encrypted,
'is_syncing': len(self.ledger._update_tasks) > 0,
'is_locked': wallet.is_locked
}
@requires(WALLET_COMPONENT)
def jsonrpc_wallet_unlock(self, password, wallet_id=None):

View file

@ -334,7 +334,7 @@ class Ledger(metaclass=LedgerRegistry):
log.info("Subscribing and updating accounts.")
async with self._header_processing_lock:
await self._update_tasks.add(self.initial_headers_sync())
await self.subscribe_accounts()
await self._update_tasks.add(self.subscribe_accounts())
await self._update_tasks.done.wait()
self._on_ready_controller.add(True)

View file

@ -8,6 +8,9 @@ class TaskGroup:
self._tasks = set()
self.done = Event()
def __len__(self):
return len(self._tasks)
def add(self, coro):
task = self._loop.create_task(coro)
self._tasks.add(task)

View file

@ -1,5 +1,6 @@
import asyncio
import json
import os
from lbry.wallet import ENCRYPT_ON_DISK
from lbry.error import InvalidPasswordError
@ -19,6 +20,17 @@ class WalletCommands(CommandTestCase):
await self.daemon.jsonrpc_wallet_add(wallet.id)
self.assertEqual(len(session.hashX_subs), 28)
async def test_wallet_syncing_status(self):
address = await self.daemon.jsonrpc_address_unused()
sendtxid = await self.blockchain.send_to_address(address, 1)
async def eventually_will_sync():
while not self.daemon.jsonrpc_wallet_status()['is_syncing']:
await asyncio.sleep(0)
check_sync = asyncio.create_task(eventually_will_sync())
await self.confirm_tx(sendtxid, self.ledger)
await asyncio.wait_for(check_sync, timeout=10)
async def test_wallet_reconnect(self):
await self.conductor.spv_node.stop(True)
self.conductor.spv_node.port = 54320
@ -268,7 +280,9 @@ class WalletEncryptionAndSynchronization(CommandTestCase):
wallet = daemon.wallet_manager.default_wallet
wallet.save()
self.assertEqual(daemon.jsonrpc_wallet_status(), {'is_locked': False, 'is_encrypted': False})
self.assertEqual(daemon.jsonrpc_wallet_status(), {
'is_locked': False, 'is_encrypted': False, 'is_syncing': False
})
self.assertIsNone(daemon.jsonrpc_preference_get(ENCRYPT_ON_DISK))
self.assertWalletEncrypted(wallet.storage.path, False)
@ -280,22 +294,26 @@ class WalletEncryptionAndSynchronization(CommandTestCase):
daemon.jsonrpc_wallet_decrypt() # already not encrypted
daemon.jsonrpc_wallet_encrypt('password')
self.assertEqual(daemon.jsonrpc_wallet_status(), {'is_locked': False, 'is_encrypted': True})
self.assertEqual(daemon.jsonrpc_wallet_status(), {'is_locked': False, 'is_encrypted': True,
'is_syncing': False})
self.assertEqual(daemon.jsonrpc_preference_get(ENCRYPT_ON_DISK), {'encrypt-on-disk': True})
self.assertWalletEncrypted(wallet.storage.path, True)
daemon.jsonrpc_wallet_lock()
self.assertEqual(daemon.jsonrpc_wallet_status(), {'is_locked': True, 'is_encrypted': True})
self.assertEqual(daemon.jsonrpc_wallet_status(), {'is_locked': True, 'is_encrypted': True,
'is_syncing': False})
# can't sign transactions with locked wallet
with self.assertRaises(AssertionError):
await daemon.jsonrpc_channel_create('@foo', '1.0')
daemon.jsonrpc_wallet_unlock('password')
self.assertEqual(daemon.jsonrpc_wallet_status(), {'is_locked': False, 'is_encrypted': True})
self.assertEqual(daemon.jsonrpc_wallet_status(), {'is_locked': False, 'is_encrypted': True,
'is_syncing': False})
await daemon.jsonrpc_channel_create('@foo', '1.0')
daemon.jsonrpc_wallet_decrypt()
self.assertEqual(daemon.jsonrpc_wallet_status(), {'is_locked': False, 'is_encrypted': False})
self.assertEqual(daemon.jsonrpc_wallet_status(), {'is_locked': False, 'is_encrypted': False,
'is_syncing': False})
self.assertEqual(daemon.jsonrpc_preference_get(ENCRYPT_ON_DISK), {'encrypt-on-disk': False})
self.assertWalletEncrypted(wallet.storage.path, False)
@ -307,7 +325,8 @@ class WalletEncryptionAndSynchronization(CommandTestCase):
self.assertTrue(daemon2.jsonrpc_wallet_encrypt('password'))
self.assertTrue(daemon2.jsonrpc_wallet_lock())
self.assertTrue(daemon2.jsonrpc_wallet_unlock("password"))
self.assertEqual(daemon2.jsonrpc_wallet_status(), {'is_locked': False, 'is_encrypted': True})
self.assertEqual(daemon2.jsonrpc_wallet_status(),
{'is_locked': False, 'is_encrypted': True, 'is_syncing': False})
async def test_sync_with_encryption_and_password_change(self):
daemon, daemon2 = self.daemon, self.daemon2
@ -328,7 +347,8 @@ class WalletEncryptionAndSynchronization(CommandTestCase):
await daemon.jsonrpc_sync_apply('password2', data=data['data'], blocking=True)
# sync_apply with new password2 also sets it as new local password
self.assertEqual(wallet.encryption_password, 'password2')
self.assertEqual(daemon.jsonrpc_wallet_status(), {'is_locked': False, 'is_encrypted': True})
self.assertEqual(daemon.jsonrpc_wallet_status(), {'is_locked': False, 'is_encrypted': True,
'is_syncing': True})
self.assertEqual(daemon.jsonrpc_preference_get(ENCRYPT_ON_DISK), {'encrypt-on-disk': True})
self.assertWalletEncrypted(wallet.storage.path, True)
@ -345,7 +365,8 @@ class WalletEncryptionAndSynchronization(CommandTestCase):
await daemon2.jsonrpc_sync_apply('password3', data=data['data'], blocking=True)
# the other device got new password and on disk encryption
self.assertEqual(wallet2.encryption_password, 'password3')
self.assertEqual(daemon2.jsonrpc_wallet_status(), {'is_locked': False, 'is_encrypted': True})
self.assertEqual(daemon2.jsonrpc_wallet_status(), {'is_locked': False, 'is_encrypted': True,
'is_syncing': True})
self.assertEqual(daemon2.jsonrpc_preference_get(ENCRYPT_ON_DISK), {'encrypt-on-disk': True})
self.assertWalletEncrypted(wallet2.storage.path, True)