From 10b7ccaa92509d0e2290e2756fae1103599d8fa9 Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Fri, 30 Aug 2019 02:50:21 -0300 Subject: [PATCH] fix unordered history inconsistency --- .../client_tests/integration/test_transactions.py | 6 ++++++ torba/torba/client/baseledger.py | 14 ++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/torba/tests/client_tests/integration/test_transactions.py b/torba/tests/client_tests/integration/test_transactions.py index 4fb67f11b..4ee4e2dfe 100644 --- a/torba/tests/client_tests/integration/test_transactions.py +++ b/torba/tests/client_tests/integration/test_transactions.py @@ -168,3 +168,9 @@ class BasicTransactionTests(IntegrationTestCase): await asyncio.wait([self.on_transaction_address(tx, address) for tx in txs], timeout=1) remote_status = await self.ledger.network.subscribe_address(address) self.assertTrue(await self.ledger.update_history(address, remote_status)) + # server history grows unordered + txid = await self.blockchain.send_to_address(address, 1) + await self.on_transaction_id(txid) + self.assertTrue(await self.ledger.update_history(address, remote_status)) + self.assertEqual(21, len((await self.ledger.get_local_status_and_history(address))[1])) + self.assertEqual(0, len(self.ledger._known_addresses_out_of_sync)) diff --git a/torba/torba/client/baseledger.py b/torba/torba/client/baseledger.py index 704654669..5c47cb79f 100644 --- a/torba/torba/client/baseledger.py +++ b/torba/torba/client/baseledger.py @@ -142,6 +142,7 @@ class BaseLedger(metaclass=LedgerRegistry): self._address_update_locks: Dict[str, asyncio.Lock] = {} self.coin_selection_strategy = None + self._known_addresses_out_of_sync = set() @classmethod def get_id(cls): @@ -411,6 +412,7 @@ class BaseLedger(metaclass=LedgerRegistry): address_manager: baseaccount.AddressManager = None): async with self._address_update_locks.setdefault(address, asyncio.Lock()): + self._known_addresses_out_of_sync.discard(address) local_status, local_history = await self.get_local_status_and_history(address) @@ -422,7 +424,7 @@ class BaseLedger(metaclass=LedgerRegistry): cache_tasks = [] synced_history = StringIO() for i, (txid, remote_height) in enumerate(map(itemgetter('tx_hash', 'height'), remote_history)): - if i < len(local_history) and local_history[i] == (txid, remote_height): + if i < len(local_history) and local_history[i] == (txid, remote_height) and not cache_tasks: synced_history.write(f'{txid}:{remote_height}:') else: cache_tasks.append(asyncio.ensure_future( @@ -472,15 +474,15 @@ class BaseLedger(metaclass=LedgerRegistry): local_status, local_history = await self.get_local_status_and_history(address) if local_status != remote_status: - remote_history = list(map(itemgetter('tx_hash', 'height'), remote_history)) - if remote_history == local_history: + if local_history == list(map(itemgetter('tx_hash', 'height'), remote_history)): return True - log.debug( + log.warning( "Wallet is out of sync after syncing. Remote: %s with %d items, local: %s with %d items", remote_status, len(remote_history), local_status, len(local_history) ) - log.debug("local: %s", local_history) - log.debug("remote: %s", remote_history) + log.warning("local: %s", local_history) + log.warning("remote: %s", remote_history) + self._known_addresses_out_of_sync.add(address) return False else: return True