Added deterministic keypair generation.
- The Account Manager has a new subcommand, allowing generation of deterministic keys given a particular validator index. - Split functionality in generate_deterministic_keypair function - Fixed up READMEs to reflect new functionality & correct naming.
This commit is contained in:
parent
a46f676f89
commit
177a351462
@ -11,3 +11,4 @@ slog = "^2.2.3"
|
||||
slog-term = "^2.4.0"
|
||||
slog-async = "^2.3.0"
|
||||
validator_client = { path = "../validator_client" }
|
||||
types = { path = "../eth2/types" }
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Lighthouse Accounts Manager
|
||||
# Lighthouse Account Manager
|
||||
|
||||
The accounts manager (AM) is a stand-alone binary which allows
|
||||
The account manager (AM) is a stand-alone binary which allows
|
||||
users to generate and manage the cryptographic keys necessary to
|
||||
interact with Ethereum Serenity.
|
||||
|
||||
@ -21,4 +21,14 @@ staking on Ethereum 1.x (TPD)
|
||||
The AM is not a service, and does not run continuously, nor does it
|
||||
interact with any running services.
|
||||
It is intended to be executed separately from other Lighthouse binaries
|
||||
and produce files which can be consumed by them.
|
||||
and produce files which can be consumed by them.&
|
||||
|
||||
## Usage
|
||||
|
||||
Simply run `./account_manager generate` to generate a new random private key,
|
||||
which will be automatically saved to the correct directory.
|
||||
|
||||
If you prefer to use our "deterministic" keys for testing purposes, simply
|
||||
run `./accounts_manager generate_deterministic -i <index>`, where `index` is
|
||||
the validator index for the key. This will reliably produce the same key each time
|
||||
and save it to the directory.
|
@ -3,6 +3,7 @@ use clap::{App, Arg, SubCommand};
|
||||
use slog::{debug, info, o, Drain};
|
||||
use std::path::PathBuf;
|
||||
use validator_client::Config as ValidatorClientConfig;
|
||||
use types::test_utils::generate_deterministic_keypair;
|
||||
|
||||
fn main() {
|
||||
// Logging
|
||||
@ -29,6 +30,21 @@ fn main() {
|
||||
.version("0.0.1")
|
||||
.author("Sigma Prime <contact@sigmaprime.io>"),
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("generate_deterministic")
|
||||
.about("Generates a deterministic validator private key FOR TESTING")
|
||||
.version("0.0.1")
|
||||
.author("Sigma Prime <contact@sigmaprime.io>")
|
||||
.arg(
|
||||
Arg::with_name("validator index")
|
||||
.long("index")
|
||||
.short("i")
|
||||
.value_name("index")
|
||||
.help("The index of the validator, for which the test key is generated")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
)
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
let config = ValidatorClientConfig::parse_args(&matches, &log)
|
||||
@ -50,7 +66,24 @@ fn main() {
|
||||
keypair.identifier(),
|
||||
key_path.to_string_lossy()
|
||||
);
|
||||
}
|
||||
},
|
||||
("generate_deterministic", Some(gen_d_matches)) => {
|
||||
let validator_index = gen_d_matches
|
||||
.value_of("validator index")
|
||||
.expect("Validator index required.")
|
||||
.parse::<u64>()
|
||||
.expect("Invalid validator index.") as usize;
|
||||
let keypair = generate_deterministic_keypair(validator_index);
|
||||
let key_path: PathBuf = config
|
||||
.save_key(&keypair)
|
||||
.expect("Unable to save newly generated deterministic private key.");
|
||||
debug!(
|
||||
log,
|
||||
"Deterministic Keypair generated {:?}, saved to: {:?}",
|
||||
keypair.identifier(),
|
||||
key_path.to_string_lossy()
|
||||
);
|
||||
},
|
||||
_ => panic!(
|
||||
"The account manager must be run with a subcommand. See help for more information."
|
||||
),
|
||||
|
@ -18,13 +18,17 @@ pub fn generate_deterministic_keypairs(validator_count: usize) -> Vec<Keypair> {
|
||||
let keypairs: Vec<Keypair> = (0..validator_count)
|
||||
.collect::<Vec<usize>>()
|
||||
.par_iter()
|
||||
.map(|&i| {
|
||||
let secret = int_to_bytes48(i as u64 + 1000);
|
||||
let sk = SecretKey::from_bytes(&secret).unwrap();
|
||||
let pk = PublicKey::from_secret_key(&sk);
|
||||
Keypair { sk, pk }
|
||||
})
|
||||
.map(|&i| generate_deterministic_keypair(i))
|
||||
.collect();
|
||||
|
||||
keypairs
|
||||
}
|
||||
|
||||
/// Generates a single deterministic keypair, where the secret key is `validator_index`.
|
||||
///
|
||||
/// This is used for testing only, and not to be used in production!
|
||||
pub fn generate_deterministic_keypair(validator_index: usize) -> Keypair {
|
||||
let secret = int_to_bytes48(validator_index as u64 + 1000);
|
||||
let sk = SecretKey::from_bytes(&secret).unwrap();
|
||||
let pk = PublicKey::from_secret_key(&sk);
|
||||
Keypair { sk, pk }
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ mod testing_transfer_builder;
|
||||
mod testing_voluntary_exit_builder;
|
||||
|
||||
pub use generate_deterministic_keypairs::generate_deterministic_keypairs;
|
||||
pub use generate_deterministic_keypairs::generate_deterministic_keypair;
|
||||
pub use keypairs_file::KeypairsFile;
|
||||
pub use rand::{prng::XorShiftRng, SeedableRng};
|
||||
pub use serde_utils::{fork_from_hex_str, u8_from_hex_str};
|
||||
|
@ -75,8 +75,9 @@ The configuration directory structure looks like:
|
||||
|
||||
Where the hex value of the directory is a portion of the validator public key.
|
||||
|
||||
Validator keys must be generated using the separate `accounts_manager` binary, which will
|
||||
Validator keys must be generated using the separate `account_manager` binary, which will
|
||||
place the keys into this directory structure in a format compatible with the validator client.
|
||||
Be sure to check the readme for `account_manager`.
|
||||
|
||||
The chain specification (slot length, BLS domain, etc.) defaults to foundation
|
||||
parameters, however is temporary and an upgrade will allow these parameters to be
|
||||
|
@ -9,7 +9,7 @@ mod signer;
|
||||
use crate::config::Config as ValidatorClientConfig;
|
||||
use clap::{App, Arg};
|
||||
use protos::services_grpc::ValidatorServiceClient;
|
||||
use service::Service as ValidatorService;
|
||||
use crate::service::Service as ValidatorService;
|
||||
use slog::{error, info, o, Drain};
|
||||
use types::Keypair;
|
||||
|
||||
|
@ -166,11 +166,15 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static> Service<B, S> {
|
||||
|
||||
/* Generate the duties manager */
|
||||
|
||||
// generate keypairs
|
||||
// Load generated keypairs
|
||||
let keypairs = match config.fetch_keys(&log) {
|
||||
Some(kps) => Arc::new(kps),
|
||||
None => panic!("No key pairs found, cannot start validator client without at least one. Try running `./account_manager generate` first.")
|
||||
};
|
||||
|
||||
// TODO: keypairs are randomly generated; they should be loaded from a file or generated.
|
||||
// https://github.com/sigp/lighthouse/issues/160
|
||||
let keypairs = Arc::new(generate_deterministic_keypairs(8));
|
||||
//let keypairs = Arc::new(generate_deterministic_keypairs(8));
|
||||
|
||||
// Builds a mapping of Epoch -> Map(PublicKey, EpochDuty)
|
||||
// where EpochDuty contains slot numbers and attestation data that each validator needs to
|
||||
|
Loading…
Reference in New Issue
Block a user