mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-03 00:31:50 +00:00
Use OS file locks in validator client (#1958)
## Issue Addressed Closes #1823 ## Proposed Changes * Use OS-level file locking for validator keystores, eliminating problems with lockfiles lingering after ungraceful shutdowns (`SIGKILL`, power outage). I'm using the `fs2` crate because it's cross-platform (unlike `file-lock`), and it seems to have the most downloads on crates.io. * Deprecate + disable `--delete-lockfiles` CLI param, it's no longer necessary * Delete the `validator_dir::Manager`, as it was mostly dead code and was only used in the `validator list` command, which has been rewritten to read the validator definitions YAML instead. ## Additional Info Tested on: - [x] Linux - [x] macOS - [x] Docker Linux - [x] Docker macOS - [ ] Windows
This commit is contained in:
@@ -9,6 +9,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
eth2_keystore = { path = "../../crypto/eth2_keystore" }
|
||||
eth2_wallet = { path = "../../crypto/eth2_wallet" }
|
||||
lockfile = { path = "../lockfile" }
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3.1.0"
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::{
|
||||
Error,
|
||||
};
|
||||
use eth2_wallet::{Uuid, ValidatorKeystores, Wallet};
|
||||
use std::fs::{remove_file, OpenOptions};
|
||||
use lockfile::Lockfile;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub const LOCK_FILE: &str = ".lock";
|
||||
@@ -26,6 +26,7 @@ pub const LOCK_FILE: &str = ".lock";
|
||||
pub struct LockedWallet {
|
||||
wallet_dir: PathBuf,
|
||||
wallet: Wallet,
|
||||
_lockfile: Lockfile,
|
||||
}
|
||||
|
||||
impl LockedWallet {
|
||||
@@ -49,20 +50,12 @@ impl LockedWallet {
|
||||
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)?;
|
||||
}
|
||||
let _lockfile = Lockfile::new(wallet_dir.join(LOCK_FILE))?;
|
||||
|
||||
Ok(Self {
|
||||
wallet: read(&wallet_dir, uuid)?,
|
||||
wallet_dir,
|
||||
_lockfile,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -99,13 +92,3 @@ impl LockedWallet {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ use crate::{
|
||||
LockedWallet,
|
||||
};
|
||||
use eth2_wallet::{bip39::Mnemonic, Error as WalletError, Uuid, Wallet, WalletBuilder};
|
||||
use lockfile::LockfileError;
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsString;
|
||||
use std::fs::{create_dir_all, read_dir, OpenOptions};
|
||||
@@ -21,10 +22,9 @@ pub enum Error {
|
||||
WalletNameUnknown(String),
|
||||
WalletDirExists(PathBuf),
|
||||
IoError(io::Error),
|
||||
WalletIsLocked(PathBuf),
|
||||
MissingWalletDir(PathBuf),
|
||||
UnableToCreateLockfile(io::Error),
|
||||
UuidMismatch((Uuid, Uuid)),
|
||||
LockfileError(LockfileError),
|
||||
}
|
||||
|
||||
impl From<io::Error> for Error {
|
||||
@@ -45,6 +45,12 @@ impl From<FilesystemError> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LockfileError> for Error {
|
||||
fn from(e: LockfileError) -> Error {
|
||||
Error::LockfileError(e)
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines the type of an EIP-2386 wallet.
|
||||
///
|
||||
/// Presently only `Hd` wallets are supported.
|
||||
@@ -358,7 +364,7 @@ mod tests {
|
||||
);
|
||||
|
||||
match LockedWallet::open(&base_dir, &uuid_a) {
|
||||
Err(Error::WalletIsLocked(_)) => {}
|
||||
Err(Error::LockfileError(_)) => {}
|
||||
_ => panic!("did not get locked error"),
|
||||
};
|
||||
|
||||
@@ -368,7 +374,7 @@ mod tests {
|
||||
.expect("should open wallet a after previous instance is dropped");
|
||||
|
||||
match LockedWallet::open(&base_dir, &uuid_b) {
|
||||
Err(Error::WalletIsLocked(_)) => {}
|
||||
Err(Error::LockfileError(_)) => {}
|
||||
_ => panic!("did not get locked error"),
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user