Update for clippy 1.50 (#2193)
## Issue Addressed
NA
## Proposed Changes
Rust 1.50 has landed 🎉
The shiny new `clippy` peers down upon us mere mortals with disgust. Brutish peasants wrapping our `usize`s in superfluous `Option`s... tsk tsk.
I've performed the goat sacrifice and corrected our evil ways in this PR. Tonight we shall pray that Github Actions bestows the almighty green tick upon us.
## Additional Info
NA
Co-authored-by: realbigsean <seananderson33@gmail.com>
Co-authored-by: Michael Sproul <michael@sigmaprime.io>
This commit is contained in:
parent
e2ff9c66a1
commit
8e5c20b6d1
20
.github/workflows/test-suite.yml
vendored
20
.github/workflows/test-suite.yml
vendored
@ -24,6 +24,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Get latest version of stable Rust
|
||||
run: rustup update stable
|
||||
- name: Get latest version of stable Rust
|
||||
run: rustup update stable
|
||||
- name: Check formatting with cargo fmt
|
||||
@ -78,6 +80,8 @@ jobs:
|
||||
needs: cargo-fmt
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Get latest version of stable Rust
|
||||
run: rustup update stable
|
||||
- name: Build the root Dockerfile
|
||||
run: docker build .
|
||||
eth1-simulator-ubuntu:
|
||||
@ -86,6 +90,8 @@ jobs:
|
||||
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: Run the beacon chain sim that starts from an eth1 contract
|
||||
@ -96,6 +102,8 @@ jobs:
|
||||
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: Run the beacon chain sim without an eth1 connection
|
||||
@ -106,6 +114,8 @@ jobs:
|
||||
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: Run the syncing simulator
|
||||
@ -116,6 +126,8 @@ jobs:
|
||||
needs: cargo-fmt
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Get latest version of stable Rust
|
||||
run: rustup update stable
|
||||
- name: Typecheck benchmark code without running it
|
||||
run: make check-benches
|
||||
check-consensus:
|
||||
@ -124,6 +136,8 @@ jobs:
|
||||
needs: cargo-fmt
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Get latest version of stable Rust
|
||||
run: rustup update stable
|
||||
- name: Typecheck consensus code in strict mode
|
||||
run: make check-consensus
|
||||
clippy:
|
||||
@ -132,6 +146,8 @@ jobs:
|
||||
needs: cargo-fmt
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Get latest version of stable Rust
|
||||
run: rustup update stable
|
||||
- name: Lint code for quality and style with Clippy
|
||||
run: make lint
|
||||
- name: Certify Cargo.lock freshness
|
||||
@ -142,6 +158,8 @@ jobs:
|
||||
needs: cargo-fmt
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Get latest version of stable Rust
|
||||
run: rustup update stable
|
||||
- name: Validate state_processing feature arbitrary-fuzz
|
||||
run: make arbitrary-fuzz
|
||||
cargo-audit:
|
||||
@ -150,6 +168,8 @@ jobs:
|
||||
needs: cargo-fmt
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Get latest version of stable Rust
|
||||
run: rustup update stable
|
||||
- name: Run cargo audit to identify known security vulnerabilities reported to the RustSec Advisory Database
|
||||
run: make audit
|
||||
cargo-udeps:
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM rust:1.47.0 AS builder
|
||||
FROM rust:1.50.0 AS builder
|
||||
RUN apt-get update && apt-get install -y cmake
|
||||
COPY . lighthouse
|
||||
ARG PORTABLE
|
||||
|
@ -29,7 +29,7 @@ pub fn read_mnemonic_from_cli(
|
||||
})
|
||||
})?,
|
||||
None => loop {
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
eprintln!("{}", MNEMONIC_PROMPT);
|
||||
|
||||
let mnemonic = read_input_from_user(stdin_inputs)?;
|
||||
@ -37,7 +37,7 @@ pub fn read_mnemonic_from_cli(
|
||||
match Mnemonic::from_phrase(mnemonic.as_str(), Language::English) {
|
||||
Ok(mnemonic_m) => {
|
||||
eprintln!("Valid mnemonic provided.");
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
sleep(Duration::from_secs(1));
|
||||
break mnemonic_m;
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ pub fn read_wallet_password_from_cli(
|
||||
.map_err(|e| format!("Unable to read {:?}: {:?}", path, e))
|
||||
.map(|bytes| strip_off_newlines(bytes).into()),
|
||||
None => {
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
eprintln!("{}", WALLET_PASSWORD_PROMPT);
|
||||
let password =
|
||||
PlainText::from(read_password_from_user(stdin_inputs)?.as_ref().to_vec());
|
||||
|
@ -280,7 +280,7 @@ fn load_voting_keypair(
|
||||
.map_err(|e| format!("Error while decrypting keypair: {:?}", e))
|
||||
} else {
|
||||
// Prompt password from user.
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
eprintln!(
|
||||
"{} for validator in {:?}: ",
|
||||
PASSWORD_PROMPT, voting_keystore_path
|
||||
@ -289,7 +289,7 @@ fn load_voting_keypair(
|
||||
match keystore.decrypt_keypair(password.as_ref()) {
|
||||
Ok(keypair) => {
|
||||
eprintln!("Password is correct.");
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
std::thread::sleep(std::time::Duration::from_secs(1)); // Provides nicer UX.
|
||||
Ok(keypair)
|
||||
}
|
||||
|
@ -135,12 +135,12 @@ pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), Strin
|
||||
let keystore = Keystore::from_json_file(src_keystore)
|
||||
.map_err(|e| format!("Unable to read keystore JSON {:?}: {:?}", src_keystore, e))?;
|
||||
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
eprintln!("Keystore found at {:?}:", src_keystore);
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
eprintln!(" - Public key: 0x{}", keystore.pubkey());
|
||||
eprintln!(" - UUID: {}", keystore.uuid());
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
eprintln!(
|
||||
"If you enter the password it will be stored as plain-text in {} so that it is not \
|
||||
required each time the validator client starts.",
|
||||
@ -152,7 +152,7 @@ pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), Strin
|
||||
eprintln!("Reuse previous password.");
|
||||
break Some(password);
|
||||
}
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
eprintln!("{}", PASSWORD_PROMPT);
|
||||
|
||||
let password = read_password_from_user(stdin_inputs)?;
|
||||
@ -166,7 +166,7 @@ pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), Strin
|
||||
match keystore.decrypt_keypair(password.as_ref()) {
|
||||
Ok(_) => {
|
||||
eprintln!("Password is correct.");
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
sleep(Duration::from_secs(1)); // Provides nicer UX.
|
||||
if reuse_password {
|
||||
previous_password = Some(password.clone());
|
||||
@ -234,13 +234,13 @@ pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), Strin
|
||||
eprintln!("Successfully updated {}.", CONFIG_FILENAME);
|
||||
}
|
||||
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
eprintln!(
|
||||
"Successfully imported {} validators ({} skipped).",
|
||||
num_imported_keystores,
|
||||
keystore_paths.len() - num_imported_keystores
|
||||
);
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
eprintln!("WARNING: {}", KEYSTORE_REUSE_WARNING);
|
||||
|
||||
Ok(())
|
||||
|
@ -93,9 +93,9 @@ pub fn cli_run(matches: &ArgMatches, validator_dir: PathBuf) -> Result<(), Strin
|
||||
ensure_dir_exists(&validator_dir)?;
|
||||
ensure_dir_exists(&secrets_dir)?;
|
||||
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
eprintln!("WARNING: KEY RECOVERY CAN LEAD TO DUPLICATING VALIDATORS KEYS, WHICH CAN LEAD TO SLASHING.");
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
|
||||
let mnemonic = read_mnemonic_from_cli(mnemonic_path, stdin_inputs)?;
|
||||
|
||||
|
@ -215,7 +215,7 @@ pub fn read_new_wallet_password_from_cli(
|
||||
Ok(password)
|
||||
}
|
||||
None => loop {
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
eprintln!("{}", NEW_WALLET_PASSWORD_PROMPT);
|
||||
let password =
|
||||
PlainText::from(read_password_from_user(stdin_inputs)?.as_ref().to_vec());
|
||||
|
@ -63,9 +63,9 @@ pub fn cli_run(matches: &ArgMatches, wallet_base_dir: PathBuf) -> Result<(), Str
|
||||
let mnemonic_path: Option<PathBuf> = clap_utils::parse_optional(matches, MNEMONIC_FLAG)?;
|
||||
let stdin_inputs = matches.is_present(STDIN_INPUTS_FLAG);
|
||||
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
eprintln!("WARNING: KEY RECOVERY CAN LEAD TO DUPLICATING VALIDATORS KEYS, WHICH CAN LEAD TO SLASHING.");
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
|
||||
let mnemonic = read_mnemonic_from_cli(mnemonic_path, stdin_inputs)?;
|
||||
|
||||
|
@ -893,7 +893,7 @@ impl<TSpec: EthSpec> Behaviour<TSpec> {
|
||||
}
|
||||
|
||||
// perform gossipsub score updates when necessary
|
||||
while let Poll::Ready(_) = self.update_gossipsub_scores.poll_tick(cx) {
|
||||
while self.update_gossipsub_scores.poll_tick(cx).is_ready() {
|
||||
self.peer_manager.update_gossipsub_scores(&self.gossipsub);
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ pub trait EnrExt {
|
||||
/// Extend ENR CombinedPublicKey for libp2p types.
|
||||
pub trait CombinedKeyPublicExt {
|
||||
/// Converts the publickey into a peer id, without consuming the key.
|
||||
fn into_peer_id(&self) -> PeerId;
|
||||
fn as_peer_id(&self) -> PeerId;
|
||||
}
|
||||
|
||||
/// Extend ENR CombinedKey for conversion to libp2p keys.
|
||||
@ -41,7 +41,7 @@ pub trait CombinedKeyExt {
|
||||
impl EnrExt for Enr {
|
||||
/// The libp2p `PeerId` for the record.
|
||||
fn peer_id(&self) -> PeerId {
|
||||
self.public_key().into_peer_id()
|
||||
self.public_key().as_peer_id()
|
||||
}
|
||||
|
||||
/// Returns a list of multiaddrs if the ENR has an `ip` and either a `tcp` or `udp` key **or** an `ip6` and either a `tcp6` or `udp6`.
|
||||
@ -195,7 +195,7 @@ impl CombinedKeyPublicExt for CombinedPublicKey {
|
||||
/// Converts the publickey into a peer id, without consuming the key.
|
||||
///
|
||||
/// This is only available with the `libp2p` feature flag.
|
||||
fn into_peer_id(&self) -> PeerId {
|
||||
fn as_peer_id(&self) -> PeerId {
|
||||
match self {
|
||||
Self::Secp256k1(pk) => {
|
||||
let pk_bytes = pk.to_bytes();
|
||||
|
@ -972,7 +972,7 @@ impl<TSpec: EthSpec> Stream for PeerManager<TSpec> {
|
||||
|
||||
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
||||
// perform the heartbeat when necessary
|
||||
while let Poll::Ready(_) = self.heartbeat.poll_tick(cx) {
|
||||
while self.heartbeat.poll_tick(cx).is_ready() {
|
||||
self.heartbeat();
|
||||
}
|
||||
|
||||
|
@ -240,7 +240,7 @@ impl Future for RPCRateLimiter {
|
||||
type Output = ();
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
while let Poll::Ready(_) = self.prune_interval.poll_tick(cx) {
|
||||
while self.prune_interval.poll_tick(cx).is_ready() {
|
||||
self.prune();
|
||||
}
|
||||
|
||||
|
@ -584,13 +584,13 @@ impl<T: BeaconChainTypes> AttestationService<T> {
|
||||
/// We don't keep track of a specific validator to random subnet, rather the ratio of active
|
||||
/// validators to random subnets. So when a validator goes offline, we can simply remove the
|
||||
/// allocated amount of random subnets.
|
||||
fn handle_known_validator_expiry(&mut self) -> Result<(), ()> {
|
||||
fn handle_known_validator_expiry(&mut self) {
|
||||
let spec = &self.beacon_chain.spec;
|
||||
let subnet_count = spec.attestation_subnet_count;
|
||||
let random_subnets_per_validator = spec.random_subnets_per_validator;
|
||||
if self.known_validators.len() as u64 * random_subnets_per_validator >= subnet_count {
|
||||
// have too many validators, ignore
|
||||
return Ok(());
|
||||
return;
|
||||
}
|
||||
|
||||
let subscribed_subnets = self.random_subnets.keys().cloned().collect::<Vec<_>>();
|
||||
@ -616,7 +616,6 @@ impl<T: BeaconChainTypes> AttestationService<T> {
|
||||
.push_back(AttServiceMessage::EnrRemove(*subnet_id));
|
||||
self.random_subnets.remove(subnet_id);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,11 @@ async fn subscribe_current_slot_wait_for_unsubscribe() {
|
||||
let events = get_events(&mut attestation_service, None, 1).await;
|
||||
assert_matches!(
|
||||
events[..3],
|
||||
[AttServiceMessage::DiscoverPeers(_), AttServiceMessage::Subscribe(_any1), AttServiceMessage::EnrAdd(_any3)]
|
||||
[
|
||||
AttServiceMessage::DiscoverPeers(_),
|
||||
AttServiceMessage::Subscribe(_any1),
|
||||
AttServiceMessage::EnrAdd(_any3)
|
||||
]
|
||||
);
|
||||
|
||||
// If the long lived and short lived subnets are the same, there should be no more events
|
||||
@ -281,7 +285,11 @@ async fn test_same_subnet_unsubscription() {
|
||||
let events = get_events(&mut attestation_service, None, 1).await;
|
||||
assert_matches!(
|
||||
events[..3],
|
||||
[AttServiceMessage::DiscoverPeers(_), AttServiceMessage::Subscribe(_any1), AttServiceMessage::EnrAdd(_any3)]
|
||||
[
|
||||
AttServiceMessage::DiscoverPeers(_),
|
||||
AttServiceMessage::Subscribe(_any1),
|
||||
AttServiceMessage::EnrAdd(_any3)
|
||||
]
|
||||
);
|
||||
|
||||
let expected = AttServiceMessage::Subscribe(subnet_id1);
|
||||
|
@ -52,11 +52,7 @@ pub fn construct_upnp_mappings<T: EthSpec>(
|
||||
// Just use the first IP of the first interface that is not a loopback and not an
|
||||
// ipv6 address.
|
||||
if !interface.is_loopback() {
|
||||
if let IpAddr::V4(_) = interface.ip() {
|
||||
Some(interface.ip())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
interface.ip().is_ipv4().then(|| interface.ip())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ impl<T: BeaconChainTypes> NetworkService<T> {
|
||||
log: network_log,
|
||||
};
|
||||
|
||||
spawn_service(executor, network_service)?;
|
||||
spawn_service(executor, network_service);
|
||||
|
||||
Ok((network_globals, network_send))
|
||||
}
|
||||
@ -228,7 +228,7 @@ impl<T: BeaconChainTypes> NetworkService<T> {
|
||||
fn spawn_service<T: BeaconChainTypes>(
|
||||
executor: task_executor::TaskExecutor,
|
||||
mut service: NetworkService<T>,
|
||||
) -> error::Result<()> {
|
||||
) {
|
||||
let mut exit_rx = executor.exit();
|
||||
let mut shutdown_sender = executor.shutdown_sender();
|
||||
|
||||
@ -570,8 +570,6 @@ fn spawn_service<T: BeaconChainTypes>(
|
||||
metrics::update_bandwidth_metrics(service.libp2p.bandwidth.clone());
|
||||
}
|
||||
}, "network");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns a `Sleep` that triggers shortly after the next change in the beacon chain fork version.
|
||||
|
@ -156,14 +156,14 @@ where
|
||||
get_pubkey(proposer_index)
|
||||
.ok_or_else(|| Error::ValidatorUnknown(proposer_index as u64))?,
|
||||
spec,
|
||||
)?,
|
||||
),
|
||||
block_header_signature_set(
|
||||
state,
|
||||
&proposer_slashing.signed_header_2,
|
||||
get_pubkey(proposer_index)
|
||||
.ok_or_else(|| Error::ValidatorUnknown(proposer_index as u64))?,
|
||||
spec,
|
||||
)?,
|
||||
),
|
||||
))
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ fn block_header_signature_set<'a, T: EthSpec>(
|
||||
signed_header: &'a SignedBeaconBlockHeader,
|
||||
pubkey: Cow<'a, PublicKey>,
|
||||
spec: &'a ChainSpec,
|
||||
) -> Result<SignatureSet<'a>> {
|
||||
) -> SignatureSet<'a> {
|
||||
let domain = spec.get_domain(
|
||||
signed_header.message.slot.epoch(T::slots_per_epoch()),
|
||||
Domain::BeaconProposer,
|
||||
@ -183,11 +183,7 @@ fn block_header_signature_set<'a, T: EthSpec>(
|
||||
|
||||
let message = signed_header.message.signing_root(domain);
|
||||
|
||||
Ok(SignatureSet::single_pubkey(
|
||||
&signed_header.signature,
|
||||
pubkey,
|
||||
message,
|
||||
))
|
||||
SignatureSet::single_pubkey(&signed_header.signature, pubkey, message)
|
||||
}
|
||||
|
||||
/// Returns the signature set for the given `indexed_attestation`.
|
||||
|
@ -35,18 +35,22 @@ pub fn compute_shuffled_index(
|
||||
let mut index = index;
|
||||
for round in 0..shuffle_round_count {
|
||||
let pivot = bytes_to_int64(&hash_with_round(seed, round)[..]) as usize % list_size;
|
||||
index = do_round(seed, index, pivot, round, list_size)?;
|
||||
index = do_round(seed, index, pivot, round, list_size);
|
||||
}
|
||||
Some(index)
|
||||
}
|
||||
|
||||
fn do_round(seed: &[u8], index: usize, pivot: usize, round: u8, list_size: usize) -> Option<usize> {
|
||||
fn do_round(seed: &[u8], index: usize, pivot: usize, round: u8, list_size: usize) -> usize {
|
||||
let flip = (pivot + (list_size - index)) % list_size;
|
||||
let position = max(index, flip);
|
||||
let source = hash_with_round_and_position(seed, round, position);
|
||||
let byte = source[(position % 256) / 8];
|
||||
let bit = (byte >> (position % 8)) % 2;
|
||||
Some(if bit == 1 { flip } else { index })
|
||||
if bit == 1 {
|
||||
flip
|
||||
} else {
|
||||
index
|
||||
}
|
||||
}
|
||||
|
||||
fn hash_with_round_and_position(seed: &[u8], round: u8, position: usize) -> Hash256 {
|
||||
|
@ -10,7 +10,9 @@ use tree_hash_derive::TreeHash;
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
|
||||
#[derive(Derivative, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
|
||||
#[derive(
|
||||
Derivative, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
|
||||
)]
|
||||
#[derivative(PartialEq, Eq, Hash(bound = "T: EthSpec"))]
|
||||
#[serde(bound = "T: EthSpec")]
|
||||
pub struct AttesterSlashing<T: EthSpec> {
|
||||
|
@ -13,7 +13,9 @@ use tree_hash_derive::TreeHash;
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
|
||||
#[derive(Derivative, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
|
||||
#[derive(
|
||||
Derivative, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
|
||||
)]
|
||||
#[derivative(PartialEq, Eq)] // to satisfy Clippy's lint about `Hash`
|
||||
#[serde(bound = "T: EthSpec")]
|
||||
pub struct IndexedAttestation<T: EthSpec> {
|
||||
|
@ -14,7 +14,9 @@ use tree_hash_derive::TreeHash;
|
||||
///
|
||||
/// Spec v0.12.1
|
||||
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
|
||||
#[derive(Derivative, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom)]
|
||||
#[derive(
|
||||
Derivative, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
|
||||
)]
|
||||
#[derivative(PartialEq, Eq)]
|
||||
pub struct SignedBeaconBlockHeader {
|
||||
pub message: BeaconBlockHeader,
|
||||
|
@ -238,29 +238,29 @@ fn unlock_keystore_via_stdin_password(
|
||||
keystore: &Keystore,
|
||||
keystore_path: &PathBuf,
|
||||
) -> Result<(ZeroizeString, Keypair), Error> {
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
eprintln!(
|
||||
"The {} file does not contain either of the following fields for {:?}:",
|
||||
CONFIG_FILENAME, keystore_path
|
||||
);
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
eprintln!(" - voting_keystore_password");
|
||||
eprintln!(" - voting_keystore_password_path");
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
eprintln!(
|
||||
"You may exit and update {} or enter a password. \
|
||||
If you choose to enter a password now then this prompt \
|
||||
will be raised next time the validator is started.",
|
||||
CONFIG_FILENAME
|
||||
);
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
eprintln!("Enter password (or press Ctrl+c to exit):");
|
||||
|
||||
loop {
|
||||
let password =
|
||||
read_password_from_user(USE_STDIN).map_err(Error::UnableToReadPasswordFromUser)?;
|
||||
|
||||
eprintln!("");
|
||||
eprintln!();
|
||||
|
||||
match keystore.decrypt_keypair(password.as_ref()) {
|
||||
Ok(keystore) => break Ok((password, keystore)),
|
||||
|
Loading…
Reference in New Issue
Block a user