From 314780e634aa471e82af81f180582521b62e667e Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Thu, 29 Aug 2019 14:59:32 +1000 Subject: [PATCH] Allow for customizable recent genesis window --- .../beacon_chain/src/beacon_chain_builder.rs | 15 ++++++++++----- beacon_node/client/src/config.rs | 5 ++++- beacon_node/client/src/lib.rs | 12 +++++++++--- beacon_node/src/config.rs | 7 +++++++ beacon_node/src/main.rs | 8 +++++++- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain_builder.rs b/beacon_node/beacon_chain/src/beacon_chain_builder.rs index 79c74b006..223d99d8d 100644 --- a/beacon_node/beacon_chain/src/beacon_chain_builder.rs +++ b/beacon_node/beacon_chain/src/beacon_chain_builder.rs @@ -22,8 +22,13 @@ pub struct BeaconChainBuilder { } impl BeaconChainBuilder { - pub fn recent_genesis(validator_count: usize, spec: ChainSpec, log: Logger) -> Self { - Self::quick_start(recent_genesis_time(), validator_count, spec, log) + pub fn recent_genesis( + validator_count: usize, + minutes: u64, + spec: ChainSpec, + log: Logger, + ) -> Self { + Self::quick_start(recent_genesis_time(minutes), validator_count, spec, log) } pub fn quick_start( @@ -123,12 +128,12 @@ fn genesis_block(genesis_state: &BeaconState, spec: &ChainSpec) - /// Returns the system time, mod 30 minutes. /// /// Used for easily creating testnets. -fn recent_genesis_time() -> u64 { +fn recent_genesis_time(minutes: u64) -> u64 { let now = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) .unwrap() .as_secs(); - let secs_after_last_period = now.checked_rem(30 * 60).unwrap_or(0); - // genesis is now the last 30 minute block. + let secs_after_last_period = now.checked_rem(minutes * 60).unwrap_or(0); + // genesis is now the last 15 minute block. now - secs_after_last_period } diff --git a/beacon_node/client/src/config.rs b/beacon_node/client/src/config.rs index f2725b3e7..3aed26881 100644 --- a/beacon_node/client/src/config.rs +++ b/beacon_node/client/src/config.rs @@ -42,7 +42,10 @@ pub enum BeaconChainStartMethod { /// Create a new beacon chain that can connect to mainnet. /// /// Set the genesis time to be the start of the previous 30-minute window. - RecentGenesis { validator_count: usize }, + RecentGenesis { + validator_count: usize, + minutes: u64, + }, /// Create a new beacon chain with `genesis_time` and `validator_count` validators, all with well-known /// secret keys. Generated { diff --git a/beacon_node/client/src/lib.rs b/beacon_node/client/src/lib.rs index 67528e2f9..4554ff9a1 100644 --- a/beacon_node/client/src/lib.rs +++ b/beacon_node/client/src/lib.rs @@ -88,9 +88,15 @@ where crit!(log, "No mainnet beacon chain startup specification."); return Err("Mainnet is not yet specified. We're working on it.".into()); } - BeaconChainStartMethod::RecentGenesis { validator_count } => { - BeaconChainBuilder::recent_genesis(*validator_count, spec.clone(), log.clone()) - } + BeaconChainStartMethod::RecentGenesis { + validator_count, + minutes, + } => BeaconChainBuilder::recent_genesis( + *validator_count, + *minutes, + spec.clone(), + log.clone(), + ), BeaconChainStartMethod::Generated { validator_count, genesis_time, diff --git a/beacon_node/src/config.rs b/beacon_node/src/config.rs index e76bd48fa..7c471e8ac 100644 --- a/beacon_node/src/config.rs +++ b/beacon_node/src/config.rs @@ -120,8 +120,15 @@ fn process_testnet_subcommand( .parse::() .map_err(|e| format!("Unable to parse validator_count: {:?}", e))?; + let minutes = cli_args + .value_of("minutes") + .ok_or_else(|| "No recent genesis minutes supplied")? + .parse::() + .map_err(|e| format!("Unable to parse minutes: {:?}", e))?; + builder.set_beacon_chain_start_method(BeaconChainStartMethod::RecentGenesis { validator_count, + minutes, }) } _ => return Err("No testnet method specified. See 'testnet --help'.".into()), diff --git a/beacon_node/src/main.rs b/beacon_node/src/main.rs index aba44e6fe..5bfb71215 100644 --- a/beacon_node/src/main.rs +++ b/beacon_node/src/main.rs @@ -259,11 +259,17 @@ fn main() { */ .subcommand(SubCommand::with_name("recent") .about("Creates a new genesis state where the genesis time was at the previous \ - 30-minute boundary (e.g., 12:00, 12:30, 13:00, etc.)") + MINUTES boundary (e.g., when MINUTES == 30; 12:00, 12:30, 13:00, etc.)") .arg(Arg::with_name("validator_count") .value_name("VALIDATOR_COUNT") .required(true) .help("The number of validators in the genesis state")) + .arg(Arg::with_name("minutes") + .short("m") + .value_name("MINUTES") + .required(true) + .default_value("15") + .help("The maximum number of minutes that will have elapsed before genesis")) ) .subcommand(SubCommand::with_name("yaml-genesis-state") .about("Creates a new datadir where the genesis state is read from YAML. Will fail to parse \