From 0ccafd5b534c234596d2e18183cb52246070f3ce Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Thu, 8 Jul 2021 03:31:20 -0300 Subject: [PATCH] make get_or_create_usable_address respect the generator lock --- lbry/wallet/account.py | 3 ++- tests/unit/wallet/test_account.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lbry/wallet/account.py b/lbry/wallet/account.py index b673a5cb5..a61878403 100644 --- a/lbry/wallet/account.py +++ b/lbry/wallet/account.py @@ -96,7 +96,8 @@ class AddressManager: return [r['address'] for r in records] async def get_or_create_usable_address(self) -> str: - addresses = await self.get_addresses(only_usable=True, limit=10) + async with self.address_generator_lock: + addresses = await self.get_addresses(only_usable=True, limit=10) if addresses: return random.choice(addresses) addresses = await self.ensure_address_gap() diff --git a/tests/unit/wallet/test_account.py b/tests/unit/wallet/test_account.py index 5ce68f430..894762c68 100644 --- a/tests/unit/wallet/test_account.py +++ b/tests/unit/wallet/test_account.py @@ -1,3 +1,4 @@ +import asyncio from binascii import hexlify from lbry.testcase import AsyncioTestCase from lbry.wallet import Wallet, Ledger, Database, Headers, Account, SingleKey, HierarchicalDeterministic @@ -37,6 +38,18 @@ class TestAccount(AsyncioTestCase): addresses = await account.change.get_addresses() self.assertEqual(len(addresses), 6) + async def test_unused_address_on_account_creation_does_not_cause_a_race(self): + account = Account.generate(self.ledger, Wallet(), 'lbryum') + await account.ledger.db.db.executescript("update pubkey_address set used_times=10") + await account.receiving.address_generator_lock.acquire() + delayed1 = asyncio.ensure_future(account.receiving.ensure_address_gap()) + delayed = asyncio.ensure_future(account.receiving.get_or_create_usable_address()) + await asyncio.sleep(0) + # wallet being created and queried at the same time + account.receiving.address_generator_lock.release() + await delayed1 + await delayed + async def test_generate_keys_over_batch_threshold_saves_it_properly(self): account = Account.generate(self.ledger, Wallet(), 'lbryum') async with account.receiving.address_generator_lock: