Fix local testnet scripts (#2229)

## Issue Addressed

Resolves #2094 

## Proposed Changes

Fixes scripts for creating local testnets. Adds an option in `lighthouse boot_node` to run with a previously generated enr.
This commit is contained in:
Pawan Dhananjay
2021-03-30 05:17:58 +00:00
parent 9eb1945136
commit 95a362213d
18 changed files with 360 additions and 141 deletions

View File

@@ -37,3 +37,5 @@ lighthouse_version = { path = "../common/lighthouse_version" }
directory = { path = "../common/directory" }
account_utils = { path = "../common/account_utils" }
eth2_wallet = { path = "../crypto/eth2_wallet" }
web3 = "0.14.0"
eth1_test_rig = { path = "../testing/eth1_test_rig" }

View File

@@ -0,0 +1,33 @@
use clap::ArgMatches;
use environment::Environment;
use types::EthSpec;
use web3::{transports::Http, Web3};
pub fn run<T: EthSpec>(env: Environment<T>, matches: &ArgMatches<'_>) -> Result<(), String> {
let eth1_http: String = clap_utils::parse_required(matches, "eth1-http")?;
let confirmations: usize = clap_utils::parse_required(matches, "confirmations")?;
let validator_count: Option<usize> = clap_utils::parse_optional(matches, "validator-count")?;
let transport =
Http::new(&eth1_http).map_err(|e| format!("Unable to connect to eth1 HTTP: {:?}", e))?;
let web3 = Web3::new(transport);
env.runtime().block_on(async {
let contract = eth1_test_rig::DepositContract::deploy(web3, confirmations, None)
.await
.map_err(|e| format!("Failed to deploy deposit contract: {:?}", e))?;
println!("Deposit contract address: {:?}", contract.address());
// Deposit insecure validators to the deposit contract created
if let Some(validator_count) = validator_count {
let amount = env.eth2_config.spec.max_effective_balance;
for i in 0..validator_count {
println!("Submitting deposit for validator {}...", i);
contract.deposit_deterministic_async::<T>(i, amount).await?;
}
}
Ok(())
})
}

View File

@@ -3,11 +3,13 @@ use std::fs;
use std::path::PathBuf;
use validator_dir::Builder as ValidatorBuilder;
pub fn run(matches: &ArgMatches) -> Result<(), String> {
let validator_count: usize = clap_utils::parse_required(matches, "count")?;
let validators_dir: PathBuf = clap_utils::parse_required(matches, "validators-dir")?;
let secrets_dir: PathBuf = clap_utils::parse_required(matches, "secrets-dir")?;
/// Generates validator directories with INSECURE, deterministic keypairs given the range
/// of indices, validator and secret directories.
pub fn generate_validator_dirs(
indices: &[usize],
validators_dir: PathBuf,
secrets_dir: PathBuf,
) -> Result<(), String> {
if !validators_dir.exists() {
fs::create_dir_all(&validators_dir)
.map_err(|e| format!("Unable to create validators dir: {:?}", e))?;
@@ -18,13 +20,13 @@ pub fn run(matches: &ArgMatches) -> Result<(), String> {
.map_err(|e| format!("Unable to create secrets dir: {:?}", e))?;
}
for i in 0..validator_count {
println!("Validator {}/{}", i + 1, validator_count);
for i in indices {
println!("Validator {}", i + 1);
ValidatorBuilder::new(validators_dir.clone())
.password_dir(secrets_dir.clone())
.store_withdrawal_keystore(false)
.insecure_voting_keypair(i)
.insecure_voting_keypair(*i)
.map_err(|e| format!("Unable to generate keys: {:?}", e))?
.build()
.map_err(|e| format!("Unable to build validator: {:?}", e))?;
@@ -32,3 +34,31 @@ pub fn run(matches: &ArgMatches) -> Result<(), String> {
Ok(())
}
pub fn run(matches: &ArgMatches) -> Result<(), String> {
let validator_count: usize = clap_utils::parse_required(matches, "count")?;
let base_dir: PathBuf = clap_utils::parse_required(matches, "base-dir")?;
let node_count: Option<usize> = clap_utils::parse_optional(matches, "node-count")?;
if let Some(node_count) = node_count {
let validators_per_node = validator_count / node_count;
let validator_range = (0..validator_count).collect::<Vec<_>>();
let indices_range = validator_range
.chunks(validators_per_node)
.collect::<Vec<_>>();
for (i, indices) in indices_range.iter().enumerate() {
let validators_dir = base_dir.join(format!("node_{}", i + 1)).join("validators");
let secrets_dir = base_dir.join(format!("node_{}", i + 1)).join("secrets");
generate_validator_dirs(indices, validators_dir, secrets_dir)?;
}
} else {
let validators_dir = base_dir.join("validators");
let secrets_dir = base_dir.join("secrets");
generate_validator_dirs(
(0..validator_count).collect::<Vec<_>>().as_slice(),
validators_dir,
secrets_dir,
)?;
}
Ok(())
}

View File

@@ -2,6 +2,7 @@
extern crate log;
mod change_genesis_time;
mod check_deposit_data;
mod deploy_deposit_contract;
mod eth1_genesis;
mod generate_bootnode_enr;
mod insecure_validators;
@@ -155,6 +156,38 @@ fn main() {
.help("SSZ encoded as 0x-prefixed hex"),
),
)
.subcommand(
SubCommand::with_name("deploy-deposit-contract")
.about(
"Deploy a testing eth1 deposit contract.",
)
.arg(
Arg::with_name("eth1-http")
.long("eth1-http")
.short("e")
.value_name("ETH1_HTTP_PATH")
.help("Path to an Eth1 JSON-RPC IPC endpoint")
.takes_value(true)
.required(true)
)
.arg(
Arg::with_name("confirmations")
.value_name("INTEGER")
.long("confirmations")
.takes_value(true)
.default_value("3")
.help("The number of block confirmations before declaring the contract deployed."),
)
.arg(
Arg::with_name("validator-count")
.value_name("VALIDATOR_COUNT")
.long("validator-count")
.takes_value(true)
.help("If present, makes `validator_count` number of INSECURE deterministic deposits after \
deploying the deposit contract."
),
)
)
.subcommand(
SubCommand::with_name("eth1-genesis")
.about("Listens to the eth1 chain and finds the genesis beacon state")
@@ -343,6 +376,20 @@ fn main() {
non-default.",
),
)
.arg(
Arg::with_name("seconds-per-eth1-block")
.long("seconds-per-eth1-block")
.value_name("SECONDS")
.takes_value(true)
.help("Eth1 block time"),
)
.arg(
Arg::with_name("eth1-id")
.long("eth1-id")
.value_name("ETH1_ID")
.takes_value(true)
.help("The chain id and network id for the eth1 testnet."),
)
.arg(
Arg::with_name("deposit-contract-address")
.long("deposit-contract-address")
@@ -446,19 +493,19 @@ fn main() {
.help("Produces validators in the range of 0..count."),
)
.arg(
Arg::with_name("validators-dir")
.long("validators-dir")
.value_name("VALIDATOR_DIR")
Arg::with_name("base-dir")
.long("base-dir")
.value_name("BASE_DIR")
.takes_value(true)
.help("The directory for storing validators."),
.help("The base directory where validator keypairs and secrets are stored"),
)
.arg(
Arg::with_name("secrets-dir")
.long("secrets-dir")
.value_name("SECRETS_DIR")
Arg::with_name("node-count")
.long("node-count")
.value_name("NODE_COUNT")
.takes_value(true)
.help("The directory for storing secrets."),
),
.help("The number of nodes to divide the validator keys to"),
)
)
.get_matches();
@@ -540,6 +587,10 @@ fn run<T: EthSpec>(
("pretty-hex", Some(matches)) => {
run_parse_hex::<T>(matches).map_err(|e| format!("Failed to pretty print hex: {}", e))
}
("deploy-deposit-contract", Some(matches)) => {
deploy_deposit_contract::run::<T>(env, matches)
.map_err(|e| format!("Failed to run deploy-deposit-contract command: {}", e))
}
("eth1-genesis", Some(matches)) => eth1_genesis::run::<T>(env, matches)
.map_err(|e| format!("Failed to run eth1-genesis command: {}", e)),
("interop-genesis", Some(matches)) => interop_genesis::run::<T>(env, matches)

View File

@@ -48,6 +48,9 @@ pub fn run<T: EthSpec>(matches: &ArgMatches) -> Result<(), String> {
maybe_update!("ejection-balance", ejection_balance);
maybe_update!("eth1-follow-distance", eth1_follow_distance);
maybe_update!("genesis-delay", genesis_delay);
maybe_update!("eth1-id", deposit_chain_id);
maybe_update!("eth1-id", deposit_network_id);
maybe_update!("seconds-per-eth1-block", seconds_per_eth1_block);
if let Some(v) = parse_ssz_optional(matches, "genesis-fork-version")? {
spec.genesis_fork_version = v;