mirror of
https://github.com/sigp/lighthouse.git
synced 2026-06-30 11:24:31 +00:00
Directory Restructure (#1163)
* Move tests -> testing * Directory restructure * Update Cargo.toml during restructure * Update Makefile during restructure * Fix arbitrary path
This commit is contained in:
111
common/eth2_wallet_manager/src/locked_wallet.rs
Normal file
111
common/eth2_wallet_manager/src/locked_wallet.rs
Normal file
@@ -0,0 +1,111 @@
|
||||
use crate::{
|
||||
filesystem::{read, update},
|
||||
Error,
|
||||
};
|
||||
use eth2_wallet::{Uuid, ValidatorKeystores, Wallet};
|
||||
use std::fs::{remove_file, OpenOptions};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub const LOCK_FILE: &str = ".lock";
|
||||
|
||||
/// Represents a `Wallet` in a `wallet_dir`.
|
||||
///
|
||||
/// For example:
|
||||
///
|
||||
/// ```ignore
|
||||
/// <wallet_dir>
|
||||
/// └── .lock
|
||||
/// └── <wallet-json>
|
||||
/// ```
|
||||
///
|
||||
/// Provides the following functionality:
|
||||
///
|
||||
/// - Control over the `.lock` file to prevent concurrent access.
|
||||
/// - A `next_validator` function which wraps `Wallet::next_validator`, ensuring that the wallet is
|
||||
/// persisted to disk (as JSON) between each consecutive call.
|
||||
pub struct LockedWallet {
|
||||
wallet_dir: PathBuf,
|
||||
wallet: Wallet,
|
||||
}
|
||||
|
||||
impl LockedWallet {
|
||||
/// Opens a wallet with the `uuid` from a `base_dir`.
|
||||
///
|
||||
/// ```ignore
|
||||
/// <base-dir>
|
||||
/// ├── <uuid (directory)>
|
||||
/// └── <uuid (json file)>
|
||||
/// ```
|
||||
///
|
||||
/// ## Errors
|
||||
///
|
||||
/// - If the wallet does not exist.
|
||||
/// - There is file-system or parsing error.
|
||||
/// - The lock-file already exists.
|
||||
pub(crate) fn open<P: AsRef<Path>>(base_dir: P, uuid: &Uuid) -> Result<Self, Error> {
|
||||
let wallet_dir = base_dir.as_ref().join(format!("{}", uuid));
|
||||
|
||||
if !wallet_dir.exists() {
|
||||
return Err(Error::MissingWalletDir(wallet_dir));
|
||||
}
|
||||
|
||||
let lockfile = wallet_dir.join(LOCK_FILE);
|
||||
if lockfile.exists() {
|
||||
return Err(Error::WalletIsLocked(wallet_dir));
|
||||
} else {
|
||||
OpenOptions::new()
|
||||
.write(true)
|
||||
.create_new(true)
|
||||
.open(lockfile)
|
||||
.map_err(Error::UnableToCreateLockfile)?;
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
wallet: read(&wallet_dir, uuid)?,
|
||||
wallet_dir,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a reference to the underlying wallet.
|
||||
///
|
||||
/// Note: this does not read from the file-system on each call. It assumes that the wallet does
|
||||
/// not change due to the use of a lock-file.
|
||||
pub fn wallet(&self) -> &Wallet {
|
||||
&self.wallet
|
||||
}
|
||||
|
||||
/// Calls `Wallet::next_validator` on the underlying `wallet`.
|
||||
///
|
||||
/// Ensures that the wallet JSON file is updated after each call.
|
||||
///
|
||||
/// ## Errors
|
||||
///
|
||||
/// - If there is an error generating the validator keys.
|
||||
/// - If there is a file-system error.
|
||||
pub fn next_validator(
|
||||
&mut self,
|
||||
wallet_password: &[u8],
|
||||
voting_keystore_password: &[u8],
|
||||
withdrawal_keystore_password: &[u8],
|
||||
) -> Result<ValidatorKeystores, Error> {
|
||||
let keystores = self.wallet.next_validator(
|
||||
wallet_password,
|
||||
voting_keystore_password,
|
||||
withdrawal_keystore_password,
|
||||
)?;
|
||||
|
||||
update(&self.wallet_dir, &self.wallet)?;
|
||||
|
||||
Ok(keystores)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for LockedWallet {
|
||||
/// Clean-up the lockfile.
|
||||
fn drop(&mut self) {
|
||||
let lockfile = self.wallet_dir.clone().join(LOCK_FILE);
|
||||
if let Err(e) = remove_file(&lockfile) {
|
||||
eprintln!("Unable to remove {:?}: {:?}", lockfile, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user