From 8fb73f16a91d1b7debdd9c9b0f53eee08fcc974d Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 5 May 2021 14:12:19 -0400 Subject: [PATCH 01/32] Made changes for Windows Compatibility --- Cargo.lock | 108 +++++++++++++++++- account_manager/Cargo.toml | 1 + account_manager/src/validator/create.rs | 19 ++- account_manager/src/wallet/create.rs | 48 +++----- common/account_utils/Cargo.toml | 1 + common/account_utils/src/lib.rs | 18 --- .../src/validator_definitions.rs | 7 +- common/filesystem/Cargo.toml | 13 +++ common/filesystem/src/lib.rs | 98 ++++++++++++++++ common/validator_dir/Cargo.toml | 1 + common/validator_dir/src/builder.rs | 20 +--- slasher/Cargo.toml | 1 + slasher/src/database.rs | 9 ++ slasher/src/error.rs | 2 + testing/remote_signer_test/src/utils.rs | 7 +- validator_client/Cargo.toml | 1 + .../slashing_protection/Cargo.toml | 1 + .../slashing_protection/src/lib.rs | 1 + .../src/slashing_database.rs | 22 +--- validator_client/src/key_cache.rs | 5 +- 20 files changed, 283 insertions(+), 100 deletions(-) create mode 100644 common/filesystem/Cargo.toml create mode 100644 common/filesystem/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 10dfc69b042..2b89514309c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,6 +21,7 @@ dependencies = [ "eth2_ssz_derive", "eth2_wallet", "eth2_wallet_manager", + "filesystem", "futures 0.3.13", "hex", "libc", @@ -45,6 +46,7 @@ dependencies = [ "directory", "eth2_keystore", "eth2_wallet", + "filesystem", "rand 0.7.3", "regex", "rpassword", @@ -986,7 +988,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" dependencies = [ - "rustc_version", + "rustc_version 0.2.3", ] [[package]] @@ -2245,6 +2247,36 @@ dependencies = [ "subtle 2.4.0", ] +[[package]] +name = "field-offset" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf539fba70056b50f40a22e0da30639518a12ee18c35807858a63b158cb6dde7" +dependencies = [ + "memoffset", + "rustc_version 0.3.3", +] + +[[package]] +name = "filepath" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd50318458226958db06f173610f54f01d26f0a9ccfa3d38bd60f70bc9939ff" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "filesystem" +version = "0.1.0" +dependencies = [ + "clap", + "filepath", + "winapi 0.3.9", + "windows-acl", +] + [[package]] name = "fixed-hash" version = "0.6.1" @@ -4498,6 +4530,15 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + [[package]] name = "petgraph" version = "0.5.1" @@ -4752,7 +4793,7 @@ dependencies = [ "byteorder", "libc", "nom", - "rustc_version", + "rustc_version 0.2.3", ] [[package]] @@ -5353,7 +5394,16 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" dependencies = [ - "semver", + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", ] [[package]] @@ -5520,7 +5570,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser", + "semver-parser 0.7.0", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser 0.10.2", ] [[package]] @@ -5529,6 +5588,15 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + [[package]] name = "serde" version = "1.0.124" @@ -5769,6 +5837,7 @@ dependencies = [ "byteorder", "eth2_ssz", "eth2_ssz_derive", + "filesystem", "flate2", "lazy_static", "lighthouse_metrics", @@ -5811,6 +5880,7 @@ dependencies = [ name = "slashing_protection" version = "0.1.0" dependencies = [ + "filesystem", "parking_lot", "r2d2", "r2d2_sqlite", @@ -5964,7 +6034,7 @@ dependencies = [ "rand 0.7.3", "rand_core 0.5.1", "ring", - "rustc_version", + "rustc_version 0.2.3", "sha2 0.9.3", "subtle 2.4.0", "x25519-dalek", @@ -6070,7 +6140,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" dependencies = [ "discard", - "rustc_version", + "rustc_version 0.2.3", "stdweb-derive", "stdweb-internal-macros", "stdweb-internal-runtime", @@ -6910,6 +6980,12 @@ dependencies = [ "tree_hash_derive", ] +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + [[package]] name = "uint" version = "0.8.5" @@ -7065,6 +7141,7 @@ dependencies = [ "eth2_ssz_derive", "exit-future", "fallback", + "filesystem", "futures 0.3.13", "hex", "hyper 0.14.4", @@ -7108,6 +7185,7 @@ dependencies = [ "deposit_contract", "derivative", "eth2_keystore", + "filesystem", "hex", "lockfile", "rand 0.7.3", @@ -7432,6 +7510,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "widestring" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" + [[package]] name = "winapi" version = "0.2.8" @@ -7475,6 +7559,18 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-acl" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177b1723986bcb4c606058e77f6e8614b51c7f9ad2face6f6fd63dd5c8b3cec3" +dependencies = [ + "field-offset", + "libc", + "widestring", + "winapi 0.3.9", +] + [[package]] name = "winreg" version = "0.7.0" diff --git a/account_manager/Cargo.toml b/account_manager/Cargo.toml index 93b06c18aee..054027dbb78 100644 --- a/account_manager/Cargo.toml +++ b/account_manager/Cargo.toml @@ -34,6 +34,7 @@ slashing_protection = { path = "../validator_client/slashing_protection" } eth2 = {path = "../common/eth2"} safe_arith = {path = "../consensus/safe_arith"} slot_clock = { path = "../common/slot_clock" } +filesystem = { path = "../common/filesystem" } [dev-dependencies] tempfile = "3.1.0" diff --git a/account_manager/src/validator/create.rs b/account_manager/src/validator/create.rs index 7960c55baee..16e9c9f03fc 100644 --- a/account_manager/src/validator/create.rs +++ b/account_manager/src/validator/create.rs @@ -1,4 +1,5 @@ use crate::common::read_wallet_name_from_cli; +#[cfg(unix)] use crate::wallet::create::STDIN_INPUTS_FLAG; use crate::{SECRETS_DIR_FLAG, WALLETS_DIR_FLAG}; use account_utils::{ @@ -27,7 +28,7 @@ pub const AT_MOST_FLAG: &str = "at-most"; pub const WALLET_PASSWORD_PROMPT: &str = "Enter your wallet's password:"; pub fn cli_app<'a, 'b>() -> App<'a, 'b> { - App::new(CMD) + let mut cli = App::new(CMD) .about( "Creates new validators from an existing EIP-2386 wallet using the EIP-2333 HD key \ derivation scheme.", @@ -102,12 +103,17 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { ) .conflicts_with("count") .takes_value(true), - ) - .arg( + ); + + #[cfg(unix)] + { + cli = cli.arg( Arg::with_name(STDIN_INPUTS_FLAG) .long(STDIN_INPUTS_FLAG) .help("If present, read all user inputs from stdin instead of tty."), - ) + ); + } + cli } pub fn cli_run( @@ -118,7 +124,12 @@ pub fn cli_run( let spec = env.core_context().eth2_config.spec; let name: Option = clap_utils::parse_optional(matches, WALLET_NAME_FLAG)?; + + #[cfg(unix)] let stdin_inputs = matches.is_present(STDIN_INPUTS_FLAG); + #[cfg(windows)] + let stdin_inputs = true; + let wallet_base_dir = if matches.value_of("datadir").is_some() { let path: PathBuf = clap_utils::parse_required(matches, "datadir")?; path.join(DEFAULT_WALLET_DIR) diff --git a/account_manager/src/wallet/create.rs b/account_manager/src/wallet/create.rs index 3965443cdf7..c5d5919bba0 100644 --- a/account_manager/src/wallet/create.rs +++ b/account_manager/src/wallet/create.rs @@ -11,9 +11,7 @@ use eth2_wallet::{ use eth2_wallet_manager::{LockedWallet, WalletManager, WalletType}; use std::ffi::OsStr; use std::fs; -use std::fs::File; -use std::io::prelude::*; -use std::os::unix::fs::PermissionsExt; +use filesystem::create_with_600_perms; use std::path::{Path, PathBuf}; pub const CMD: &str = "create"; @@ -36,7 +34,7 @@ pub const NEW_WALLET_PASSWORD_PROMPT: &str = pub const RETYPE_PASSWORD_PROMPT: &str = "Please re-enter your wallet's new password:"; pub fn cli_app<'a, 'b>() -> App<'a, 'b> { - App::new(CMD) + let mut cli = App::new(CMD) .about("Creates a new HD (hierarchical-deterministic) EIP-2386 wallet.") .arg( Arg::with_name(NAME_FLAG) @@ -81,11 +79,6 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { ) .takes_value(true) ) - .arg( - Arg::with_name(STDIN_INPUTS_FLAG) - .long(STDIN_INPUTS_FLAG) - .help("If present, read all user inputs from stdin instead of tty."), - ) .arg( Arg::with_name(MNEMONIC_LENGTH_FLAG) .long(MNEMONIC_LENGTH_FLAG) @@ -99,7 +92,16 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { } }) .default_value("24"), - ) + ); + #[cfg(unix)] + { + cli = cli.arg( + Arg::with_name(STDIN_INPUTS_FLAG) + .long(STDIN_INPUTS_FLAG) + .help("If present, read all user inputs from stdin instead of tty."), + ); + } + cli } pub fn cli_run(matches: &ArgMatches, wallet_base_dir: PathBuf) -> Result<(), String> { @@ -153,7 +155,11 @@ pub fn create_wallet_from_mnemonic( let name: Option = clap_utils::parse_optional(matches, NAME_FLAG)?; let wallet_password_path: Option = clap_utils::parse_optional(matches, PASSWORD_FLAG)?; let type_field: String = clap_utils::parse_required(matches, TYPE_FLAG)?; + + #[cfg(unix)] let stdin_inputs = matches.is_present(STDIN_INPUTS_FLAG); + #[cfg(windows)] + let stdin_inputs = true; let wallet_type = match type_field.as_ref() { HD_TYPE => WalletType::Hd, @@ -238,25 +244,3 @@ pub fn read_new_wallet_password_from_cli( } } -/// Creates a file with `600 (-rw-------)` permissions. -pub fn create_with_600_perms>(path: P, bytes: &[u8]) -> Result<(), String> { - let path = path.as_ref(); - - let mut file = - File::create(&path).map_err(|e| format!("Unable to create {:?}: {}", path, e))?; - - let mut perm = file - .metadata() - .map_err(|e| format!("Unable to get {:?} metadata: {}", path, e))? - .permissions(); - - perm.set_mode(0o600); - - file.set_permissions(perm) - .map_err(|e| format!("Unable to set {:?} permissions: {}", path, e))?; - - file.write_all(bytes) - .map_err(|e| format!("Unable to write to {:?}: {}", path, e))?; - - Ok(()) -} diff --git a/common/account_utils/Cargo.toml b/common/account_utils/Cargo.toml index 1b7580ded44..91a31e39534 100644 --- a/common/account_utils/Cargo.toml +++ b/common/account_utils/Cargo.toml @@ -10,6 +10,7 @@ edition = "2018" rand = "0.7.3" eth2_wallet = { path = "../../crypto/eth2_wallet" } eth2_keystore = { path = "../../crypto/eth2_keystore" } +filesystem = { path = "../filesystem" } zeroize = { version = "1.1.1", features = ["zeroize_derive"] } serde = "1.0.116" serde_derive = "1.0.116" diff --git a/common/account_utils/src/lib.rs b/common/account_utils/src/lib.rs index 1ec15fa4e23..1fa411e4907 100644 --- a/common/account_utils/src/lib.rs +++ b/common/account_utils/src/lib.rs @@ -11,7 +11,6 @@ use serde_derive::{Deserialize, Serialize}; use std::fs::{self, File}; use std::io; use std::io::prelude::*; -use std::os::unix::fs::PermissionsExt; use std::path::{Path, PathBuf}; use zeroize::Zeroize; @@ -59,23 +58,6 @@ pub fn read_password>(path: P) -> Result { fs::read(path).map(strip_off_newlines).map(Into::into) } -/// Creates a file with `600 (-rw-------)` permissions. -pub fn create_with_600_perms>(path: P, bytes: &[u8]) -> Result<(), io::Error> { - let path = path.as_ref(); - - let mut file = File::create(&path)?; - - let mut perm = file.metadata()?.permissions(); - - perm.set_mode(0o600); - - file.set_permissions(perm)?; - - file.write_all(bytes)?; - - Ok(()) -} - /// Generates a random alphanumeric password of length `DEFAULT_PASSWORD_LEN`. pub fn random_password() -> PlainText { rand::thread_rng() diff --git a/common/account_utils/src/validator_definitions.rs b/common/account_utils/src/validator_definitions.rs index 466349cf95b..8e4e9bed3d7 100644 --- a/common/account_utils/src/validator_definitions.rs +++ b/common/account_utils/src/validator_definitions.rs @@ -3,7 +3,8 @@ //! Serves as the source-of-truth of which validators this validator client should attempt (or not //! attempt) to load into the `crate::intialized_validators::InitializedValidators` struct. -use crate::{create_with_600_perms, default_keystore_password_path, ZeroizeString}; +use crate::{default_keystore_password_path, ZeroizeString}; +use filesystem::{create_with_600_perms, Error as fsError}; use directory::ensure_dir_exists; use eth2_keystore::Keystore; use regex::Regex; @@ -31,6 +32,8 @@ pub enum Error { UnableToEncodeFile(serde_yaml::Error), /// The config file could not be written to the filesystem. UnableToWriteFile(io::Error), + /// The config file could not be created + UnableToCreateFile(fsError), /// The public key from the keystore is invalid. InvalidKeystorePubkey, /// The keystore was unable to be opened. @@ -260,7 +263,7 @@ impl ValidatorDefinitions { if config_path.exists() { fs::write(config_path, &bytes).map_err(Error::UnableToWriteFile) } else { - create_with_600_perms(&config_path, &bytes).map_err(Error::UnableToWriteFile) + create_with_600_perms(&config_path, &bytes).map_err(|e| Error::UnableToCreateFile(e)) } } diff --git a/common/filesystem/Cargo.toml b/common/filesystem/Cargo.toml new file mode 100644 index 00000000000..159e5ad268b --- /dev/null +++ b/common/filesystem/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "filesystem" +version = "0.1.0" +authors = ["Mark Mackey "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clap = "2.33.3" +winapi = "~0.3.5" +windows-acl = "~0.3.0" +filepath = "~0.1.1" diff --git a/common/filesystem/src/lib.rs b/common/filesystem/src/lib.rs new file mode 100644 index 00000000000..aa9b572e515 --- /dev/null +++ b/common/filesystem/src/lib.rs @@ -0,0 +1,98 @@ +use std::fs::File; +use std::io; +use std::io::Write; +use std::path::Path; + +#[derive(Debug)] +pub enum Error { + /// The file could not be created + UnableToCreateFile(io::Error), + /// The file could not be opened + UnableToOpenFile(io::Error), + /// Failed to set permissions + UnableToSetPermissions(io::Error), + /// Failed to retrieve file metadata + UnableToRetrieveMetadata(io::Error), + /// Failed to write bytes to file + UnableToWriteFile(io::Error), + /// Failed to obtain file path + UnableToObtainFilePath, + /// Failed to retrieve ACL for file + UnableToRetrieveACL(u32), + /// Failed to enumerate ACL entries + UnableToEnumerateACLEntries(u32), + /// Failed to add new ACL entry + UnableToAddACLEntry(String), + /// Failed to remove ACL entry + UnableToRemoveACLEntry(String) +} + +/// Creates a file with `600 (-rw-------)` permissions. +pub fn create_with_600_perms>(path: P, bytes: &[u8]) -> Result<(), Error> { + let path = path.as_ref(); + let mut file = File::create(&path).map_err(|e| Error::UnableToCreateFile(e))?; + + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + let mut perm = file.metadata().map_err(Error::UnableToRetrieveMetadata)?.permissions(); + + perm.set_mode(0o600); + + file.set_permissions(perm).map_err(|e| Error::UnableToSetPermissions(e))?; + } + + file.write_all(bytes).map_err(|e| Error::UnableToWriteFile(e))?; + #[cfg(windows)] + { + restrict_file_permissions(path)?; + } + + Ok(()) +} + +pub fn restrict_file_permissions>(path: P) -> Result<(), Error> { + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + let file = File::open(path.as_ref()).map_err(Error::UnableToOpenFile)?; + let mut perm = file.metadata().map_err(Error::UnableToRetrieveMetadata)?.permissions(); + perm.set_mode(0o600); + file.set_permissions(perm).map_err(|e| Error::UnableToSetPermissions(e))?; + } + + #[cfg(windows)] + { + use winapi::um::winnt::PSID; + use windows_acl::acl::{ + ACL, AceType, + }; + use windows_acl::helper::sid_to_string; + + let path_str = path.as_ref().to_str().ok_or(Error::UnableToObtainFilePath)?; + let mut acl = ACL::from_file_path(&path_str, false).map_err(|e| Error::UnableToRetrieveACL(e))?; + + let owner_sid_str = "S-1-3-4"; + let owner_sid = windows_acl::helper::string_to_sid(owner_sid_str).unwrap(); + + let entries = acl.all().map_err(|e| Error::UnableToEnumerateACLEntries(e))?; + + // add single entry for file owner + acl.add_entry(owner_sid.as_ptr() as PSID, AceType::AccessAllow, 0, 0x1f01ff).map_err(|code| Error::UnableToAddACLEntry(format!("Failed to add ACL entry for SID {} error={}", owner_sid_str, code)))?; + // remove all AccessAllow entries from the file that aren't the owner_sid + for entry in &entries { + if let Some(ref entry_sid) = entry.sid { + let entry_sid_str = sid_to_string((*entry_sid).as_ptr() as PSID).unwrap_or_else( + |_| "BadFormat".to_string() + ); + if entry_sid_str != owner_sid_str { + acl.remove((*entry_sid).as_ptr() as PSID, Some(AceType::AccessAllow), None).map_err(|_| Error::UnableToRemoveACLEntry(format!("Failed to remove ACL entry for SID {}", entry_sid_str)))?; + } + } + } + } + + Ok(()) +} + + diff --git a/common/validator_dir/Cargo.toml b/common/validator_dir/Cargo.toml index f993197c6a9..eb6a4e9e432 100644 --- a/common/validator_dir/Cargo.toml +++ b/common/validator_dir/Cargo.toml @@ -12,6 +12,7 @@ insecure_keys = [] [dependencies] bls = { path = "../../crypto/bls" } eth2_keystore = { path = "../../crypto/eth2_keystore" } +filesystem = { path = "../filesystem" } types = { path = "../../consensus/types" } rand = "0.7.3" deposit_contract = { path = "../deposit_contract" } diff --git a/common/validator_dir/src/builder.rs b/common/validator_dir/src/builder.rs index 70cb13ae99b..37b630f74ef 100644 --- a/common/validator_dir/src/builder.rs +++ b/common/validator_dir/src/builder.rs @@ -3,11 +3,11 @@ use bls::get_withdrawal_credentials; use deposit_contract::{encode_eth1_tx_data, Error as DepositError}; use eth2_keystore::{Error as KeystoreError, Keystore, KeystoreBuilder, PlainText}; use rand::{distributions::Alphanumeric, Rng}; -use std::fs::{create_dir_all, File, OpenOptions}; +use std::fs::{create_dir_all, OpenOptions}; use std::io::{self, Write}; -use std::os::unix::fs::PermissionsExt; use std::path::{Path, PathBuf}; use types::{ChainSpec, DepositData, Hash256, Keypair, Signature}; +use filesystem::{Error as fsError, create_with_600_perms}; /// The `Alphanumeric` crate only generates a-z, A-Z, 0-9, therefore it has a range of 62 /// characters. @@ -33,7 +33,7 @@ pub enum Error { KeystoreAlreadyExists(PathBuf), UnableToSaveKeystore(io::Error), PasswordAlreadyExists(PathBuf), - UnableToSavePassword(io::Error), + UnableToSavePassword(fsError), KeystoreError(KeystoreError), UnableToOpenDir(DirError), UninitializedVotingKeystore, @@ -283,19 +283,7 @@ pub fn write_password_to_file>(path: P, bytes: &[u8]) -> Result<( return Err(Error::PasswordAlreadyExists(path.into())); } - let mut file = File::create(&path).map_err(Error::UnableToSavePassword)?; - - let mut perm = file - .metadata() - .map_err(Error::UnableToSavePassword)? - .permissions(); - - perm.set_mode(0o600); - - file.set_permissions(perm) - .map_err(Error::UnableToSavePassword)?; - - file.write_all(bytes).map_err(Error::UnableToSavePassword)?; + create_with_600_perms(path, bytes).map_err(|e| Error::UnableToSavePassword(e))?; Ok(()) } diff --git a/slasher/Cargo.toml b/slasher/Cargo.toml index aa1f85006ee..3e6461e783d 100644 --- a/slasher/Cargo.toml +++ b/slasher/Cargo.toml @@ -12,6 +12,7 @@ eth2_ssz_derive = { path = "../consensus/ssz_derive" } flate2 = { version = "1.0.14", features = ["zlib"], default-features = false } lazy_static = "1.4.0" lighthouse_metrics = { path = "../common/lighthouse_metrics" } +filesystem = { path = "../common/filesystem" } lmdb = "0.8" lmdb-sys = "0.8" parking_lot = "0.11.0" diff --git a/slasher/src/database.rs b/slasher/src/database.rs index 8f1c97aa4ee..9eb2e47e751 100644 --- a/slasher/src/database.rs +++ b/slasher/src/database.rs @@ -195,6 +195,15 @@ impl SlasherDB { let proposers_db = env.create_db(Some(PROPOSERS_DB), Self::db_flags())?; let metadata_db = env.create_db(Some(METADATA_DB), Self::db_flags())?; + #[cfg(windows)] + { + use filesystem::restrict_file_permissions; + let mut data = config.database_path.clone(); data.push("data.mdb"); + let mut lock = config.database_path.clone(); lock.push("lock.mdb"); + restrict_file_permissions(data).or_else(|e| { println!("Error setting permissions for slasher db: {:?}", e); Err(e)}).map_err(Error::DatabasePermissionsError)?; + restrict_file_permissions(lock).or_else(|e| { println!("Error setting permissions for slasher db: {:?}", e); Err(e)}).map_err(Error::DatabasePermissionsError)?; + } + let db = Self { env, indexed_attestation_db, diff --git a/slasher/src/error.rs b/slasher/src/error.rs index 97b3f8cd05f..3077dd07373 100644 --- a/slasher/src/error.rs +++ b/slasher/src/error.rs @@ -1,11 +1,13 @@ use crate::Config; use std::io; use types::{Epoch, Hash256}; +use filesystem::Error as fsError; #[derive(Debug)] pub enum Error { DatabaseError(lmdb::Error), DatabaseIOError(io::Error), + DatabasePermissionsError(fsError), SszDecodeError(ssz::DecodeError), BincodeError(bincode::Error), ArithError(safe_arith::ArithError), diff --git a/testing/remote_signer_test/src/utils.rs b/testing/remote_signer_test/src/utils.rs index 858f4d60244..498a413e246 100644 --- a/testing/remote_signer_test/src/utils.rs +++ b/testing/remote_signer_test/src/utils.rs @@ -5,12 +5,11 @@ pub use local_signer_test_data::*; pub use mock::*; use remote_signer_client::Client; pub use remote_signer_test_data::*; -use std::fs; use std::fs::{create_dir, File}; use std::io::Write; use std::net::IpAddr::{V4, V6}; +#[cfg(unix)] use std::os::unix::fs::PermissionsExt; -use std::path::Path; use tempfile::TempDir; use types::{ AggregateSignature, Attestation, AttestationData, AttesterSlashing, BeaconBlock, @@ -29,7 +28,11 @@ pub fn get_address(client: &Client) -> String { format!("http://{}:{}", ip, listening_address.port()) } +#[cfg(unix)] pub fn set_permissions(path: &Path, perm_octal: u32) { + use std::path::Path; + use std::fs; + let metadata = fs::metadata(path).unwrap(); let mut permissions = metadata.permissions(); permissions.set_mode(perm_octal); diff --git a/validator_client/Cargo.toml b/validator_client/Cargo.toml index 30b3ce29b40..901e48b7deb 100644 --- a/validator_client/Cargo.toml +++ b/validator_client/Cargo.toml @@ -39,6 +39,7 @@ logging = { path = "../common/logging" } environment = { path = "../lighthouse/environment" } parking_lot = "0.11.0" exit-future = "0.2.0" +filesystem = { path = "../common/filesystem" } libc = "0.2.79" eth2_ssz_derive = "0.1.0" hex = "0.4.2" diff --git a/validator_client/slashing_protection/Cargo.toml b/validator_client/slashing_protection/Cargo.toml index a1abb855631..655d58b1f27 100644 --- a/validator_client/slashing_protection/Cargo.toml +++ b/validator_client/slashing_protection/Cargo.toml @@ -16,6 +16,7 @@ serde = "1.0.116" serde_derive = "1.0.116" serde_json = "1.0.58" serde_utils = { path = "../../consensus/serde_utils" } +filesystem = { path = "../../common/filesystem" } [dev-dependencies] rayon = "1.4.1" diff --git a/validator_client/slashing_protection/src/lib.rs b/validator_client/slashing_protection/src/lib.rs index 8f6bdb50e9e..ed93b346a7a 100644 --- a/validator_client/slashing_protection/src/lib.rs +++ b/validator_client/slashing_protection/src/lib.rs @@ -30,6 +30,7 @@ pub enum NotSafe { UnregisteredValidator(PublicKeyBytes), InvalidBlock(InvalidBlock), InvalidAttestation(InvalidAttestation), + PermissionsError, IOError(ErrorKind), SQLError(String), SQLPoolError(String), diff --git a/validator_client/slashing_protection/src/slashing_database.rs b/validator_client/slashing_protection/src/slashing_database.rs index 79bcec7a93d..beeb8ccb0e0 100644 --- a/validator_client/slashing_protection/src/slashing_database.rs +++ b/validator_client/slashing_protection/src/slashing_database.rs @@ -7,10 +7,11 @@ use crate::signed_block::InvalidBlock; use crate::{hash256_from_row, NotSafe, Safe, SignedAttestation, SignedBlock, SigningRoot}; use r2d2_sqlite::SqliteConnectionManager; use rusqlite::{params, OptionalExtension, Transaction, TransactionBehavior}; -use std::fs::{File, OpenOptions}; +use std::fs::OpenOptions; use std::path::Path; use std::time::Duration; use types::{AttestationData, BeaconBlockHeader, Epoch, Hash256, PublicKeyBytes, SignedRoot, Slot}; +use filesystem::restrict_file_permissions; type Pool = r2d2::Pool; @@ -46,13 +47,13 @@ impl SlashingDatabase { /// /// Error if a database (or any file) already exists at `path`. pub fn create(path: &Path) -> Result { - let file = OpenOptions::new() + let _file = OpenOptions::new() .write(true) .read(true) .create_new(true) .open(path)?; - Self::set_db_file_permissions(&file)?; + restrict_file_permissions(path).map_err(|_| NotSafe::PermissionsError)?; let conn_pool = Self::open_conn_pool(path)?; let conn = conn_pool.get()?; @@ -121,21 +122,6 @@ impl SlashingDatabase { Ok(()) } - /// Set the database file to readable and writable only by its owner (0600). - #[cfg(unix)] - fn set_db_file_permissions(file: &File) -> Result<(), NotSafe> { - use std::os::unix::fs::PermissionsExt; - - let mut perm = file.metadata()?.permissions(); - perm.set_mode(0o600); - file.set_permissions(perm)?; - Ok(()) - } - - // TODO: add support for Windows ACLs - #[cfg(windows)] - fn set_db_file_permissions(file: &File) -> Result<(), NotSafe> {} - /// Creates an empty transaction and drops it. Used to test whether the database is locked. pub fn test_transaction(&self) -> Result<(), NotSafe> { let mut conn = self.conn_pool.get()?; diff --git a/validator_client/src/key_cache.rs b/validator_client/src/key_cache.rs index 6da06aaa1b2..1eba296b120 100644 --- a/validator_client/src/key_cache.rs +++ b/validator_client/src/key_cache.rs @@ -1,4 +1,4 @@ -use account_utils::create_with_600_perms; +use filesystem::{create_with_600_perms, Error as fsError}; use bls::{Keypair, PublicKey}; use eth2_keystore::json_keystore::{ Aes128Ctr, ChecksumModule, Cipher, CipherModule, Crypto, EmptyMap, EmptyString, KdfModule, @@ -144,7 +144,7 @@ impl KeyCache { let res = if cache_path.exists() { fs::write(cache_path, &bytes).map_err(Error::UnableToWriteFile) } else { - create_with_600_perms(&cache_path, &bytes).map_err(Error::UnableToWriteFile) + create_with_600_perms(&cache_path, &bytes).map_err(Error::UnableToCreateFile) }; if res.is_ok() { self.state = State::DecryptedAndSaved; @@ -245,6 +245,7 @@ pub enum Error { UnableToEncodeFile(serde_json::Error), /// The cache file could not be written to the filesystem. UnableToWriteFile(io::Error), + UnableToCreateFile(fsError), /// Couldn't decrypt the cache file UnableToDecrypt(KeystoreError), UnableToEncrypt(KeystoreError), From 0a796db2c64896afae4a219334a3279db4c34adb Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 5 May 2021 15:36:10 -0400 Subject: [PATCH 02/32] Cleaned up command line args for windows --- account_manager/src/validator/create.rs | 21 ++++++++++---------- account_manager/src/validator/exit.rs | 10 ++++++++++ account_manager/src/validator/import.rs | 10 ++++++++++ account_manager/src/validator/recover.rs | 10 ++++++++++ account_manager/src/wallet/create.rs | 25 +++++++++++++----------- account_manager/src/wallet/recover.rs | 10 ++++++++++ 6 files changed, 65 insertions(+), 21 deletions(-) diff --git a/account_manager/src/validator/create.rs b/account_manager/src/validator/create.rs index 16e9c9f03fc..8aa25d85092 100644 --- a/account_manager/src/validator/create.rs +++ b/account_manager/src/validator/create.rs @@ -1,5 +1,4 @@ use crate::common::read_wallet_name_from_cli; -#[cfg(unix)] use crate::wallet::create::STDIN_INPUTS_FLAG; use crate::{SECRETS_DIR_FLAG, WALLETS_DIR_FLAG}; use account_utils::{ @@ -28,7 +27,12 @@ pub const AT_MOST_FLAG: &str = "at-most"; pub const WALLET_PASSWORD_PROMPT: &str = "Enter your wallet's password:"; pub fn cli_app<'a, 'b>() -> App<'a, 'b> { - let mut cli = App::new(CMD) + #[cfg(unix)] + let windows = false; + #[cfg(windows)] + let windows = true; + + App::new(CMD) .about( "Creates new validators from an existing EIP-2386 wallet using the EIP-2333 HD key \ derivation scheme.", @@ -103,17 +107,14 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { ) .conflicts_with("count") .takes_value(true), - ); - - #[cfg(unix)] - { - cli = cli.arg( + ) + .arg( Arg::with_name(STDIN_INPUTS_FLAG) + .takes_value(false) + .hidden(windows) .long(STDIN_INPUTS_FLAG) .help("If present, read all user inputs from stdin instead of tty."), - ); - } - cli + ) } pub fn cli_run( diff --git a/account_manager/src/validator/exit.rs b/account_manager/src/validator/exit.rs index 66fb21dd5d7..f96a834b67c 100644 --- a/account_manager/src/validator/exit.rs +++ b/account_manager/src/validator/exit.rs @@ -27,6 +27,11 @@ pub const WEBSITE_URL: &str = "https://lighthouse-book.sigmaprime.io/voluntary-e pub const PROMPT: &str = "WARNING: WITHDRAWING STAKED ETH IS NOT CURRENTLY POSSIBLE"; pub fn cli_app<'a, 'b>() -> App<'a, 'b> { + #[cfg(unix)] + let windows = false; + #[cfg(windows)] + let windows = true; + App::new("exit") .about("Submits a VoluntaryExit to the beacon chain for a given validator keystore.") .arg( @@ -54,6 +59,8 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { ) .arg( Arg::with_name(STDIN_INPUTS_FLAG) + .takes_value(false) + .hidden(windows) .long(STDIN_INPUTS_FLAG) .help("If present, read all user inputs from stdin instead of tty."), ) @@ -63,7 +70,10 @@ pub fn cli_run(matches: &ArgMatches, env: Environment) -> Result< let keystore_path: PathBuf = clap_utils::parse_required(matches, KEYSTORE_FLAG)?; let password_file_path: Option = clap_utils::parse_optional(matches, PASSWORD_FILE_FLAG)?; + #[cfg(unix)] let stdin_inputs = matches.is_present(STDIN_INPUTS_FLAG); + #[cfg(windows)] + let stdin_inputs = true; let spec = env.eth2_config().spec.clone(); let server_url: String = clap_utils::parse_required(matches, BEACON_SERVER_FLAG)?; diff --git a/account_manager/src/validator/import.rs b/account_manager/src/validator/import.rs index 7ce73076c9f..6356fc0c611 100644 --- a/account_manager/src/validator/import.rs +++ b/account_manager/src/validator/import.rs @@ -25,6 +25,11 @@ pub const KEYSTORE_REUSE_WARNING: &str = "DO NOT USE THE ORIGINAL KEYSTORES TO V ANOTHER CLIENT, OR YOU WILL GET SLASHED."; pub fn cli_app<'a, 'b>() -> App<'a, 'b> { + #[cfg(unix)] + let windows = false; + #[cfg(windows)] + let windows = true; + App::new(CMD) .about( "Imports one or more EIP-2335 passwords into a Lighthouse VC directory, \ @@ -57,6 +62,8 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { ) .arg( Arg::with_name(STDIN_INPUTS_FLAG) + .takes_value(false) + .hidden(windows) .long(STDIN_INPUTS_FLAG) .help("If present, read all user inputs from stdin instead of tty."), ) @@ -83,7 +90,10 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), String> { let keystore: Option = clap_utils::parse_optional(matches, KEYSTORE_FLAG)?; let keystores_dir: Option = clap_utils::parse_optional(matches, DIR_FLAG)?; + #[cfg(unix)] let stdin_inputs = matches.is_present(STDIN_INPUTS_FLAG); + #[cfg(windows)] + let stdin_inputs = true; let reuse_password = matches.is_present(REUSE_PASSWORD_FLAG); let keystore_password_path: Option = clap_utils::parse_optional(matches, PASSWORD_FLAG)?; diff --git a/account_manager/src/validator/recover.rs b/account_manager/src/validator/recover.rs index 27d8aa71d4f..427bbef7da8 100644 --- a/account_manager/src/validator/recover.rs +++ b/account_manager/src/validator/recover.rs @@ -17,6 +17,11 @@ pub const FIRST_INDEX_FLAG: &str = "first-index"; pub const MNEMONIC_FLAG: &str = "mnemonic-path"; pub fn cli_app<'a, 'b>() -> App<'a, 'b> { + #[cfg(unix)] + let windows = false; + #[cfg(windows)] + let windows = true; + App::new(CMD) .about( "Recovers validator private keys given a BIP-39 mnemonic phrase. \ @@ -71,6 +76,8 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { ) .arg( Arg::with_name(STDIN_INPUTS_FLAG) + .takes_value(false) + .hidden(windows) .long(STDIN_INPUTS_FLAG) .help("If present, read all user inputs from stdin instead of tty."), ) @@ -86,7 +93,10 @@ pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), Strin let first_index: u32 = clap_utils::parse_required(matches, FIRST_INDEX_FLAG)?; let count: u32 = clap_utils::parse_required(matches, COUNT_FLAG)?; let mnemonic_path: Option = clap_utils::parse_optional(matches, MNEMONIC_FLAG)?; + #[cfg(unix)] let stdin_inputs = matches.is_present(STDIN_INPUTS_FLAG); + #[cfg(windows)] + let stdin_inputs = true; eprintln!("secrets-dir path: {:?}", secrets_dir); diff --git a/account_manager/src/wallet/create.rs b/account_manager/src/wallet/create.rs index c5d5919bba0..7b31481cbac 100644 --- a/account_manager/src/wallet/create.rs +++ b/account_manager/src/wallet/create.rs @@ -34,7 +34,12 @@ pub const NEW_WALLET_PASSWORD_PROMPT: &str = pub const RETYPE_PASSWORD_PROMPT: &str = "Please re-enter your wallet's new password:"; pub fn cli_app<'a, 'b>() -> App<'a, 'b> { - let mut cli = App::new(CMD) + #[cfg(unix)] + let windows = false; + #[cfg(windows)] + let windows = true; + + App::new(CMD) .about("Creates a new HD (hierarchical-deterministic) EIP-2386 wallet.") .arg( Arg::with_name(NAME_FLAG) @@ -79,6 +84,13 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { ) .takes_value(true) ) + .arg( + Arg::with_name(STDIN_INPUTS_FLAG) + .takes_value(false) + .hidden(windows) + .long(STDIN_INPUTS_FLAG) + .help("If present, read all user inputs from stdin instead of tty."), + ) .arg( Arg::with_name(MNEMONIC_LENGTH_FLAG) .long(MNEMONIC_LENGTH_FLAG) @@ -92,16 +104,7 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { } }) .default_value("24"), - ); - #[cfg(unix)] - { - cli = cli.arg( - Arg::with_name(STDIN_INPUTS_FLAG) - .long(STDIN_INPUTS_FLAG) - .help("If present, read all user inputs from stdin instead of tty."), - ); - } - cli + ) } pub fn cli_run(matches: &ArgMatches, wallet_base_dir: PathBuf) -> Result<(), String> { diff --git a/account_manager/src/wallet/recover.rs b/account_manager/src/wallet/recover.rs index 0ac30fe27ab..63efb666fd8 100644 --- a/account_manager/src/wallet/recover.rs +++ b/account_manager/src/wallet/recover.rs @@ -8,6 +8,11 @@ pub const CMD: &str = "recover"; pub const MNEMONIC_FLAG: &str = "mnemonic-path"; pub fn cli_app<'a, 'b>() -> App<'a, 'b> { + #[cfg(unix)] + let windows = false; + #[cfg(windows)] + let windows = true; + App::new(CMD) .about("Recovers an EIP-2386 wallet from a given a BIP-39 mnemonic phrase.") .arg( @@ -54,6 +59,8 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { ) .arg( Arg::with_name(STDIN_INPUTS_FLAG) + .takes_value(false) + .hidden(windows) .long(STDIN_INPUTS_FLAG) .help("If present, read all user inputs from stdin instead of tty."), ) @@ -61,7 +68,10 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { pub fn cli_run(matches: &ArgMatches, wallet_base_dir: PathBuf) -> Result<(), String> { let mnemonic_path: Option = clap_utils::parse_optional(matches, MNEMONIC_FLAG)?; + #[cfg(unix)] let stdin_inputs = matches.is_present(STDIN_INPUTS_FLAG); + #[cfg(windows)] + let stdin_inputs = true; eprintln!(); eprintln!("WARNING: KEY RECOVERY CAN LEAD TO DUPLICATING VALIDATORS KEYS, WHICH CAN LEAD TO SLASHING."); From c401368aeb4347baa225c887e80144165a4e34ba Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 5 May 2021 16:05:28 -0400 Subject: [PATCH 03/32] Cleaned up formatting --- account_manager/src/validator/exit.rs | 1 - account_manager/src/wallet/create.rs | 3 +- .../src/validator_definitions.rs | 2 +- common/filesystem/src/lib.rs | 73 +++++++++++++------ common/validator_dir/src/builder.rs | 2 +- slasher/src/database.rs | 20 ++++- slasher/src/error.rs | 2 +- testing/remote_signer_test/src/utils.rs | 2 +- .../src/slashing_database.rs | 2 +- validator_client/src/key_cache.rs | 2 +- 10 files changed, 74 insertions(+), 35 deletions(-) diff --git a/account_manager/src/validator/exit.rs b/account_manager/src/validator/exit.rs index 422f352b06e..906436df089 100644 --- a/account_manager/src/validator/exit.rs +++ b/account_manager/src/validator/exit.rs @@ -85,7 +85,6 @@ pub fn cli_run(matches: &ArgMatches, env: Environment) -> Result< let no_wait = matches.is_present(NO_WAIT); - let spec = env.eth2_config().spec.clone(); let server_url: String = clap_utils::parse_required(matches, BEACON_SERVER_FLAG)?; let client = BeaconNodeHttpClient::new( diff --git a/account_manager/src/wallet/create.rs b/account_manager/src/wallet/create.rs index 7b31481cbac..b23eedfa036 100644 --- a/account_manager/src/wallet/create.rs +++ b/account_manager/src/wallet/create.rs @@ -9,9 +9,9 @@ use eth2_wallet::{ PlainText, }; use eth2_wallet_manager::{LockedWallet, WalletManager, WalletType}; +use filesystem::create_with_600_perms; use std::ffi::OsStr; use std::fs; -use filesystem::create_with_600_perms; use std::path::{Path, PathBuf}; pub const CMD: &str = "create"; @@ -246,4 +246,3 @@ pub fn read_new_wallet_password_from_cli( }, } } - diff --git a/common/account_utils/src/validator_definitions.rs b/common/account_utils/src/validator_definitions.rs index 8e4e9bed3d7..e5910908454 100644 --- a/common/account_utils/src/validator_definitions.rs +++ b/common/account_utils/src/validator_definitions.rs @@ -4,9 +4,9 @@ //! attempt) to load into the `crate::intialized_validators::InitializedValidators` struct. use crate::{default_keystore_password_path, ZeroizeString}; -use filesystem::{create_with_600_perms, Error as fsError}; use directory::ensure_dir_exists; use eth2_keystore::Keystore; +use filesystem::{create_with_600_perms, Error as fsError}; use regex::Regex; use serde_derive::{Deserialize, Serialize}; use slog::{error, Logger}; diff --git a/common/filesystem/src/lib.rs b/common/filesystem/src/lib.rs index aa9b572e515..2fcd4f5aec9 100644 --- a/common/filesystem/src/lib.rs +++ b/common/filesystem/src/lib.rs @@ -24,7 +24,7 @@ pub enum Error { /// Failed to add new ACL entry UnableToAddACLEntry(String), /// Failed to remove ACL entry - UnableToRemoveACLEntry(String) + UnableToRemoveACLEntry(String), } /// Creates a file with `600 (-rw-------)` permissions. @@ -35,14 +35,17 @@ pub fn create_with_600_perms>(path: P, bytes: &[u8]) -> Result<() #[cfg(unix)] { use std::os::unix::fs::PermissionsExt; - let mut perm = file.metadata().map_err(Error::UnableToRetrieveMetadata)?.permissions(); - + let mut perm = file + .metadata() + .map_err(Error::UnableToRetrieveMetadata)? + .permissions(); perm.set_mode(0o600); - - file.set_permissions(perm).map_err(|e| Error::UnableToSetPermissions(e))?; + file.set_permissions(perm) + .map_err(|e| Error::UnableToSetPermissions(e))?; } - file.write_all(bytes).map_err(|e| Error::UnableToWriteFile(e))?; + file.write_all(bytes) + .map_err(|e| Error::UnableToWriteFile(e))?; #[cfg(windows)] { restrict_file_permissions(path)?; @@ -56,37 +59,65 @@ pub fn restrict_file_permissions>(path: P) -> Result<(), Error> { { use std::os::unix::fs::PermissionsExt; let file = File::open(path.as_ref()).map_err(Error::UnableToOpenFile)?; - let mut perm = file.metadata().map_err(Error::UnableToRetrieveMetadata)?.permissions(); + let mut perm = file + .metadata() + .map_err(Error::UnableToRetrieveMetadata)? + .permissions(); perm.set_mode(0o600); - file.set_permissions(perm).map_err(|e| Error::UnableToSetPermissions(e))?; + file.set_permissions(perm) + .map_err(|e| Error::UnableToSetPermissions(e))?; } #[cfg(windows)] { use winapi::um::winnt::PSID; - use windows_acl::acl::{ - ACL, AceType, - }; + use windows_acl::acl::{AceType, ACL}; use windows_acl::helper::sid_to_string; - let path_str = path.as_ref().to_str().ok_or(Error::UnableToObtainFilePath)?; - let mut acl = ACL::from_file_path(&path_str, false).map_err(|e| Error::UnableToRetrieveACL(e))?; + let path_str = path + .as_ref() + .to_str() + .ok_or(Error::UnableToObtainFilePath)?; + let mut acl = + ACL::from_file_path(&path_str, false).map_err(|e| Error::UnableToRetrieveACL(e))?; let owner_sid_str = "S-1-3-4"; - let owner_sid = windows_acl::helper::string_to_sid(owner_sid_str).unwrap(); + let owner_sid = windows_acl::helper::string_to_sid(owner_sid_str).unwrap(); - let entries = acl.all().map_err(|e| Error::UnableToEnumerateACLEntries(e))?; + let entries = acl + .all() + .map_err(|e| Error::UnableToEnumerateACLEntries(e))?; // add single entry for file owner - acl.add_entry(owner_sid.as_ptr() as PSID, AceType::AccessAllow, 0, 0x1f01ff).map_err(|code| Error::UnableToAddACLEntry(format!("Failed to add ACL entry for SID {} error={}", owner_sid_str, code)))?; + acl.add_entry( + owner_sid.as_ptr() as PSID, + AceType::AccessAllow, + 0, + 0x1f01ff, + ) + .map_err(|code| { + Error::UnableToAddACLEntry(format!( + "Failed to add ACL entry for SID {} error={}", + owner_sid_str, code + )) + })?; // remove all AccessAllow entries from the file that aren't the owner_sid for entry in &entries { if let Some(ref entry_sid) = entry.sid { - let entry_sid_str = sid_to_string((*entry_sid).as_ptr() as PSID).unwrap_or_else( - |_| "BadFormat".to_string() - ); + let entry_sid_str = sid_to_string((*entry_sid).as_ptr() as PSID) + .unwrap_or_else(|_| "BadFormat".to_string()); if entry_sid_str != owner_sid_str { - acl.remove((*entry_sid).as_ptr() as PSID, Some(AceType::AccessAllow), None).map_err(|_| Error::UnableToRemoveACLEntry(format!("Failed to remove ACL entry for SID {}", entry_sid_str)))?; + acl.remove( + (*entry_sid).as_ptr() as PSID, + Some(AceType::AccessAllow), + None, + ) + .map_err(|_| { + Error::UnableToRemoveACLEntry(format!( + "Failed to remove ACL entry for SID {}", + entry_sid_str + )) + })?; } } } @@ -94,5 +125,3 @@ pub fn restrict_file_permissions>(path: P) -> Result<(), Error> { Ok(()) } - - diff --git a/common/validator_dir/src/builder.rs b/common/validator_dir/src/builder.rs index 37b630f74ef..1a6602feef9 100644 --- a/common/validator_dir/src/builder.rs +++ b/common/validator_dir/src/builder.rs @@ -2,12 +2,12 @@ use crate::{Error as DirError, ValidatorDir}; use bls::get_withdrawal_credentials; use deposit_contract::{encode_eth1_tx_data, Error as DepositError}; use eth2_keystore::{Error as KeystoreError, Keystore, KeystoreBuilder, PlainText}; +use filesystem::{create_with_600_perms, Error as fsError}; use rand::{distributions::Alphanumeric, Rng}; use std::fs::{create_dir_all, OpenOptions}; use std::io::{self, Write}; use std::path::{Path, PathBuf}; use types::{ChainSpec, DepositData, Hash256, Keypair, Signature}; -use filesystem::{Error as fsError, create_with_600_perms}; /// The `Alphanumeric` crate only generates a-z, A-Z, 0-9, therefore it has a range of 62 /// characters. diff --git a/slasher/src/database.rs b/slasher/src/database.rs index 9eb2e47e751..fa655cb878a 100644 --- a/slasher/src/database.rs +++ b/slasher/src/database.rs @@ -198,10 +198,22 @@ impl SlasherDB { #[cfg(windows)] { use filesystem::restrict_file_permissions; - let mut data = config.database_path.clone(); data.push("data.mdb"); - let mut lock = config.database_path.clone(); lock.push("lock.mdb"); - restrict_file_permissions(data).or_else(|e| { println!("Error setting permissions for slasher db: {:?}", e); Err(e)}).map_err(Error::DatabasePermissionsError)?; - restrict_file_permissions(lock).or_else(|e| { println!("Error setting permissions for slasher db: {:?}", e); Err(e)}).map_err(Error::DatabasePermissionsError)?; + let mut data = config.database_path.clone(); + data.push("data.mdb"); + let mut lock = config.database_path.clone(); + lock.push("lock.mdb"); + restrict_file_permissions(data) + .or_else(|e| { + println!("Error setting permissions for slasher db: {:?}", e); + Err(e) + }) + .map_err(Error::DatabasePermissionsError)?; + restrict_file_permissions(lock) + .or_else(|e| { + println!("Error setting permissions for slasher db: {:?}", e); + Err(e) + }) + .map_err(Error::DatabasePermissionsError)?; } let db = Self { diff --git a/slasher/src/error.rs b/slasher/src/error.rs index 3077dd07373..6cfddf12ddd 100644 --- a/slasher/src/error.rs +++ b/slasher/src/error.rs @@ -1,7 +1,7 @@ use crate::Config; +use filesystem::Error as fsError; use std::io; use types::{Epoch, Hash256}; -use filesystem::Error as fsError; #[derive(Debug)] pub enum Error { diff --git a/testing/remote_signer_test/src/utils.rs b/testing/remote_signer_test/src/utils.rs index 498a413e246..387da44427f 100644 --- a/testing/remote_signer_test/src/utils.rs +++ b/testing/remote_signer_test/src/utils.rs @@ -30,8 +30,8 @@ pub fn get_address(client: &Client) -> String { #[cfg(unix)] pub fn set_permissions(path: &Path, perm_octal: u32) { - use std::path::Path; use std::fs; + use std::path::Path; let metadata = fs::metadata(path).unwrap(); let mut permissions = metadata.permissions(); diff --git a/validator_client/slashing_protection/src/slashing_database.rs b/validator_client/slashing_protection/src/slashing_database.rs index beeb8ccb0e0..23de7d30004 100644 --- a/validator_client/slashing_protection/src/slashing_database.rs +++ b/validator_client/slashing_protection/src/slashing_database.rs @@ -5,13 +5,13 @@ use crate::interchange::{ use crate::signed_attestation::InvalidAttestation; use crate::signed_block::InvalidBlock; use crate::{hash256_from_row, NotSafe, Safe, SignedAttestation, SignedBlock, SigningRoot}; +use filesystem::restrict_file_permissions; use r2d2_sqlite::SqliteConnectionManager; use rusqlite::{params, OptionalExtension, Transaction, TransactionBehavior}; use std::fs::OpenOptions; use std::path::Path; use std::time::Duration; use types::{AttestationData, BeaconBlockHeader, Epoch, Hash256, PublicKeyBytes, SignedRoot, Slot}; -use filesystem::restrict_file_permissions; type Pool = r2d2::Pool; diff --git a/validator_client/src/key_cache.rs b/validator_client/src/key_cache.rs index 1eba296b120..21c3b8f396d 100644 --- a/validator_client/src/key_cache.rs +++ b/validator_client/src/key_cache.rs @@ -1,4 +1,3 @@ -use filesystem::{create_with_600_perms, Error as fsError}; use bls::{Keypair, PublicKey}; use eth2_keystore::json_keystore::{ Aes128Ctr, ChecksumModule, Cipher, CipherModule, Crypto, EmptyMap, EmptyString, KdfModule, @@ -8,6 +7,7 @@ use eth2_keystore::{ decrypt, default_kdf, encrypt, keypair_from_secret, Error as KeystoreError, PlainText, Uuid, ZeroizeHash, IV_SIZE, SALT_SIZE, }; +use filesystem::{create_with_600_perms, Error as fsError}; use rand::prelude::*; use serde::{Deserialize, Serialize}; use std::collections::HashMap; From 6c4fda14823f89244b2416b0c054b0fa70625089 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 5 May 2021 16:14:39 -0400 Subject: [PATCH 04/32] removed forgotten println --- slasher/src/database.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/slasher/src/database.rs b/slasher/src/database.rs index fa655cb878a..e09876c27d9 100644 --- a/slasher/src/database.rs +++ b/slasher/src/database.rs @@ -202,18 +202,8 @@ impl SlasherDB { data.push("data.mdb"); let mut lock = config.database_path.clone(); lock.push("lock.mdb"); - restrict_file_permissions(data) - .or_else(|e| { - println!("Error setting permissions for slasher db: {:?}", e); - Err(e) - }) - .map_err(Error::DatabasePermissionsError)?; - restrict_file_permissions(lock) - .or_else(|e| { - println!("Error setting permissions for slasher db: {:?}", e); - Err(e) - }) - .map_err(Error::DatabasePermissionsError)?; + restrict_file_permissions(data).map_err(Error::DatabasePermissionsError)?; + restrict_file_permissions(lock).map_err(Error::DatabasePermissionsError)?; } let db = Self { From 8f73443a3132caac816d2411e38484d556e2a16f Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 5 May 2021 17:10:29 -0400 Subject: [PATCH 05/32] fixed unused import issue --- testing/remote_signer_test/src/utils.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testing/remote_signer_test/src/utils.rs b/testing/remote_signer_test/src/utils.rs index 387da44427f..e649960eb8c 100644 --- a/testing/remote_signer_test/src/utils.rs +++ b/testing/remote_signer_test/src/utils.rs @@ -10,6 +10,8 @@ use std::io::Write; use std::net::IpAddr::{V4, V6}; #[cfg(unix)] use std::os::unix::fs::PermissionsExt; +#[cfg(unix)] +use std::path::Path; use tempfile::TempDir; use types::{ AggregateSignature, Attestation, AttestationData, AttesterSlashing, BeaconBlock, @@ -31,7 +33,6 @@ pub fn get_address(client: &Client) -> String { #[cfg(unix)] pub fn set_permissions(path: &Path, perm_octal: u32) { use std::fs; - use std::path::Path; let metadata = fs::metadata(path).unwrap(); let mut permissions = metadata.permissions(); From 1cd6a6fd1d7b2b928c8bd7dacd5eb33e01efe564 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 5 May 2021 17:25:15 -0400 Subject: [PATCH 06/32] Fixed clippy complaints --- common/filesystem/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/filesystem/src/lib.rs b/common/filesystem/src/lib.rs index 2fcd4f5aec9..a01c95d29fc 100644 --- a/common/filesystem/src/lib.rs +++ b/common/filesystem/src/lib.rs @@ -30,7 +30,7 @@ pub enum Error { /// Creates a file with `600 (-rw-------)` permissions. pub fn create_with_600_perms>(path: P, bytes: &[u8]) -> Result<(), Error> { let path = path.as_ref(); - let mut file = File::create(&path).map_err(|e| Error::UnableToCreateFile(e))?; + let mut file = File::create(&path).map_err(Error::UnableToCreateFile)?; #[cfg(unix)] { @@ -41,11 +41,11 @@ pub fn create_with_600_perms>(path: P, bytes: &[u8]) -> Result<() .permissions(); perm.set_mode(0o600); file.set_permissions(perm) - .map_err(|e| Error::UnableToSetPermissions(e))?; + .map_err(Error::UnableToSetPermissions)?; } file.write_all(bytes) - .map_err(|e| Error::UnableToWriteFile(e))?; + .map_err(Error::UnableToWriteFile)?; #[cfg(windows)] { restrict_file_permissions(path)?; @@ -65,7 +65,7 @@ pub fn restrict_file_permissions>(path: P) -> Result<(), Error> { .permissions(); perm.set_mode(0o600); file.set_permissions(perm) - .map_err(|e| Error::UnableToSetPermissions(e))?; + .map_err(Error::UnableToSetPermissions)?; } #[cfg(windows)] From 138f34af67540279eed6cac7ee7ebc1f075f5ed4 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 5 May 2021 17:27:26 -0400 Subject: [PATCH 07/32] Fixed formatting again --- common/filesystem/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/common/filesystem/src/lib.rs b/common/filesystem/src/lib.rs index a01c95d29fc..bee4a200381 100644 --- a/common/filesystem/src/lib.rs +++ b/common/filesystem/src/lib.rs @@ -44,8 +44,7 @@ pub fn create_with_600_perms>(path: P, bytes: &[u8]) -> Result<() .map_err(Error::UnableToSetPermissions)?; } - file.write_all(bytes) - .map_err(Error::UnableToWriteFile)?; + file.write_all(bytes).map_err(Error::UnableToWriteFile)?; #[cfg(windows)] { restrict_file_permissions(path)?; From 82eed9e2923cbb618a9c0b7003f2f6c348be865e Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 5 May 2021 17:45:18 -0400 Subject: [PATCH 08/32] fixed clippy complaints again --- common/validator_dir/src/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/validator_dir/src/builder.rs b/common/validator_dir/src/builder.rs index 1a6602feef9..c80ee2c9a42 100644 --- a/common/validator_dir/src/builder.rs +++ b/common/validator_dir/src/builder.rs @@ -283,7 +283,7 @@ pub fn write_password_to_file>(path: P, bytes: &[u8]) -> Result<( return Err(Error::PasswordAlreadyExists(path.into())); } - create_with_600_perms(path, bytes).map_err(|e| Error::UnableToSavePassword(e))?; + create_with_600_perms(path, bytes).map_err(Error::UnableToSavePassword)?; Ok(()) } From 33b900f54a603e3c50d215ae994653ec04ac2d52 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 5 May 2021 17:49:31 -0400 Subject: [PATCH 09/32] fixed clippy complaints again again --- common/account_utils/src/validator_definitions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/account_utils/src/validator_definitions.rs b/common/account_utils/src/validator_definitions.rs index e5910908454..68f68c3d2d8 100644 --- a/common/account_utils/src/validator_definitions.rs +++ b/common/account_utils/src/validator_definitions.rs @@ -263,7 +263,7 @@ impl ValidatorDefinitions { if config_path.exists() { fs::write(config_path, &bytes).map_err(Error::UnableToWriteFile) } else { - create_with_600_perms(&config_path, &bytes).map_err(|e| Error::UnableToCreateFile(e)) + create_with_600_perms(&config_path, &bytes).map_err(Error::UnableToCreateFile) } } From 669ae04ccc6fbfa7a3f7822e66d92aa6b291a585 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 5 May 2021 19:00:40 -0400 Subject: [PATCH 10/32] fixed platform-specific dependencies --- common/filesystem/Cargo.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/common/filesystem/Cargo.toml b/common/filesystem/Cargo.toml index 159e5ad268b..f263f680cee 100644 --- a/common/filesystem/Cargo.toml +++ b/common/filesystem/Cargo.toml @@ -7,7 +7,8 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -clap = "2.33.3" + +[target.'cfg(windows)'.dependencies] winapi = "~0.3.5" windows-acl = "~0.3.0" -filepath = "~0.1.1" + From 5df34e3f9155fb328d0ff0027e1a4b3256df22f8 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 5 May 2021 21:14:53 -0400 Subject: [PATCH 11/32] Fixed Cargo.lock for clippy --- Cargo.lock | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 88e5586a3d9..b26abcfb46c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2254,22 +2254,10 @@ dependencies = [ "rustc_version 0.3.3", ] -[[package]] -name = "filepath" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd50318458226958db06f173610f54f01d26f0a9ccfa3d38bd60f70bc9939ff" -dependencies = [ - "libc", - "winapi 0.3.9", -] - [[package]] name = "filesystem" version = "0.1.0" dependencies = [ - "clap", - "filepath", "winapi 0.3.9", "windows-acl", ] From c8ba601a53885a99b476ff9ced9168bd0c99257c Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Thu, 6 May 2021 08:32:20 -0400 Subject: [PATCH 12/32] Use cfg! macro for windows booleans --- account_manager/src/validator/create.rs | 7 +------ account_manager/src/validator/exit.rs | 7 +------ account_manager/src/validator/import.rs | 7 +------ account_manager/src/validator/recover.rs | 7 +------ account_manager/src/wallet/create.rs | 7 +------ account_manager/src/wallet/recover.rs | 7 +------ 6 files changed, 6 insertions(+), 36 deletions(-) diff --git a/account_manager/src/validator/create.rs b/account_manager/src/validator/create.rs index 8aa25d85092..2b4c1c38006 100644 --- a/account_manager/src/validator/create.rs +++ b/account_manager/src/validator/create.rs @@ -27,11 +27,6 @@ pub const AT_MOST_FLAG: &str = "at-most"; pub const WALLET_PASSWORD_PROMPT: &str = "Enter your wallet's password:"; pub fn cli_app<'a, 'b>() -> App<'a, 'b> { - #[cfg(unix)] - let windows = false; - #[cfg(windows)] - let windows = true; - App::new(CMD) .about( "Creates new validators from an existing EIP-2386 wallet using the EIP-2333 HD key \ @@ -111,7 +106,7 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { .arg( Arg::with_name(STDIN_INPUTS_FLAG) .takes_value(false) - .hidden(windows) + .hidden(cfg!(windows)) .long(STDIN_INPUTS_FLAG) .help("If present, read all user inputs from stdin instead of tty."), ) diff --git a/account_manager/src/validator/exit.rs b/account_manager/src/validator/exit.rs index 906436df089..3d3e214f42f 100644 --- a/account_manager/src/validator/exit.rs +++ b/account_manager/src/validator/exit.rs @@ -29,11 +29,6 @@ pub const WEBSITE_URL: &str = "https://lighthouse-book.sigmaprime.io/voluntary-e pub const PROMPT: &str = "WARNING: WITHDRAWING STAKED ETH IS NOT CURRENTLY POSSIBLE"; pub fn cli_app<'a, 'b>() -> App<'a, 'b> { - #[cfg(unix)] - let windows = false; - #[cfg(windows)] - let windows = true; - App::new("exit") .about("Submits a VoluntaryExit to the beacon chain for a given validator keystore.") .arg( @@ -67,7 +62,7 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { .arg( Arg::with_name(STDIN_INPUTS_FLAG) .takes_value(false) - .hidden(windows) + .hidden(cfg!(windows)) .long(STDIN_INPUTS_FLAG) .help("If present, read all user inputs from stdin instead of tty."), ) diff --git a/account_manager/src/validator/import.rs b/account_manager/src/validator/import.rs index 6356fc0c611..529a400d8bb 100644 --- a/account_manager/src/validator/import.rs +++ b/account_manager/src/validator/import.rs @@ -25,11 +25,6 @@ pub const KEYSTORE_REUSE_WARNING: &str = "DO NOT USE THE ORIGINAL KEYSTORES TO V ANOTHER CLIENT, OR YOU WILL GET SLASHED."; pub fn cli_app<'a, 'b>() -> App<'a, 'b> { - #[cfg(unix)] - let windows = false; - #[cfg(windows)] - let windows = true; - App::new(CMD) .about( "Imports one or more EIP-2335 passwords into a Lighthouse VC directory, \ @@ -63,7 +58,7 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { .arg( Arg::with_name(STDIN_INPUTS_FLAG) .takes_value(false) - .hidden(windows) + .hidden(cfg!(windows)) .long(STDIN_INPUTS_FLAG) .help("If present, read all user inputs from stdin instead of tty."), ) diff --git a/account_manager/src/validator/recover.rs b/account_manager/src/validator/recover.rs index 427bbef7da8..48cb5f16620 100644 --- a/account_manager/src/validator/recover.rs +++ b/account_manager/src/validator/recover.rs @@ -17,11 +17,6 @@ pub const FIRST_INDEX_FLAG: &str = "first-index"; pub const MNEMONIC_FLAG: &str = "mnemonic-path"; pub fn cli_app<'a, 'b>() -> App<'a, 'b> { - #[cfg(unix)] - let windows = false; - #[cfg(windows)] - let windows = true; - App::new(CMD) .about( "Recovers validator private keys given a BIP-39 mnemonic phrase. \ @@ -77,7 +72,7 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { .arg( Arg::with_name(STDIN_INPUTS_FLAG) .takes_value(false) - .hidden(windows) + .hidden(cfg!(windows)) .long(STDIN_INPUTS_FLAG) .help("If present, read all user inputs from stdin instead of tty."), ) diff --git a/account_manager/src/wallet/create.rs b/account_manager/src/wallet/create.rs index b23eedfa036..7829d45e0ba 100644 --- a/account_manager/src/wallet/create.rs +++ b/account_manager/src/wallet/create.rs @@ -34,11 +34,6 @@ pub const NEW_WALLET_PASSWORD_PROMPT: &str = pub const RETYPE_PASSWORD_PROMPT: &str = "Please re-enter your wallet's new password:"; pub fn cli_app<'a, 'b>() -> App<'a, 'b> { - #[cfg(unix)] - let windows = false; - #[cfg(windows)] - let windows = true; - App::new(CMD) .about("Creates a new HD (hierarchical-deterministic) EIP-2386 wallet.") .arg( @@ -87,7 +82,7 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { .arg( Arg::with_name(STDIN_INPUTS_FLAG) .takes_value(false) - .hidden(windows) + .hidden(cfg!(windows)) .long(STDIN_INPUTS_FLAG) .help("If present, read all user inputs from stdin instead of tty."), ) diff --git a/account_manager/src/wallet/recover.rs b/account_manager/src/wallet/recover.rs index 63efb666fd8..572c6458a7b 100644 --- a/account_manager/src/wallet/recover.rs +++ b/account_manager/src/wallet/recover.rs @@ -8,11 +8,6 @@ pub const CMD: &str = "recover"; pub const MNEMONIC_FLAG: &str = "mnemonic-path"; pub fn cli_app<'a, 'b>() -> App<'a, 'b> { - #[cfg(unix)] - let windows = false; - #[cfg(windows)] - let windows = true; - App::new(CMD) .about("Recovers an EIP-2386 wallet from a given a BIP-39 mnemonic phrase.") .arg( @@ -60,7 +55,7 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { .arg( Arg::with_name(STDIN_INPUTS_FLAG) .takes_value(false) - .hidden(windows) + .hidden(cfg!(windows)) .long(STDIN_INPUTS_FLAG) .help("If present, read all user inputs from stdin instead of tty."), ) From d725a09f3112ee31a3277a4a38c9bc3d73acc0a1 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Thu, 6 May 2021 09:35:33 -0400 Subject: [PATCH 13/32] use cfg! macro again --- account_manager/src/validator/create.rs | 6 +----- account_manager/src/validator/exit.rs | 6 +----- account_manager/src/validator/import.rs | 5 +---- account_manager/src/validator/recover.rs | 5 +---- account_manager/src/wallet/create.rs | 7 +------ account_manager/src/wallet/recover.rs | 5 +---- 6 files changed, 6 insertions(+), 28 deletions(-) diff --git a/account_manager/src/validator/create.rs b/account_manager/src/validator/create.rs index 2b4c1c38006..5099c2de5e2 100644 --- a/account_manager/src/validator/create.rs +++ b/account_manager/src/validator/create.rs @@ -120,11 +120,7 @@ pub fn cli_run( let spec = env.core_context().eth2_config.spec; let name: Option = clap_utils::parse_optional(matches, WALLET_NAME_FLAG)?; - - #[cfg(unix)] - let stdin_inputs = matches.is_present(STDIN_INPUTS_FLAG); - #[cfg(windows)] - let stdin_inputs = true; + let stdin_inputs = cfg!(windows) || matches.is_present(STDIN_INPUTS_FLAG); let wallet_base_dir = if matches.value_of("datadir").is_some() { let path: PathBuf = clap_utils::parse_required(matches, "datadir")?; diff --git a/account_manager/src/validator/exit.rs b/account_manager/src/validator/exit.rs index 3d3e214f42f..6c15615af46 100644 --- a/account_manager/src/validator/exit.rs +++ b/account_manager/src/validator/exit.rs @@ -73,11 +73,7 @@ pub fn cli_run(matches: &ArgMatches, env: Environment) -> Result< let password_file_path: Option = clap_utils::parse_optional(matches, PASSWORD_FILE_FLAG)?; - #[cfg(unix)] - let stdin_inputs = matches.is_present(STDIN_INPUTS_FLAG); - #[cfg(windows)] - let stdin_inputs = true; - + let stdin_inputs = cfg!(windows) || matches.is_present(STDIN_INPUTS_FLAG); let no_wait = matches.is_present(NO_WAIT); let spec = env.eth2_config().spec.clone(); diff --git a/account_manager/src/validator/import.rs b/account_manager/src/validator/import.rs index 529a400d8bb..96da154031d 100644 --- a/account_manager/src/validator/import.rs +++ b/account_manager/src/validator/import.rs @@ -85,10 +85,7 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), String> { let keystore: Option = clap_utils::parse_optional(matches, KEYSTORE_FLAG)?; let keystores_dir: Option = clap_utils::parse_optional(matches, DIR_FLAG)?; - #[cfg(unix)] - let stdin_inputs = matches.is_present(STDIN_INPUTS_FLAG); - #[cfg(windows)] - let stdin_inputs = true; + let stdin_inputs = cfg!(windows) || matches.is_present(STDIN_INPUTS_FLAG); let reuse_password = matches.is_present(REUSE_PASSWORD_FLAG); let keystore_password_path: Option = clap_utils::parse_optional(matches, PASSWORD_FLAG)?; diff --git a/account_manager/src/validator/recover.rs b/account_manager/src/validator/recover.rs index 48cb5f16620..45a7fe9b610 100644 --- a/account_manager/src/validator/recover.rs +++ b/account_manager/src/validator/recover.rs @@ -88,10 +88,7 @@ pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), Strin let first_index: u32 = clap_utils::parse_required(matches, FIRST_INDEX_FLAG)?; let count: u32 = clap_utils::parse_required(matches, COUNT_FLAG)?; let mnemonic_path: Option = clap_utils::parse_optional(matches, MNEMONIC_FLAG)?; - #[cfg(unix)] - let stdin_inputs = matches.is_present(STDIN_INPUTS_FLAG); - #[cfg(windows)] - let stdin_inputs = true; + let stdin_inputs = cfg!(windows) || matches.is_preset(STDIN_INPUTS_FLAG); eprintln!("secrets-dir path: {:?}", secrets_dir); diff --git a/account_manager/src/wallet/create.rs b/account_manager/src/wallet/create.rs index 7829d45e0ba..1390f35033c 100644 --- a/account_manager/src/wallet/create.rs +++ b/account_manager/src/wallet/create.rs @@ -153,12 +153,7 @@ pub fn create_wallet_from_mnemonic( let name: Option = clap_utils::parse_optional(matches, NAME_FLAG)?; let wallet_password_path: Option = clap_utils::parse_optional(matches, PASSWORD_FLAG)?; let type_field: String = clap_utils::parse_required(matches, TYPE_FLAG)?; - - #[cfg(unix)] - let stdin_inputs = matches.is_present(STDIN_INPUTS_FLAG); - #[cfg(windows)] - let stdin_inputs = true; - + let stdin_inputs = cfg!(windows) || matches.is_present(STDIN_INPUTS_FLAG); let wallet_type = match type_field.as_ref() { HD_TYPE => WalletType::Hd, unknown => return Err(format!("--{} {} is not supported", TYPE_FLAG, unknown)), diff --git a/account_manager/src/wallet/recover.rs b/account_manager/src/wallet/recover.rs index 572c6458a7b..ec4cbb2ada1 100644 --- a/account_manager/src/wallet/recover.rs +++ b/account_manager/src/wallet/recover.rs @@ -63,10 +63,7 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { pub fn cli_run(matches: &ArgMatches, wallet_base_dir: PathBuf) -> Result<(), String> { let mnemonic_path: Option = clap_utils::parse_optional(matches, MNEMONIC_FLAG)?; - #[cfg(unix)] - let stdin_inputs = matches.is_present(STDIN_INPUTS_FLAG); - #[cfg(windows)] - let stdin_inputs = true; + let stdin_inputs = cfg!(windows) || matches.is_present(STDIN_INPUTS_FLAG); eprintln!(); eprintln!("WARNING: KEY RECOVERY CAN LEAD TO DUPLICATING VALIDATORS KEYS, WHICH CAN LEAD TO SLASHING."); From e39277fe7c0df0aa7d72f0f9571abee06592003b Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Thu, 6 May 2021 09:51:20 -0400 Subject: [PATCH 14/32] fixed typo --- account_manager/src/validator/recover.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/account_manager/src/validator/recover.rs b/account_manager/src/validator/recover.rs index 45a7fe9b610..d9b05e7756e 100644 --- a/account_manager/src/validator/recover.rs +++ b/account_manager/src/validator/recover.rs @@ -88,7 +88,7 @@ pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), Strin let first_index: u32 = clap_utils::parse_required(matches, FIRST_INDEX_FLAG)?; let count: u32 = clap_utils::parse_required(matches, COUNT_FLAG)?; let mnemonic_path: Option = clap_utils::parse_optional(matches, MNEMONIC_FLAG)?; - let stdin_inputs = cfg!(windows) || matches.is_preset(STDIN_INPUTS_FLAG); + let stdin_inputs = cfg!(windows) || matches.is_present(STDIN_INPUTS_FLAG); eprintln!("secrets-dir path: {:?}", secrets_dir); From 749ea97603acaa7863a57ac64e2733ef2a239f09 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Fri, 7 May 2021 01:43:50 -0400 Subject: [PATCH 15/32] Tests *should* complete in windows now --- Cargo.lock | 2 + common/remote_signer_consumer/tests/post.rs | 8 +- remote_signer/backend/src/lib.rs | 12 +-- remote_signer/backend/src/storage_raw_dir.rs | 12 +-- remote_signer/tests/get_keys.rs | 4 +- remote_signer/tests/sign.rs | 8 +- testing/eth1_test_rig/src/ganache.rs | 12 ++- testing/remote_signer_test/Cargo.toml | 5 ++ testing/remote_signer_test/src/utils.rs | 81 +++++++++++++++++--- 9 files changed, 108 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b26abcfb46c..835601f3737 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5215,6 +5215,8 @@ dependencies = [ "tempfile", "tokio 1.5.0", "types", + "winapi 0.3.9", + "windows-acl", ] [[package]] diff --git a/common/remote_signer_consumer/tests/post.rs b/common/remote_signer_consumer/tests/post.rs index 1667ee2c621..42ea1cb25e3 100644 --- a/common/remote_signer_consumer/tests/post.rs +++ b/common/remote_signer_consumer/tests/post.rs @@ -31,15 +31,15 @@ mod post { #[test] fn server_error() { let (test_signer, tmp_dir) = set_up_api_test_signer_to_sign_message(); - set_permissions(tmp_dir.path(), 0o40311); - set_permissions(&tmp_dir.path().join(PUBLIC_KEY_1), 0o40311); + restrict_permissions(tmp_dir.path()); + restrict_permissions(&tmp_dir.path().join(PUBLIC_KEY_1)); let test_client = set_up_test_consumer(&test_signer.address); let test_input = get_input_data_block(0xc137); let signature = do_sign_request(&test_client, test_input); - set_permissions(tmp_dir.path(), 0o40755); - set_permissions(&tmp_dir.path().join(PUBLIC_KEY_1), 0o40755); + unrestrict_permissions(tmp_dir.path()); + unrestrict_permissions(&tmp_dir.path().join(PUBLIC_KEY_1)); match signature.unwrap_err() { Error::ServerMessage(message) => assert_eq!(message, "Storage error: PermissionDenied"), diff --git a/remote_signer/backend/src/lib.rs b/remote_signer/backend/src/lib.rs index 9631f00b1db..5e29fbee124 100644 --- a/remote_signer/backend/src/lib.rs +++ b/remote_signer/backend/src/lib.rs @@ -171,7 +171,7 @@ pub mod backend_new { #[test] fn given_inaccessible() { let tmp_dir = tempdir().unwrap(); - set_permissions(tmp_dir.path(), 0o40311); + restrict_permissions(tmp_dir.path()); let matches = set_matches(vec![ "this_test", @@ -184,7 +184,7 @@ pub mod backend_new { // A `d-wx--x--x` directory is innaccesible but not unwrittable. // By switching back to `drwxr-xr-x` we can get rid of the // temporal directory once we leave this scope. - set_permissions(tmp_dir.path(), 0o40755); + unrestrict_permissions(tmp_dir.path()); match result { Ok(_) => panic!("This invocation to Backend::new() should return error"), @@ -263,16 +263,16 @@ pub mod backend_raw_dir_sign_message { fn storage_error() { let (backend, tmp_dir) = new_backend_for_signing(); - set_permissions(tmp_dir.path(), 0o40311); - set_permissions(&tmp_dir.path().join(PUBLIC_KEY_1), 0o40311); + restrict_permissions(tmp_dir.path()); + restrict_permissions(&tmp_dir.path().join(PUBLIC_KEY_1)); let result = backend.sign_message( PUBLIC_KEY_1, Hash256::from_slice(&hex::decode(SIGNING_ROOT).unwrap()), ); - set_permissions(tmp_dir.path(), 0o40755); - set_permissions(&tmp_dir.path().join(PUBLIC_KEY_1), 0o40755); + unrestrict_permissions(tmp_dir.path()); + unrestrict_permissions(&tmp_dir.path().join(PUBLIC_KEY_1)); assert_eq!( result.unwrap_err().to_string(), diff --git a/remote_signer/backend/src/storage_raw_dir.rs b/remote_signer/backend/src/storage_raw_dir.rs index 4990ca574ef..8ae5dfd6766 100644 --- a/remote_signer/backend/src/storage_raw_dir.rs +++ b/remote_signer/backend/src/storage_raw_dir.rs @@ -83,12 +83,12 @@ mod get_keys { add_key_files(&tmp_dir); // All good and fancy, let's make the dir innacessible now. - set_permissions(tmp_dir.path(), 0o40311); + restrict_permissions(tmp_dir.path()); let result = storage.get_keys(); // Give permissions back, we want the tempdir to be deleted. - set_permissions(tmp_dir.path(), 0o40755); + unrestrict_permissions(tmp_dir.path()); assert_eq!( result.unwrap_err().to_string(), @@ -141,13 +141,13 @@ mod get_secret_key { let (storage, tmp_dir) = new_storage_with_tmp_dir(); add_key_files(&tmp_dir); - set_permissions(tmp_dir.path(), 0o40311); - set_permissions(&tmp_dir.path().join(PUBLIC_KEY_1), 0o40311); + restrict_permissions(tmp_dir.path()); + restrict_permissions(&tmp_dir.path().join(PUBLIC_KEY_1)); let result = storage.get_secret_key(PUBLIC_KEY_1); - set_permissions(tmp_dir.path(), 0o40755); - set_permissions(&tmp_dir.path().join(PUBLIC_KEY_1), 0o40755); + unrestrict_permissions(tmp_dir.path()); + unrestrict_permissions(&tmp_dir.path().join(PUBLIC_KEY_1)); assert_eq!( result.unwrap_err().to_string(), diff --git a/remote_signer/tests/get_keys.rs b/remote_signer/tests/get_keys.rs index 88d981a11b6..887a16a80d3 100644 --- a/remote_signer/tests/get_keys.rs +++ b/remote_signer/tests/get_keys.rs @@ -68,14 +68,14 @@ mod get_keys { add_non_key_files(&tmp_dir); // Somebody tripped over a wire. - set_permissions(tmp_dir.path(), 0o40311); + restrict_permissions(tmp_dir.path()); let url = format!("{}/keys", test_signer.address); let resp = http_get(&url); // Be able to delete the tempdir afterward, regardless of this test result. - set_permissions(tmp_dir.path(), 0o40755); + unrestrict_permissions(tmp_dir.path()); assert_error(resp, 500, "Storage error: PermissionDenied"); diff --git a/remote_signer/tests/sign.rs b/remote_signer/tests/sign.rs index d019c446149..ee124c80db3 100644 --- a/remote_signer/tests/sign.rs +++ b/remote_signer/tests/sign.rs @@ -20,14 +20,14 @@ mod sign { fn storage_error() { let (test_signer, tmp_dir) = set_up_api_test_signer_to_sign_message(); let test_block_body = get_test_block_body(0xc137); - set_permissions(tmp_dir.path(), 0o40311); - set_permissions(&tmp_dir.path().join(PUBLIC_KEY_1), 0o40311); + restrict_permissions(tmp_dir.path()); + restrict_permissions(&tmp_dir.path().join(PUBLIC_KEY_1)); let url = format!("{}/sign/{}", test_signer.address, PUBLIC_KEY_1); let response = http_post_custom_body(&url, &test_block_body); - set_permissions(tmp_dir.path(), 0o40755); - set_permissions(&tmp_dir.path().join(PUBLIC_KEY_1), 0o40755); + unrestrict_permissions(tmp_dir.path()); + unrestrict_permissions(&tmp_dir.path().join(PUBLIC_KEY_1)); assert_sign_error(response, 500, "Storage error: PermissionDenied"); diff --git a/testing/eth1_test_rig/src/ganache.rs b/testing/eth1_test_rig/src/ganache.rs index 7b62db30b9a..8c005c1e3cc 100644 --- a/testing/eth1_test_rig/src/ganache.rs +++ b/testing/eth1_test_rig/src/ganache.rs @@ -74,8 +74,11 @@ impl GanacheInstance { /// RPC connections. pub fn new(network_id: u64, chain_id: u64) -> Result { let port = unused_port()?; - - let child = Command::new("ganache-cli") + let binary = match cfg!(windows) { + true => "ganache-cli.cmd", // really windows? + false => "ganache-cli", + }; + let child = Command::new(binary) .stdout(Stdio::piped()) .arg("--defaultBalanceEther") .arg("1000000000") @@ -94,8 +97,9 @@ impl GanacheInstance { .spawn() .map_err(|e| { format!( - "Failed to start ganache-cli. \ - Is it ganache-cli installed and available on $PATH? Error: {:?}", + "Failed to start {}. \ + Is it installed and available on $PATH? Error: {:?}", + binary, e ) })?; diff --git a/testing/remote_signer_test/Cargo.toml b/testing/remote_signer_test/Cargo.toml index 1daf8c2c582..e6a75c66947 100644 --- a/testing/remote_signer_test/Cargo.toml +++ b/testing/remote_signer_test/Cargo.toml @@ -18,3 +18,8 @@ tempfile = "3.1.0" tokio = { version = "1.1.0", features = ["time"] } types = { path = "../../consensus/types" } sensitive_url = { path = "../../common/sensitive_url" } + +[target.'cfg(windows)'.dependencies] +winapi = "~0.3.5" +windows-acl = "~0.3.0" + diff --git a/testing/remote_signer_test/src/utils.rs b/testing/remote_signer_test/src/utils.rs index e649960eb8c..e65fe840350 100644 --- a/testing/remote_signer_test/src/utils.rs +++ b/testing/remote_signer_test/src/utils.rs @@ -8,9 +8,6 @@ pub use remote_signer_test_data::*; use std::fs::{create_dir, File}; use std::io::Write; use std::net::IpAddr::{V4, V6}; -#[cfg(unix)] -use std::os::unix::fs::PermissionsExt; -#[cfg(unix)] use std::path::Path; use tempfile::TempDir; use types::{ @@ -30,14 +27,78 @@ pub fn get_address(client: &Client) -> String { format!("http://{}:{}", ip, listening_address.port()) } -#[cfg(unix)] -pub fn set_permissions(path: &Path, perm_octal: u32) { - use std::fs; +pub fn restrict_permissions(path: &Path) { + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + use std::fs; - let metadata = fs::metadata(path).unwrap(); - let mut permissions = metadata.permissions(); - permissions.set_mode(perm_octal); - fs::set_permissions(path, permissions).unwrap(); + let metadata = fs::metadata(path).unwrap(); + let mut permissions = metadata.permissions(); + permissions.set_mode(0o0311); // set to '*-wx--x--x' + fs::set_permissions(path, permissions).unwrap(); + } + + #[cfg(windows)] + { + use winapi::um::winnt::PSID; + use windows_acl::acl::{AceType, ACL}; + + let path_str = path + .to_str() + .unwrap(); + let mut acl = + ACL::from_file_path(&path_str, false).unwrap(); + + let entries = acl + .all() + .unwrap(); + // remove all AccessAllow entries + for entry in &entries { + if let Some(ref entry_sid) = entry.sid { + acl.remove( + (*entry_sid).as_ptr() as PSID, + Some(AceType::AccessAllow), + None, + ).unwrap(); + } + } + } +} + +pub fn unrestrict_permissions(path: &Path) { + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + use std::fs; + + let metadata = fs::metadata(path).unwrap(); + let mut permissions = metadata.permissions(); + permissions.set_mode(0o0755); // set to '*rwxr-xr-x' + fs::set_permissions(path, permissions).unwrap(); + } + + #[cfg(windows)] + { + use winapi::um::winnt::PSID; + use windows_acl::acl::{AceType, ACL}; + + let path_str = path + .to_str() + .unwrap(); + let mut acl = + ACL::from_file_path(&path_str, false).unwrap(); + + let owner_sid = windows_acl::helper::string_to_sid("S-1-3-4").unwrap(); + // add single entry for file owner + acl.add_entry( + owner_sid.as_ptr() as PSID, + AceType::AccessAllow, + 0, + 0x1f01ff, + ) + .unwrap(); + } } pub fn add_key_files(tmp_dir: &TempDir) { From ab775ee2fa422d36492900e5484391c36b521047 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Fri, 7 May 2021 10:22:51 -0400 Subject: [PATCH 16/32] Ran cargo fmt --- testing/eth1_test_rig/src/ganache.rs | 5 ++--- testing/remote_signer_test/src/utils.rs | 25 +++++++++---------------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/testing/eth1_test_rig/src/ganache.rs b/testing/eth1_test_rig/src/ganache.rs index 8c005c1e3cc..707866398de 100644 --- a/testing/eth1_test_rig/src/ganache.rs +++ b/testing/eth1_test_rig/src/ganache.rs @@ -75,7 +75,7 @@ impl GanacheInstance { pub fn new(network_id: u64, chain_id: u64) -> Result { let port = unused_port()?; let binary = match cfg!(windows) { - true => "ganache-cli.cmd", // really windows? + true => "ganache-cli.cmd", // really windows? false => "ganache-cli", }; let child = Command::new(binary) @@ -99,8 +99,7 @@ impl GanacheInstance { format!( "Failed to start {}. \ Is it installed and available on $PATH? Error: {:?}", - binary, - e + binary, e ) })?; diff --git a/testing/remote_signer_test/src/utils.rs b/testing/remote_signer_test/src/utils.rs index e65fe840350..b9ce64fa546 100644 --- a/testing/remote_signer_test/src/utils.rs +++ b/testing/remote_signer_test/src/utils.rs @@ -30,8 +30,8 @@ pub fn get_address(client: &Client) -> String { pub fn restrict_permissions(path: &Path) { #[cfg(unix)] { - use std::os::unix::fs::PermissionsExt; use std::fs; + use std::os::unix::fs::PermissionsExt; let metadata = fs::metadata(path).unwrap(); let mut permissions = metadata.permissions(); @@ -44,15 +44,10 @@ pub fn restrict_permissions(path: &Path) { use winapi::um::winnt::PSID; use windows_acl::acl::{AceType, ACL}; - let path_str = path - .to_str() - .unwrap(); - let mut acl = - ACL::from_file_path(&path_str, false).unwrap(); + let path_str = path.to_str().unwrap(); + let mut acl = ACL::from_file_path(&path_str, false).unwrap(); - let entries = acl - .all() - .unwrap(); + let entries = acl.all().unwrap(); // remove all AccessAllow entries for entry in &entries { if let Some(ref entry_sid) = entry.sid { @@ -60,7 +55,8 @@ pub fn restrict_permissions(path: &Path) { (*entry_sid).as_ptr() as PSID, Some(AceType::AccessAllow), None, - ).unwrap(); + ) + .unwrap(); } } } @@ -69,8 +65,8 @@ pub fn restrict_permissions(path: &Path) { pub fn unrestrict_permissions(path: &Path) { #[cfg(unix)] { - use std::os::unix::fs::PermissionsExt; use std::fs; + use std::os::unix::fs::PermissionsExt; let metadata = fs::metadata(path).unwrap(); let mut permissions = metadata.permissions(); @@ -83,11 +79,8 @@ pub fn unrestrict_permissions(path: &Path) { use winapi::um::winnt::PSID; use windows_acl::acl::{AceType, ACL}; - let path_str = path - .to_str() - .unwrap(); - let mut acl = - ACL::from_file_path(&path_str, false).unwrap(); + let path_str = path.to_str().unwrap(); + let mut acl = ACL::from_file_path(&path_str, false).unwrap(); let owner_sid = windows_acl::helper::string_to_sid("S-1-3-4").unwrap(); // add single entry for file owner From 4a1e251bf0b2a03eebc81960cc14db9bb3eae8cf Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Mon, 10 May 2021 15:30:28 -0400 Subject: [PATCH 17/32] cargo test --all --release now succeeds on windows --- .../beacon_chain/tests/block_verification.rs | 3 ++ common/lockfile/src/lib.rs | 18 ++++++--- common/remote_signer_consumer/tests/post.rs | 25 ++++++++---- remote_signer/backend/src/lib.rs | 5 ++- slasher/tests/attester_slashings.rs | 4 ++ testing/eth1_test_rig/src/ganache.rs | 38 ++++++++++++++++--- testing/remote_signer_test/src/utils.rs | 10 +++++ validator_client/slashing_protection/Makefile | 15 ++++++-- 8 files changed, 95 insertions(+), 23 deletions(-) diff --git a/beacon_node/beacon_chain/tests/block_verification.rs b/beacon_node/beacon_chain/tests/block_verification.rs index 1bd12b6e308..2cc0502cdfe 100644 --- a/beacon_node/beacon_chain/tests/block_verification.rs +++ b/beacon_node/beacon_chain/tests/block_verification.rs @@ -824,4 +824,7 @@ fn verify_block_for_gossip_slashing_detection() { slasher.process_queued(Epoch::new(0)).unwrap(); let proposer_slashings = slasher.get_proposer_slashings(); assert_eq!(proposer_slashings.len(), 1); + // windows won't delete the temporary directory if you don't do this.. + drop(harness); + drop(slasher); } diff --git a/common/lockfile/src/lib.rs b/common/lockfile/src/lib.rs index 28e5b90a0e1..d6240ecb64c 100644 --- a/common/lockfile/src/lib.rs +++ b/common/lockfile/src/lib.rs @@ -81,12 +81,20 @@ mod test { fn new_lock() { let temp = tempdir().unwrap(); let path = temp.path().join("lockfile"); - let _lock = Lockfile::new(path.clone()).unwrap(); - assert!(matches!( - Lockfile::new(path).unwrap_err(), - LockfileError::FileLocked(..) - )); + if cfg!(windows) { + assert!(matches!( + Lockfile::new(path).unwrap_err(), + // windows returns an IoError because the lockfile is already open :/ + LockfileError::IoError(..), + )); + } + else { + assert!(matches!( + Lockfile::new(path).unwrap_err(), + LockfileError::FileLocked(..) + )); + } } #[test] diff --git a/common/remote_signer_consumer/tests/post.rs b/common/remote_signer_consumer/tests/post.rs index 42ea1cb25e3..3b241f57ab3 100644 --- a/common/remote_signer_consumer/tests/post.rs +++ b/common/remote_signer_consumer/tests/post.rs @@ -18,11 +18,20 @@ mod post { match signature.unwrap_err() { Error::Reqwest(e) => { let error_msg = e.to_string(); - assert!(error_msg.contains("error sending request for url")); - assert!(error_msg.contains(PUBLIC_KEY_1)); - assert!(error_msg.contains("error trying to connect")); - assert!(error_msg.contains("tcp connect error")); - assert!(error_msg.contains("Connection refused")); + let pubkey_string = format!("{}", PUBLIC_KEY_1); + let msgs = vec![ + "error sending request for url", + &pubkey_string, + "error trying to connect", + "tcp connect error", + match cfg!(windows) { + true => "No connection could be made because the target machine actively refused it", + false => "Connection refused", + } + ]; + for msg in msgs.iter() { + assert!(error_msg.contains(msg), "{:?} should contain {:?}", error_msg, msg); + } } e => panic!("{:?}", e), } @@ -145,7 +154,6 @@ mod post { let testcase = |u: &str, msgs: Vec<&str>| { let r = run_testcase(u).unwrap_err(); - for msg in msgs.iter() { assert!(r.contains(msg), "{:?} should contain {:?}", r, msg); } @@ -159,7 +167,10 @@ mod post { &format!("/sign/{}", PUBLIC_KEY_1), "hyper::Error(Connect, ConnectError", "dns error", - "failed to lookup address information", + match cfg!(windows) { + true => "No such host is known.", + false => "failed to lookup address information", + }, ], ); diff --git a/remote_signer/backend/src/lib.rs b/remote_signer/backend/src/lib.rs index 5e29fbee124..0366f18e0ee 100644 --- a/remote_signer/backend/src/lib.rs +++ b/remote_signer/backend/src/lib.rs @@ -163,7 +163,10 @@ pub mod backend_new { #[test] fn given_path_is_not_a_dir() { - let matches = set_matches(vec!["this_test", "--storage-raw-dir", "/dev/null"]); + let matches = set_matches(vec!["this_test", "--storage-raw-dir", match cfg!(windows) { + true => "C:\\Windows\\system.ini", + false => "/dev/null" + }]); assert_backend_new_error(&matches, "Storage Raw Dir: Path is not a directory."); } diff --git a/slasher/tests/attester_slashings.rs b/slasher/tests/attester_slashings.rs index 3b541e7a8fe..494eb0a227a 100644 --- a/slasher/tests/attester_slashings.rs +++ b/slasher/tests/attester_slashings.rs @@ -189,6 +189,8 @@ fn slasher_test( // Pruning should not error. slasher.prune_database(current_epoch).unwrap(); + // windows won't delete the temporary directory if you don't do this.. + drop(slasher); } fn parallel_slasher_test( @@ -212,4 +214,6 @@ fn parallel_slasher_test( let slashings = slasher.get_attester_slashings(); let slashed_validators = slashed_validators_from_slashings(&slashings); assert_eq!(slashed_validators, expected_slashed_validators); + // windows won't delete the temporary directory if you don't do this.. + drop(slasher); } diff --git a/testing/eth1_test_rig/src/ganache.rs b/testing/eth1_test_rig/src/ganache.rs index 707866398de..e90d3f08a14 100644 --- a/testing/eth1_test_rig/src/ganache.rs +++ b/testing/eth1_test_rig/src/ganache.rs @@ -75,7 +75,7 @@ impl GanacheInstance { pub fn new(network_id: u64, chain_id: u64) -> Result { let port = unused_port()?; let binary = match cfg!(windows) { - true => "ganache-cli.cmd", // really windows? + true => "ganache-cli.cmd", false => "ganache-cli", }; let child = Command::new(binary) @@ -86,6 +86,8 @@ impl GanacheInstance { .arg("1000000000") .arg("--accounts") .arg("10") + .arg("--keepAliveTimeout") + .arg("0") .arg("--port") .arg(format!("{}", port)) .arg("--mnemonic") @@ -108,20 +110,26 @@ impl GanacheInstance { pub fn fork(&self) -> Result { let port = unused_port()?; - - let child = Command::new("ganache-cli") + let binary = match cfg!(windows) { + true => "ganache-cli.cmd", + false => "ganache-cli", + }; + let child = Command::new(binary) .stdout(Stdio::piped()) .arg("--fork") .arg(self.endpoint()) .arg("--port") .arg(format!("{}", port)) + .arg("--keepAliveTimeout") + .arg("0") .arg("--chainId") .arg(format!("{}", self.chain_id)) .spawn() .map_err(|e| { format!( - "Failed to start ganache-cli. \ - Is it ganache-cli installed and available on $PATH? Error: {:?}", + "Failed to start {}. \ + Is it installed and available on $PATH? Error: {:?}", + binary, e ) })?; @@ -205,6 +213,24 @@ pub fn unused_port() -> Result { impl Drop for GanacheInstance { fn drop(&mut self) { - let _ = self.child.kill(); + if cfg!(windows) { + // Calling child.kill() in Windows will only kill the process + // that spawned ganache, leaving the actual ganache process + // intact. You have to kill the whole process tree. What's more, + // if you don't spawn ganache with --keepAliveTimeout=0, Windows + // will STILL keep the server running even after you've ended + // the process tree and it's disappeared from the task manager. + // Unbelievable... + Command::new("taskkill") + .arg("/pid") + .arg(self.child.id().to_string()) + .arg("/T") + .arg("/F") + .output() + .expect("failed to execute taskkill"); + } + else { + let _ = self.child.kill(); + } } } diff --git a/testing/remote_signer_test/src/utils.rs b/testing/remote_signer_test/src/utils.rs index b9ce64fa546..42995ed5e7e 100644 --- a/testing/remote_signer_test/src/utils.rs +++ b/testing/remote_signer_test/src/utils.rs @@ -47,6 +47,7 @@ pub fn restrict_permissions(path: &Path) { let path_str = path.to_str().unwrap(); let mut acl = ACL::from_file_path(&path_str, false).unwrap(); + let owner_sid = windows_acl::helper::string_to_sid("S-1-3-4").unwrap(); let entries = acl.all().unwrap(); // remove all AccessAllow entries for entry in &entries { @@ -59,6 +60,15 @@ pub fn restrict_permissions(path: &Path) { .unwrap(); } } + // add single entry for minimal access to file owner + // allowing them only to read attributes of the file + // and read/modify permissions + acl.add_entry( + owner_sid.as_ptr() as PSID, + AceType::AccessAllow, + 0, + 0x160088, + ).unwrap(); } } diff --git a/validator_client/slashing_protection/Makefile b/validator_client/slashing_protection/Makefile index 79960ec5aa1..a773beaf4b3 100644 --- a/validator_client/slashing_protection/Makefile +++ b/validator_client/slashing_protection/Makefile @@ -4,8 +4,15 @@ OUTPUT_DIR := interchange-tests TARBALL := $(OUTPUT_DIR)-$(TESTS_TAG).tar.gz ARCHIVE_URL := https://github.com/eth2-clients/slashing-protection-interchange-tests/tarball/$(TESTS_TAG) +ifeq ($(OS),Windows_NT) + RMFILE:=del /F /Q + RMDIR:=rmdir /Q /S +else + RMFILE:=rm -f + RMDIR:=rm -rf +endif + $(OUTPUT_DIR): $(TARBALL) - rm -rf $@ mkdir $@ tar --strip-components=1 -xzf $^ -C $@ @@ -13,13 +20,13 @@ $(TARBALL): curl --fail -L -o $@ $(ARCHIVE_URL) clean-test-files: - rm -rf $(OUTPUT_DIR) + $(RMDIR) $(OUTPUT_DIR) clean-archives: - rm -f $(TARBALL) + $(RMFILE) $(TARBALL) generate: - rm -rf $(GENERATE_DIR) + $(RMDIR) $(GENERATE_DIR) cargo run --release --bin test_generator -- $(GENERATE_DIR) clean: clean-test-files clean-archives From d7ffcda8d82d01d88c9b0f81ae88cabf71c77685 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Mon, 10 May 2021 15:33:42 -0400 Subject: [PATCH 18/32] forgot to run cargo fmt >.< --- common/lockfile/src/lib.rs | 3 +-- common/remote_signer_consumer/tests/post.rs | 7 ++++++- remote_signer/backend/src/lib.rs | 12 ++++++++---- testing/eth1_test_rig/src/ganache.rs | 6 ++---- testing/remote_signer_test/src/utils.rs | 3 ++- 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/common/lockfile/src/lib.rs b/common/lockfile/src/lib.rs index d6240ecb64c..82e28256f74 100644 --- a/common/lockfile/src/lib.rs +++ b/common/lockfile/src/lib.rs @@ -88,8 +88,7 @@ mod test { // windows returns an IoError because the lockfile is already open :/ LockfileError::IoError(..), )); - } - else { + } else { assert!(matches!( Lockfile::new(path).unwrap_err(), LockfileError::FileLocked(..) diff --git a/common/remote_signer_consumer/tests/post.rs b/common/remote_signer_consumer/tests/post.rs index 3b241f57ab3..1de21a3cdc6 100644 --- a/common/remote_signer_consumer/tests/post.rs +++ b/common/remote_signer_consumer/tests/post.rs @@ -30,7 +30,12 @@ mod post { } ]; for msg in msgs.iter() { - assert!(error_msg.contains(msg), "{:?} should contain {:?}", error_msg, msg); + assert!( + error_msg.contains(msg), + "{:?} should contain {:?}", + error_msg, + msg + ); } } e => panic!("{:?}", e), diff --git a/remote_signer/backend/src/lib.rs b/remote_signer/backend/src/lib.rs index 0366f18e0ee..4c3c2464e18 100644 --- a/remote_signer/backend/src/lib.rs +++ b/remote_signer/backend/src/lib.rs @@ -163,10 +163,14 @@ pub mod backend_new { #[test] fn given_path_is_not_a_dir() { - let matches = set_matches(vec!["this_test", "--storage-raw-dir", match cfg!(windows) { - true => "C:\\Windows\\system.ini", - false => "/dev/null" - }]); + let matches = set_matches(vec![ + "this_test", + "--storage-raw-dir", + match cfg!(windows) { + true => "C:\\Windows\\system.ini", + false => "/dev/null", + }, + ]); assert_backend_new_error(&matches, "Storage Raw Dir: Path is not a directory."); } diff --git a/testing/eth1_test_rig/src/ganache.rs b/testing/eth1_test_rig/src/ganache.rs index e90d3f08a14..d2eadd478c6 100644 --- a/testing/eth1_test_rig/src/ganache.rs +++ b/testing/eth1_test_rig/src/ganache.rs @@ -129,8 +129,7 @@ impl GanacheInstance { format!( "Failed to start {}. \ Is it installed and available on $PATH? Error: {:?}", - binary, - e + binary, e ) })?; @@ -228,8 +227,7 @@ impl Drop for GanacheInstance { .arg("/F") .output() .expect("failed to execute taskkill"); - } - else { + } else { let _ = self.child.kill(); } } diff --git a/testing/remote_signer_test/src/utils.rs b/testing/remote_signer_test/src/utils.rs index 42995ed5e7e..d696b3ba378 100644 --- a/testing/remote_signer_test/src/utils.rs +++ b/testing/remote_signer_test/src/utils.rs @@ -68,7 +68,8 @@ pub fn restrict_permissions(path: &Path) { AceType::AccessAllow, 0, 0x160088, - ).unwrap(); + ) + .unwrap(); } } From c6f9e798e2bca506c3ff7b5639b9a370aa4152c7 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Mon, 10 May 2021 15:49:07 -0400 Subject: [PATCH 19/32] clippy again.. --- common/remote_signer_consumer/tests/post.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/remote_signer_consumer/tests/post.rs b/common/remote_signer_consumer/tests/post.rs index 1de21a3cdc6..543605fb5be 100644 --- a/common/remote_signer_consumer/tests/post.rs +++ b/common/remote_signer_consumer/tests/post.rs @@ -18,7 +18,7 @@ mod post { match signature.unwrap_err() { Error::Reqwest(e) => { let error_msg = e.to_string(); - let pubkey_string = format!("{}", PUBLIC_KEY_1); + let pubkey_string = PUBLIC_KEY_1.to_string(); let msgs = vec![ "error sending request for url", &pubkey_string, From b8b04b65be2e91f8ccc1d15146d2890e0ab2be03 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 12 May 2021 16:09:03 -0400 Subject: [PATCH 20/32] Made changes requested by msproul --- .../src/validator_definitions.rs | 3 +- common/filesystem/src/lib.rs | 36 ++++++++++++++----- common/validator_dir/src/builder.rs | 4 +-- slasher/src/database.rs | 6 ++-- slasher/src/error.rs | 3 +- testing/remote_signer_test/src/utils.rs | 36 ++++++++++++++++--- validator_client/slashing_protection/Makefile | 15 ++++---- validator_client/src/key_cache.rs | 3 +- 8 files changed, 73 insertions(+), 33 deletions(-) diff --git a/common/account_utils/src/validator_definitions.rs b/common/account_utils/src/validator_definitions.rs index fe446f87a13..47aaff2155e 100644 --- a/common/account_utils/src/validator_definitions.rs +++ b/common/account_utils/src/validator_definitions.rs @@ -6,7 +6,6 @@ use crate::{default_keystore_password_path, write_file_via_temporary, ZeroizeString}; use directory::ensure_dir_exists; use eth2_keystore::Keystore; -use filesystem::Error as FsError; use regex::Regex; use serde_derive::{Deserialize, Serialize}; use slog::{error, Logger}; @@ -37,7 +36,7 @@ pub enum Error { /// The config file could not be serialized as YAML. UnableToEncodeFile(serde_yaml::Error), /// The config file or temp file could not be written to the filesystem. - UnableToWriteFile(FsError), + UnableToWriteFile(filesystem::Error), /// The public key from the keystore is invalid. InvalidKeystorePubkey, /// The keystore was unable to be opened. diff --git a/common/filesystem/src/lib.rs b/common/filesystem/src/lib.rs index 0147d38acde..38d8fd99727 100644 --- a/common/filesystem/src/lib.rs +++ b/common/filesystem/src/lib.rs @@ -2,6 +2,25 @@ use std::fs::File; use std::io; use std::io::Write; use std::path::Path; +#[cfg(windows)] +use winapi::um::winnt::{FILE_GENERIC_READ, FILE_GENERIC_WRITE, STANDARD_RIGHTS_ALL}; + +/// This is the security identifier in Windows for the owner of a file. See: +/// - https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/security-identifiers-in-windows#well-known-sids-all-versions-of-windows +#[cfg(windows)] +const OWNER_SID_STR: &str = "S-1-3-4"; +/// We don't need any of the `AceFlags` listed here: +/// - https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header +#[cfg(windows)] +const OWNER_ACL_ENTRY_FLAGS: u32 = 0; +/// Generic Rights: +/// - https://docs.microsoft.com/en-us/windows/win32/fileio/file-security-and-access-rights +/// Individual Read/Write/Execute Permissions (referenced in generic rights link): +/// - https://docs.microsoft.com/en-us/windows/win32/wmisdk/file-and-directory-access-rights-constants +/// STANDARD_RIGHTS_ALL +/// - https://docs.microsoft.com/en-us/windows/win32/secauthz/access-mask +#[cfg(windows)] +const OWNER_ACL_ENTRY_MASK: u32 = FILE_GENERIC_READ | FILE_GENERIC_WRITE | STANDARD_RIGHTS_ALL; #[derive(Debug)] pub enum Error { @@ -21,6 +40,8 @@ pub enum Error { UnableToWriteFile(io::Error), /// Failed to obtain file path UnableToObtainFilePath, + /// Failed to convert string to SID + UnableToConvertSID(u32), /// Failed to retrieve ACL for file UnableToRetrieveACL(u32), /// Failed to enumerate ACL entries @@ -81,22 +102,19 @@ pub fn restrict_file_permissions>(path: P) -> Result<(), Error> { .as_ref() .to_str() .ok_or(Error::UnableToObtainFilePath)?; - let mut acl = - ACL::from_file_path(&path_str, false).map_err(|e| Error::UnableToRetrieveACL(e))?; + let mut acl = ACL::from_file_path(&path_str, false).map_err(Error::UnableToRetrieveACL)?; - let owner_sid_str = "S-1-3-4"; - let owner_sid = windows_acl::helper::string_to_sid(owner_sid_str).unwrap(); + let owner_sid = + windows_acl::helper::string_to_sid(OWNER_SID_STR).map_err(Error::UnableToConvertSID)?; - let entries = acl - .all() - .map_err(|e| Error::UnableToEnumerateACLEntries(e))?; + let entries = acl.all().map_err(Error::UnableToEnumerateACLEntries)?; // add single entry for file owner acl.add_entry( owner_sid.as_ptr() as PSID, AceType::AccessAllow, - 0, - 0x1f01ff, + OWNER_ACL_ENTRY_FLAGS, + OWNER_ACL_ENTRY_MASK, ) .map_err(|code| { Error::UnableToAddACLEntry(format!( diff --git a/common/validator_dir/src/builder.rs b/common/validator_dir/src/builder.rs index c80ee2c9a42..d284e2d6732 100644 --- a/common/validator_dir/src/builder.rs +++ b/common/validator_dir/src/builder.rs @@ -2,7 +2,7 @@ use crate::{Error as DirError, ValidatorDir}; use bls::get_withdrawal_credentials; use deposit_contract::{encode_eth1_tx_data, Error as DepositError}; use eth2_keystore::{Error as KeystoreError, Keystore, KeystoreBuilder, PlainText}; -use filesystem::{create_with_600_perms, Error as fsError}; +use filesystem::create_with_600_perms; use rand::{distributions::Alphanumeric, Rng}; use std::fs::{create_dir_all, OpenOptions}; use std::io::{self, Write}; @@ -33,7 +33,7 @@ pub enum Error { KeystoreAlreadyExists(PathBuf), UnableToSaveKeystore(io::Error), PasswordAlreadyExists(PathBuf), - UnableToSavePassword(fsError), + UnableToSavePassword(filesystem::Error), KeystoreError(KeystoreError), UnableToOpenDir(DirError), UninitializedVotingKeystore, diff --git a/slasher/src/database.rs b/slasher/src/database.rs index e09876c27d9..447179e3936 100644 --- a/slasher/src/database.rs +++ b/slasher/src/database.rs @@ -198,10 +198,8 @@ impl SlasherDB { #[cfg(windows)] { use filesystem::restrict_file_permissions; - let mut data = config.database_path.clone(); - data.push("data.mdb"); - let mut lock = config.database_path.clone(); - lock.push("lock.mdb"); + let data = config.database_path.join("data.mtb"); + let lock = config.database_path.join("lock.mdb"); restrict_file_permissions(data).map_err(Error::DatabasePermissionsError)?; restrict_file_permissions(lock).map_err(Error::DatabasePermissionsError)?; } diff --git a/slasher/src/error.rs b/slasher/src/error.rs index 6cfddf12ddd..d40a54f7144 100644 --- a/slasher/src/error.rs +++ b/slasher/src/error.rs @@ -1,5 +1,4 @@ use crate::Config; -use filesystem::Error as fsError; use std::io; use types::{Epoch, Hash256}; @@ -7,7 +6,7 @@ use types::{Epoch, Hash256}; pub enum Error { DatabaseError(lmdb::Error), DatabaseIOError(io::Error), - DatabasePermissionsError(fsError), + DatabasePermissionsError(filesystem::Error), SszDecodeError(ssz::DecodeError), BincodeError(bincode::Error), ArithError(safe_arith::ArithError), diff --git a/testing/remote_signer_test/src/utils.rs b/testing/remote_signer_test/src/utils.rs index d696b3ba378..796962800e4 100644 --- a/testing/remote_signer_test/src/utils.rs +++ b/testing/remote_signer_test/src/utils.rs @@ -16,6 +16,32 @@ use types::{ Hash256, IndexedAttestation, ProposerSlashing, PublicKeyBytes, Signature, SignatureBytes, SignedBeaconBlockHeader, SignedVoluntaryExit, Slot, Unsigned, VariableList, VoluntaryExit, }; +#[cfg(windows)] +use winapi::um::winnt::{ + FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_READ_ATTRIBUTES, FILE_READ_EA, READ_CONTROL, + STANDARD_RIGHTS_ALL, SYNCHRONIZE, WRITE_DAC, +}; + +/// This is the security identifier in Windows for the owner of a file. See: +/// - https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/security-identifiers-in-windows#well-known-sids-all-versions-of-windows +#[cfg(windows)] +const OWNER_SID_STR: &str = "S-1-3-4"; +/// We don't need any of the `AceFlags` listed here: +/// - https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header +#[cfg(windows)] +const OWNER_ACL_ENTRY_FLAGS: u8 = 0; +/// See here for explanation: +/// - https://docs.microsoft.com/en-us/windows/win32/wmisdk/file-and-directory-access-rights-constants +#[cfg(windows)] +const OWNER_ACL_ENTRY_RESTRICT_MASK: u32 = + FILE_READ_ATTRIBUTES | FILE_READ_EA | READ_CONTROL | WRITE_DAC | SYNCHRONIZE; +/// Generic Rights: +/// - https://docs.microsoft.com/en-us/windows/win32/fileio/file-security-and-access-rights +/// STANDARD_RIGHTS_ALL +/// - https://docs.microsoft.com/en-us/windows/win32/secauthz/access-mask +#[cfg(windows)] +const OWNER_ACL_ENTRY_UNRESTRICT_MASK: u32 = + FILE_GENERIC_READ | FILE_GENERIC_WRITE | STANDARD_RIGHTS_ALL; pub fn get_address(client: &Client) -> String { let listening_address = client.get_listening_address(); @@ -47,7 +73,7 @@ pub fn restrict_permissions(path: &Path) { let path_str = path.to_str().unwrap(); let mut acl = ACL::from_file_path(&path_str, false).unwrap(); - let owner_sid = windows_acl::helper::string_to_sid("S-1-3-4").unwrap(); + let owner_sid = windows_acl::helper::string_to_sid(OWNER_SID_STR).unwrap(); let entries = acl.all().unwrap(); // remove all AccessAllow entries for entry in &entries { @@ -66,8 +92,8 @@ pub fn restrict_permissions(path: &Path) { acl.add_entry( owner_sid.as_ptr() as PSID, AceType::AccessAllow, - 0, - 0x160088, + OWNER_ACL_ENTRY_FLAGS, + OWNER_ACL_ENTRY_RESTRICT_MASK, ) .unwrap(); } @@ -98,8 +124,8 @@ pub fn unrestrict_permissions(path: &Path) { acl.add_entry( owner_sid.as_ptr() as PSID, AceType::AccessAllow, - 0, - 0x1f01ff, + OWNER_ACL_ENTRY_FLAGS, + OWNER_ACL_ENTRY_UNRESTRICT_MASK, ) .unwrap(); } diff --git a/validator_client/slashing_protection/Makefile b/validator_client/slashing_protection/Makefile index a773beaf4b3..4ef23869096 100644 --- a/validator_client/slashing_protection/Makefile +++ b/validator_client/slashing_protection/Makefile @@ -5,14 +5,15 @@ TARBALL := $(OUTPUT_DIR)-$(TESTS_TAG).tar.gz ARCHIVE_URL := https://github.com/eth2-clients/slashing-protection-interchange-tests/tarball/$(TESTS_TAG) ifeq ($(OS),Windows_NT) - RMFILE:=del /F /Q - RMDIR:=rmdir /Q /S + rmfile = if exist $(1) (del /F /Q $(1)) + rmdir = if exist $(1) (rmdir /Q /S $(1)) else - RMFILE:=rm -f - RMDIR:=rm -rf + rmfile = rm -f $(1) + rmdir = rm -rf $(1) endif $(OUTPUT_DIR): $(TARBALL) + $(call rmdir,$@) mkdir $@ tar --strip-components=1 -xzf $^ -C $@ @@ -20,13 +21,13 @@ $(TARBALL): curl --fail -L -o $@ $(ARCHIVE_URL) clean-test-files: - $(RMDIR) $(OUTPUT_DIR) + $(call rmdir,$(OUTPUT_DIR)) clean-archives: - $(RMFILE) $(TARBALL) + $(call rmfile,$(TARBALL)) generate: - $(RMDIR) $(GENERATE_DIR) + $(call rmdir,$(GENERATE_DIR)) cargo run --release --bin test_generator -- $(GENERATE_DIR) clean: clean-test-files clean-archives diff --git a/validator_client/src/key_cache.rs b/validator_client/src/key_cache.rs index 252531719ad..5947621023a 100644 --- a/validator_client/src/key_cache.rs +++ b/validator_client/src/key_cache.rs @@ -8,7 +8,6 @@ use eth2_keystore::{ decrypt, default_kdf, encrypt, keypair_from_secret, Error as KeystoreError, PlainText, Uuid, ZeroizeHash, IV_SIZE, SALT_SIZE, }; -use filesystem::Error as FsError; use rand::prelude::*; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -246,7 +245,7 @@ pub enum Error { UnableToEncodeFile(serde_json::Error), /// The cache file or its temporary could not be written to the filesystem. UnableToWriteFile(io::Error), - UnableToCreateFile(FsError), + UnableToCreateFile(filesystem::Error), /// Couldn't decrypt the cache file UnableToDecrypt(KeystoreError), UnableToEncrypt(KeystoreError), From c20a63dddcb2e05e0b4e48340338fe2f0810d58e Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Thu, 13 May 2021 10:07:04 +1000 Subject: [PATCH 21/32] Fix some compilation errors/quirks --- common/filesystem/src/lib.rs | 10 +++++----- testing/remote_signer_test/src/utils.rs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/common/filesystem/src/lib.rs b/common/filesystem/src/lib.rs index 38d8fd99727..046602e4e38 100644 --- a/common/filesystem/src/lib.rs +++ b/common/filesystem/src/lib.rs @@ -12,7 +12,7 @@ const OWNER_SID_STR: &str = "S-1-3-4"; /// We don't need any of the `AceFlags` listed here: /// - https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header #[cfg(windows)] -const OWNER_ACL_ENTRY_FLAGS: u32 = 0; +const OWNER_ACL_ENTRY_FLAGS: u8 = 0; /// Generic Rights: /// - https://docs.microsoft.com/en-us/windows/win32/fileio/file-security-and-access-rights /// Individual Read/Write/Execute Permissions (referenced in generic rights link): @@ -119,17 +119,17 @@ pub fn restrict_file_permissions>(path: P) -> Result<(), Error> { .map_err(|code| { Error::UnableToAddACLEntry(format!( "Failed to add ACL entry for SID {} error={}", - owner_sid_str, code + OWNER_SID_STR, code )) })?; // remove all AccessAllow entries from the file that aren't the owner_sid for entry in &entries { if let Some(ref entry_sid) = entry.sid { - let entry_sid_str = sid_to_string((*entry_sid).as_ptr() as PSID) + let entry_sid_str = sid_to_string(entry_sid.as_ptr() as PSID) .unwrap_or_else(|_| "BadFormat".to_string()); - if entry_sid_str != owner_sid_str { + if entry_sid_str != OWNER_SID_STR { acl.remove( - (*entry_sid).as_ptr() as PSID, + entry_sid.as_ptr() as PSID, Some(AceType::AccessAllow), None, ) diff --git a/testing/remote_signer_test/src/utils.rs b/testing/remote_signer_test/src/utils.rs index 796962800e4..169603031cb 100644 --- a/testing/remote_signer_test/src/utils.rs +++ b/testing/remote_signer_test/src/utils.rs @@ -79,7 +79,7 @@ pub fn restrict_permissions(path: &Path) { for entry in &entries { if let Some(ref entry_sid) = entry.sid { acl.remove( - (*entry_sid).as_ptr() as PSID, + entry_sid.as_ptr() as PSID, Some(AceType::AccessAllow), None, ) From f3d48b9b07a0c6cf6e195b3f08ec89dd17ce6e91 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Thu, 13 May 2021 12:03:49 +1000 Subject: [PATCH 22/32] Fix typo, check for tempdir cleanup --- beacon_node/beacon_chain/tests/block_verification.rs | 1 + slasher/src/database.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/beacon_node/beacon_chain/tests/block_verification.rs b/beacon_node/beacon_chain/tests/block_verification.rs index 2cc0502cdfe..b2ae1cfbb99 100644 --- a/beacon_node/beacon_chain/tests/block_verification.rs +++ b/beacon_node/beacon_chain/tests/block_verification.rs @@ -827,4 +827,5 @@ fn verify_block_for_gossip_slashing_detection() { // windows won't delete the temporary directory if you don't do this.. drop(harness); drop(slasher); + slasher_dir.close().unwrap(); } diff --git a/slasher/src/database.rs b/slasher/src/database.rs index 447179e3936..7576d18483d 100644 --- a/slasher/src/database.rs +++ b/slasher/src/database.rs @@ -198,7 +198,7 @@ impl SlasherDB { #[cfg(windows)] { use filesystem::restrict_file_permissions; - let data = config.database_path.join("data.mtb"); + let data = config.database_path.join("data.mdb"); let lock = config.database_path.join("lock.mdb"); restrict_file_permissions(data).map_err(Error::DatabasePermissionsError)?; restrict_file_permissions(lock).map_err(Error::DatabasePermissionsError)?; From 4f3ef51e93971a9467147f2604eb0568d53ee3e4 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Thu, 13 May 2021 12:27:08 +1000 Subject: [PATCH 23/32] First go at Windows CI --- .github/workflows/test-suite.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 75b01606932..1967d797a21 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -44,6 +44,20 @@ jobs: run: sudo npm install -g ganache-cli - name: Run tests in release run: make test-release + release-tests-windows: + name: release-tests-windows + runs-on: windows-latest + needs: cargo-fmt + steps: + - uses: actions/checkout@v1 + - name: Get latest version of stable Rust + run: rustup update stable + - name: Install ganache-cli + run: sudo npm install -g ganache-cli + - name: Install make + run: sudo choco install make + - name: Run tests in release + run: make test-release debug-tests-ubuntu: name: debug-tests-ubuntu runs-on: ubuntu-latest From 2f418524ca0310e5e609dc0cc815550714acc259 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Thu, 13 May 2021 12:32:45 +1000 Subject: [PATCH 24/32] Cargo fmt --- common/filesystem/src/lib.rs | 18 +++++++----------- testing/remote_signer_test/src/utils.rs | 8 ++------ 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/common/filesystem/src/lib.rs b/common/filesystem/src/lib.rs index 046602e4e38..127fcd55b99 100644 --- a/common/filesystem/src/lib.rs +++ b/common/filesystem/src/lib.rs @@ -128,17 +128,13 @@ pub fn restrict_file_permissions>(path: P) -> Result<(), Error> { let entry_sid_str = sid_to_string(entry_sid.as_ptr() as PSID) .unwrap_or_else(|_| "BadFormat".to_string()); if entry_sid_str != OWNER_SID_STR { - acl.remove( - entry_sid.as_ptr() as PSID, - Some(AceType::AccessAllow), - None, - ) - .map_err(|_| { - Error::UnableToRemoveACLEntry(format!( - "Failed to remove ACL entry for SID {}", - entry_sid_str - )) - })?; + acl.remove(entry_sid.as_ptr() as PSID, Some(AceType::AccessAllow), None) + .map_err(|_| { + Error::UnableToRemoveACLEntry(format!( + "Failed to remove ACL entry for SID {}", + entry_sid_str + )) + })?; } } } diff --git a/testing/remote_signer_test/src/utils.rs b/testing/remote_signer_test/src/utils.rs index 169603031cb..e17c8e9eee2 100644 --- a/testing/remote_signer_test/src/utils.rs +++ b/testing/remote_signer_test/src/utils.rs @@ -78,12 +78,8 @@ pub fn restrict_permissions(path: &Path) { // remove all AccessAllow entries for entry in &entries { if let Some(ref entry_sid) = entry.sid { - acl.remove( - entry_sid.as_ptr() as PSID, - Some(AceType::AccessAllow), - None, - ) - .unwrap(); + acl.remove(entry_sid.as_ptr() as PSID, Some(AceType::AccessAllow), None) + .unwrap(); } } // add single entry for minimal access to file owner From 0ec467ee19cfb6d5d4a122e9abbd787f824e4ec2 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Thu, 13 May 2021 12:45:10 +1000 Subject: [PATCH 25/32] Smaller DB for slasher tests --- slasher/src/config.rs | 13 +++++++++++++ slasher/tests/attester_slashings.rs | 4 ++-- slasher/tests/proposer_slashings.rs | 4 ++-- slasher/tests/random.rs | 2 +- slasher/tests/wrap_around.rs | 4 ++-- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/slasher/src/config.rs b/slasher/src/config.rs index 0f44d8d4890..5a701048bdb 100644 --- a/slasher/src/config.rs +++ b/slasher/src/config.rs @@ -10,6 +10,13 @@ pub const DEFAULT_UPDATE_PERIOD: u64 = 12; pub const DEFAULT_MAX_DB_SIZE: usize = 256 * 1024; // 256 GiB pub const DEFAULT_BROADCAST: bool = false; +/// Database size to use for tests. +/// +/// Mostly a workaround for Windows due to a bug in LMDB, see: +/// +/// https://github.com/sigp/lighthouse/issues/2342 +pub const TESTING_MAX_DB_SIZE: usize = 16; // MiB + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Config { pub database_path: PathBuf, @@ -38,6 +45,12 @@ impl Config { } } + /// Use a smaller max DB size for testing. + pub fn for_testing(mut self) -> Self { + self.max_db_size_mbs = TESTING_MAX_DB_SIZE; + self + } + pub fn validate(&self) -> Result<(), Error> { if self.chunk_size == 0 || self.validator_chunk_size == 0 diff --git a/slasher/tests/attester_slashings.rs b/slasher/tests/attester_slashings.rs index 494eb0a227a..138d5526cbd 100644 --- a/slasher/tests/attester_slashings.rs +++ b/slasher/tests/attester_slashings.rs @@ -170,7 +170,7 @@ fn slasher_test( should_process_after: impl Fn(usize) -> bool, ) { let tempdir = tempdir().unwrap(); - let config = Config::new(tempdir.path().into()); + let config = Config::new(tempdir.path().into()).for_testing(); let slasher = Slasher::open(config, logger()).unwrap(); let current_epoch = Epoch::new(current_epoch); @@ -199,7 +199,7 @@ fn parallel_slasher_test( current_epoch: u64, ) { let tempdir = tempdir().unwrap(); - let config = Config::new(tempdir.path().into()); + let config = Config::new(tempdir.path().into()).for_testing(); let slasher = Slasher::open(config, logger()).unwrap(); let current_epoch = Epoch::new(current_epoch); diff --git a/slasher/tests/proposer_slashings.rs b/slasher/tests/proposer_slashings.rs index f584bacfba0..ec46f6db852 100644 --- a/slasher/tests/proposer_slashings.rs +++ b/slasher/tests/proposer_slashings.rs @@ -8,7 +8,7 @@ use types::{Epoch, EthSpec}; #[test] fn empty_pruning() { let tempdir = tempdir().unwrap(); - let config = Config::new(tempdir.path().into()); + let config = Config::new(tempdir.path().into()).for_testing(); let slasher = Slasher::::open(config, logger()).unwrap(); slasher.prune_database(Epoch::new(0)).unwrap(); } @@ -18,7 +18,7 @@ fn block_pruning() { let slots_per_epoch = E::slots_per_epoch(); let tempdir = tempdir().unwrap(); - let mut config = Config::new(tempdir.path().into()); + let mut config = Config::new(tempdir.path().into()).for_testing(); config.chunk_size = 2; config.history_length = 2; diff --git a/slasher/tests/random.rs b/slasher/tests/random.rs index 47fce46f4fb..641a52b7efe 100644 --- a/slasher/tests/random.rs +++ b/slasher/tests/random.rs @@ -40,7 +40,7 @@ fn random_test(seed: u64, test_config: TestConfig) { let tempdir = tempdir().unwrap(); - let mut config = Config::new(tempdir.path().into()); + let mut config = Config::new(tempdir.path().into()).for_testing(); config.validator_chunk_size = 1 << rng.gen_range(1, 4); let chunk_size_exponent = rng.gen_range(1, 4); diff --git a/slasher/tests/wrap_around.rs b/slasher/tests/wrap_around.rs index 1480704e6bf..79ec91fbe6b 100644 --- a/slasher/tests/wrap_around.rs +++ b/slasher/tests/wrap_around.rs @@ -8,7 +8,7 @@ use types::Epoch; #[test] fn attestation_pruning_empty_wrap_around() { let tempdir = tempdir().unwrap(); - let mut config = Config::new(tempdir.path().into()); + let mut config = Config::new(tempdir.path().into()).for_testing(); config.validator_chunk_size = 1; config.chunk_size = 16; config.history_length = 16; @@ -42,7 +42,7 @@ fn attestation_pruning_empty_wrap_around() { #[test] fn pruning_with_map_full() { let tempdir = tempdir().unwrap(); - let mut config = Config::new(tempdir.path().into()); + let mut config = Config::new(tempdir.path().into()).for_testing(); config.validator_chunk_size = 1; config.chunk_size = 16; config.history_length = 1024; From c30b1554d45f9e743fd416a381de8ef0b39b48d3 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Thu, 13 May 2021 14:59:30 +1000 Subject: [PATCH 26/32] No sudo on Windows oops --- .github/workflows/test-suite.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 1967d797a21..5c46cee66c1 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -53,9 +53,9 @@ jobs: - name: Get latest version of stable Rust run: rustup update stable - name: Install ganache-cli - run: sudo npm install -g ganache-cli + run: npm install -g ganache-cli - name: Install make - run: sudo choco install make + run: choco install -y make - name: Run tests in release run: make test-release debug-tests-ubuntu: From 18603c97289e716539f864c03902f23e6c7bb36e Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Thu, 13 May 2021 17:47:31 -0400 Subject: [PATCH 27/32] forgot one of the tests needs testing config --- beacon_node/beacon_chain/tests/block_verification.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon_node/beacon_chain/tests/block_verification.rs b/beacon_node/beacon_chain/tests/block_verification.rs index b2ae1cfbb99..d5378d627bc 100644 --- a/beacon_node/beacon_chain/tests/block_verification.rs +++ b/beacon_node/beacon_chain/tests/block_verification.rs @@ -805,7 +805,7 @@ fn verify_block_for_gossip_slashing_detection() { let slasher_dir = tempdir().unwrap(); let slasher = Arc::new( Slasher::open( - SlasherConfig::new(slasher_dir.path().into()), + SlasherConfig::new(slasher_dir.path().into()).for_testing(), harness.logger().clone(), ) .unwrap(), From d23e6953c460090b5b35e74a2ef109f5da8a3ab6 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Tue, 18 May 2021 12:08:07 -0400 Subject: [PATCH 28/32] Updated lighthouse book & fixed slasher cli tests --- book/src/installation-source.md | 48 +++++++++++++++++++++------------ book/src/slasher.md | 1 + lighthouse/tests/beacon_node.rs | 7 +++++ 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/book/src/installation-source.md b/book/src/installation-source.md index 286379390be..f6059f338d2 100644 --- a/book/src/installation-source.md +++ b/book/src/installation-source.md @@ -1,9 +1,10 @@ # Installation: Build from Source -Lighthouse builds on Linux, macOS, and Windows (via [WSL][] only). +Lighthouse builds on Linux, macOS, and Windows (native Windows support in +BETA, we also support Windows via [WSL][]). -Compilation should be easy. In fact, if you already have Rust installed all you -need is: +Compilation should be easy. In fact, if you already have Rust and the build +dependencies installed, all you need is: - `git clone https://github.com/sigp/lighthouse.git` - `cd lighthouse` @@ -26,35 +27,45 @@ directory will be the location you cloned Lighthouse to during the installation - `git checkout ${VERSION}` - `make` + ## Detailed Instructions -1. Install Rust and Cargo with [rustup](https://rustup.rs/). - - Use the `stable` toolchain (it's the default). - - Check the [Troubleshooting](#troubleshooting) section for additional - dependencies (e.g., `cmake`). +1. Install the build dependencies for your platform + - Check the [Dependencies](#dependencies) section for additional + information. 1. Clone the Lighthouse repository. - Run `$ git clone https://github.com/sigp/lighthouse.git` - Change into the newly created directory with `$ cd lighthouse` 1. Build Lighthouse with `$ make`. -1. Installation was successful if `$ lighthouse --help` displays the - command-line documentation. +1. The build was successful if the `lighthouse` binary exists in the `target/release` directory and `$ ./target/release/lighthouse --help` displays the command-line documentation. > First time compilation may take several minutes. If you experience any > failures, please reach out on [discord](https://discord.gg/cyAszAh) or > [create an issue](https://github.com/sigp/lighthouse/issues/new). -## Windows Support -Compiling or running Lighthouse natively on Windows is not currently supported. However, -Lighthouse can run successfully under the [Windows Subsystem for Linux (WSL)][WSL]. If using -Ubuntu under WSL, you can should install the Ubuntu dependencies listed in the [Dependencies -(Ubuntu)](#dependencies-ubuntu) section. +## Dependencies -[WSL]: https://docs.microsoft.com/en-us/windows/wsl/about +#### Installing Rust -## Troubleshooting +The best way to install Rust (regardless of platform) is usually with [rustup](https://rustup.rs/) +- Use the `stable` toolchain (it's the default). + +#### Windows Support + +These instructions are for compiling or running Lighthouse natively on Windows, which is currently in +BETA testing. Lighthouse can also run successfully under the [Windows Subsystem for Linux (WSL)][WSL]. +If using Ubuntu under WSL, you should follow the instructions for Ubuntu listed in the +[Dependencies (Ubuntu)](#ubuntu) section. -### Dependencies +[WSL]: https://docs.microsoft.com/en-us/windows/wsl/about + +1. Install [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +1. Install [Chocolatey](https://chocolatey.org/install) Package Manager for Windows + - Install `make` via `choco install make` + - Install `cmake` via `choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System'` +1. Note that in Windows, the lighthouse binary will exist at `.\target\release\lighthouse.exe` when + built successfully. #### Ubuntu @@ -71,6 +82,9 @@ You will need `cmake`. You can install via homebrew: brew install cmake + +## Troubleshooting + ### Command is not found Lighthouse will be installed to `CARGO_HOME` or `$HOME/.cargo`. This directory diff --git a/book/src/slasher.md b/book/src/slasher.md index 27f03dcac33..14ce0252438 100644 --- a/book/src/slasher.md +++ b/book/src/slasher.md @@ -12,6 +12,7 @@ of the immaturity of the slasher UX and the extra resources required. * Quad-core CPU * 16 GB RAM * 256 GB solid state storage (in addition to space for the beacon node DB) +- ⚠️ **If you are running natively on Windows**: LMDB will pre-allocate the entire 256 GB for the slasher database ## How to Run diff --git a/lighthouse/tests/beacon_node.rs b/lighthouse/tests/beacon_node.rs index ef1edb77475..d21a4845cd7 100644 --- a/lighthouse/tests/beacon_node.rs +++ b/lighthouse/tests/beacon_node.rs @@ -681,6 +681,7 @@ fn compact_db_flag() { fn slasher_flag() { CommandLineTest::new() .flag("slasher", None) + .flag("slasher-max-db-size", Some("16")) .run() .with_config_and_dir(|config, dir| { if let Some(slasher_config) = &config.slasher { @@ -699,6 +700,7 @@ fn slasher_dir_flag() { CommandLineTest::new() .flag("slasher", None) .flag("slasher-dir", dir.path().as_os_str().to_str()) + .flag("slasher-max-db-size", Some("16")) .run() .with_config(|config| { if let Some(slasher_config) = &config.slasher { @@ -712,6 +714,7 @@ fn slasher_dir_flag() { fn slasher_update_period_flag() { CommandLineTest::new() .flag("slasher", None) + .flag("slasher-max-db-size", Some("16")) .flag("slasher-update-period", Some("100")) .run() .with_config(|config| { @@ -726,6 +729,7 @@ fn slasher_update_period_flag() { fn slasher_history_length_flag() { CommandLineTest::new() .flag("slasher", None) + .flag("slasher-max-db-size", Some("16")) .flag("slasher-history-length", Some("2048")) .run() .with_config(|config| { @@ -755,6 +759,7 @@ fn slasher_chunk_size_flag() { CommandLineTest::new() .flag("slasher", None) .flag("slasher-chunk-size", Some("32")) + .flag("slasher-max-db-size", Some("16")) .run() .with_config(|config| { let slasher_config = config @@ -768,6 +773,7 @@ fn slasher_chunk_size_flag() { fn slasher_validator_chunk_size_flag() { CommandLineTest::new() .flag("slasher", None) + .flag("slasher-max-db-size", Some("16")) .flag("slasher-validator-chunk-size", Some("512")) .run() .with_config(|config| { @@ -783,6 +789,7 @@ fn slasher_broadcast_flag() { CommandLineTest::new() .flag("slasher", None) .flag("slasher-broadcast", None) + .flag("slasher-max-db-size", Some("16")) .run() .with_config(|config| { let slasher_config = config From 5124fa6ce7a649be59980c576b6220dfeb24c5a8 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Tue, 18 May 2021 20:50:10 -0400 Subject: [PATCH 29/32] Windows shell is so weird.. works in both now --- validator_client/slashing_protection/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/validator_client/slashing_protection/Makefile b/validator_client/slashing_protection/Makefile index 4ef23869096..ae1f2e3d08a 100644 --- a/validator_client/slashing_protection/Makefile +++ b/validator_client/slashing_protection/Makefile @@ -5,12 +5,17 @@ TARBALL := $(OUTPUT_DIR)-$(TESTS_TAG).tar.gz ARCHIVE_URL := https://github.com/eth2-clients/slashing-protection-interchange-tests/tarball/$(TESTS_TAG) ifeq ($(OS),Windows_NT) +ifeq (, $(shell where rm)) rmfile = if exist $(1) (del /F /Q $(1)) rmdir = if exist $(1) (rmdir /Q /S $(1)) else rmfile = rm -f $(1) rmdir = rm -rf $(1) endif +else + rmfile = rm -f $(1) + rmdir = rm -rf $(1) +endif $(OUTPUT_DIR): $(TARBALL) $(call rmdir,$@) From 96d5c07027aa205d8938a01eb9f3ef2bded0a24e Mon Sep 17 00:00:00 2001 From: ethDreamer <37123614+ethDreamer@users.noreply.github.com> Date: Wed, 19 May 2021 09:39:21 -0400 Subject: [PATCH 30/32] Update book/src/slasher.md Co-authored-by: Michael Sproul --- book/src/slasher.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/src/slasher.md b/book/src/slasher.md index 14ce0252438..d4d70567c5f 100644 --- a/book/src/slasher.md +++ b/book/src/slasher.md @@ -12,7 +12,7 @@ of the immaturity of the slasher UX and the extra resources required. * Quad-core CPU * 16 GB RAM * 256 GB solid state storage (in addition to space for the beacon node DB) -- ⚠️ **If you are running natively on Windows**: LMDB will pre-allocate the entire 256 GB for the slasher database +* ⚠️ **If you are running natively on Windows**: LMDB will pre-allocate the entire 256 GB for the slasher database ## How to Run From 339c25b9f3588d11963c41f6ba6f9183da8c2df9 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 19 May 2021 09:43:22 -0400 Subject: [PATCH 31/32] made requested changes to lighthouse book --- book/src/installation-source.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/book/src/installation-source.md b/book/src/installation-source.md index f6059f338d2..864e647ad7e 100644 --- a/book/src/installation-source.md +++ b/book/src/installation-source.md @@ -37,7 +37,7 @@ directory will be the location you cloned Lighthouse to during the installation - Run `$ git clone https://github.com/sigp/lighthouse.git` - Change into the newly created directory with `$ cd lighthouse` 1. Build Lighthouse with `$ make`. -1. The build was successful if the `lighthouse` binary exists in the `target/release` directory and `$ ./target/release/lighthouse --help` displays the command-line documentation. +1. Installation was successful if `$ lighthouse --help` displays the command-line documentation. > First time compilation may take several minutes. If you experience any > failures, please reach out on [discord](https://discord.gg/cyAszAh) or @@ -64,8 +64,6 @@ If using Ubuntu under WSL, you should follow the instructions for Ubuntu listed 1. Install [Chocolatey](https://chocolatey.org/install) Package Manager for Windows - Install `make` via `choco install make` - Install `cmake` via `choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System'` -1. Note that in Windows, the lighthouse binary will exist at `.\target\release\lighthouse.exe` when - built successfully. #### Ubuntu From 80360b8982feb04879fb89f9d316c57c0c986c26 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 19 May 2021 09:56:14 -0400 Subject: [PATCH 32/32] Forgot to use const for OWNER_SID_STR --- testing/remote_signer_test/src/utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/remote_signer_test/src/utils.rs b/testing/remote_signer_test/src/utils.rs index e17c8e9eee2..e1e04f11003 100644 --- a/testing/remote_signer_test/src/utils.rs +++ b/testing/remote_signer_test/src/utils.rs @@ -115,7 +115,7 @@ pub fn unrestrict_permissions(path: &Path) { let path_str = path.to_str().unwrap(); let mut acl = ACL::from_file_path(&path_str, false).unwrap(); - let owner_sid = windows_acl::helper::string_to_sid("S-1-3-4").unwrap(); + let owner_sid = windows_acl::helper::string_to_sid(OWNER_SID_STR).unwrap(); // add single entry for file owner acl.add_entry( owner_sid.as_ptr() as PSID,