[cli] Lock keystore accesses

pull/2/head
Daniel Van Der Maden 5 years ago
parent 00ad71714d
commit 3ee4aa15f8
  1. 2
      pyhmy/_version.py
  2. 29
      pyhmy/cli.py

@ -7,5 +7,5 @@ Provides pyhmy version information.
from incremental import Version from incremental import Version
__version__ = Version('pyhmy', 20, 1, 15) __version__ = Version('pyhmy', 20, 1, 16)
__all__ = ["__version__"] __all__ = ["__version__"]

@ -60,36 +60,11 @@ else:
_accounts = {} # Internal accounts keystore, make sure to sync when needed. _accounts = {} # Internal accounts keystore, make sure to sync when needed.
_account_keystore_path = "~/.hmy/account-keys" # Internal path to account keystore, will match the current binary. _account_keystore_path = "~/.hmy/account-keys" # Internal path to account keystore, will match the current binary.
_binary_path = "hmy" # Internal binary path. _binary_path = "hmy" # Internal binary path.
_keystore_cache_lock = Lock() _keystore_lock = Lock()
environment = os.environ.copy() # The environment for the CLI to execute in. environment = os.environ.copy() # The environment for the CLI to execute in.
def _cache_and_lock_accounts_keystore(fn):
"""
Internal decorator to cache the accounts keystore and
prevent concurrent accesses with locks.
"""
cached_accounts = {}
last_mod = None
def wrap(*args):
nonlocal last_mod
_keystore_cache_lock.acquire()
files_in_dir = str(os.listdir(_account_keystore_path))
dir_mod_time = str(os.path.getmtime(_account_keystore_path))
curr_mod = hash(files_in_dir + dir_mod_time + _binary_path)
if curr_mod != last_mod:
cached_accounts.clear()
cached_accounts.update(fn(*args))
last_mod = curr_mod
accounts = cached_accounts.copy()
_keystore_cache_lock.release()
return accounts
return wrap
def _get_current_accounts_keystore(): def _get_current_accounts_keystore():
""" """
Internal function that gets the current keystore from the CLI. Internal function that gets the current keystore from the CLI.
@ -97,8 +72,10 @@ def _get_current_accounts_keystore():
:returns A dictionary where the keys are the account names/aliases and the :returns A dictionary where the keys are the account names/aliases and the
values are their 'one1...' addresses. values are their 'one1...' addresses.
""" """
_keystore_lock.acquire()
curr_addresses = {} curr_addresses = {}
response = single_call("hmy keys list") response = single_call("hmy keys list")
_keystore_lock.release()
lines = response.split("\n") lines = response.split("\n")
if "NAME" not in lines[0] or "ADDRESS" not in lines[0]: if "NAME" not in lines[0] or "ADDRESS" not in lines[0]:
raise ValueError("Name or Address not found on first line of key list") raise ValueError("Name or Address not found on first line of key list")

Loading…
Cancel
Save