diff --git a/ethstore/src/dir/disk.rs b/ethstore/src/dir/disk.rs index c8afcc910..ccc84077b 100755 --- a/ethstore/src/dir/disk.rs +++ b/ethstore/src/dir/disk.rs @@ -219,6 +219,10 @@ impl KeyDirectory for DiskDirectory where T: KeyFileManager { fn as_vault_provider(&self) -> Option<&VaultKeyDirectoryProvider> { Some(self) } + + fn hash(&self) -> Result { + self.files_hash() + } } impl VaultKeyDirectoryProvider for DiskDirectory where T: KeyFileManager { diff --git a/ethstore/src/dir/mod.rs b/ethstore/src/dir/mod.rs index 6e4326968..11a1a2f23 100755 --- a/ethstore/src/dir/mod.rs +++ b/ethstore/src/dir/mod.rs @@ -16,6 +16,7 @@ use std::path::{PathBuf}; use {SafeAccount, Error}; +use util::{H256, FixedHash}; mod disk; mod geth; @@ -62,6 +63,8 @@ pub trait KeyDirectory: Send + Sync { fn path(&self) -> Option<&PathBuf> { None } /// Return vault provider, if available fn as_vault_provider(&self) -> Option<&VaultKeyDirectoryProvider> { None } + /// Returns hash of the directory content, if supported + fn hash(&self) -> Result { Ok(H256::zero()) } } /// Vaults provider diff --git a/ethstore/src/ethstore.rs b/ethstore/src/ethstore.rs index 86b6dce46..eecc361e4 100755 --- a/ethstore/src/ethstore.rs +++ b/ethstore/src/ethstore.rs @@ -27,6 +27,7 @@ use account::SafeAccount; use presale::PresaleWallet; use json::{self, Uuid}; use {import, Error, SimpleSecretStore, SecretStore, SecretVaultRef, StoreAccountRef, Derivation}; +use util::H256; pub struct EthStore { store: EthMultiStore, @@ -230,6 +231,7 @@ pub struct EthMultiStore { // order lock: cache, then vaults cache: RwLock>>, vaults: Mutex>>, + dir_hash: RwLock>, } impl EthMultiStore { @@ -244,11 +246,23 @@ impl EthMultiStore { vaults: Mutex::new(HashMap::new()), iterations: iterations, cache: Default::default(), + dir_hash: Default::default(), }; store.reload_accounts()?; Ok(store) } + fn reload_if_changed(&self) -> Result<(), Error> { + let mut last_dir_hash = self.dir_hash.write(); + let dir_hash = Some(self.dir.hash()?); + if *last_dir_hash == dir_hash { + return Ok(()) + } + self.reload_accounts()?; + *last_dir_hash = dir_hash; + Ok(()) + } + fn reload_accounts(&self) -> Result<(), Error> { let mut cache = self.cache.write(); @@ -284,7 +298,7 @@ impl EthMultiStore { } } - self.reload_accounts()?; + self.reload_if_changed()?; let cache = self.cache.read(); let accounts = cache.get(account).ok_or(Error::InvalidAccount)?; if accounts.is_empty() { @@ -431,7 +445,7 @@ impl SimpleSecretStore for EthMultiStore { } fn account_ref(&self, address: &Address) -> Result { - self.reload_accounts()?; + self.reload_if_changed()?; self.cache.read().keys() .find(|r| &r.address == address) .cloned() @@ -439,7 +453,7 @@ impl SimpleSecretStore for EthMultiStore { } fn accounts(&self) -> Result, Error> { - self.reload_accounts()?; + self.reload_if_changed()?; Ok(self.cache.read().keys().cloned().collect()) }