Add input validation for --creation-time/--lockup-date args (#7646)
automerge
This commit is contained in:
parent
06c63f2026
commit
4b3bc587ab
|
@ -3489,6 +3489,7 @@ name = "solana-genesis"
|
||||||
version = "0.23.0"
|
version = "0.23.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hex 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -33,7 +33,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unix_timestamp_of(matches: &ArgMatches<'_>, name: &str) -> Option<UnixTimestamp> {
|
pub fn unix_timestamp_from_rfc3339_datetime(
|
||||||
|
matches: &ArgMatches<'_>,
|
||||||
|
name: &str,
|
||||||
|
) -> Option<UnixTimestamp> {
|
||||||
matches.value_of(name).and_then(|value| {
|
matches.value_of(name).and_then(|value| {
|
||||||
DateTime::parse_from_rfc3339(value)
|
DateTime::parse_from_rfc3339(value)
|
||||||
.ok()
|
.ok()
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::keypair::ASK_KEYWORD;
|
use crate::keypair::ASK_KEYWORD;
|
||||||
|
use chrono::DateTime;
|
||||||
use solana_sdk::hash::Hash;
|
use solana_sdk::hash::Hash;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
use solana_sdk::signature::{read_keypair_file, Signature};
|
use solana_sdk::signature::{read_keypair_file, Signature};
|
||||||
|
@ -129,3 +130,9 @@ pub fn is_amount(amount: String) -> Result<(), String> {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_rfc3339_datetime(value: String) -> Result<(), String> {
|
||||||
|
DateTime::parse_from_rfc3339(&value)
|
||||||
|
.map(|_| ())
|
||||||
|
.map_err(|e| format!("{:?}", e))
|
||||||
|
}
|
||||||
|
|
|
@ -86,6 +86,7 @@ impl StakeSubCommands for App<'_, '_> {
|
||||||
Arg::with_name("lockup_date")
|
Arg::with_name("lockup_date")
|
||||||
.long("lockup-date")
|
.long("lockup-date")
|
||||||
.value_name("RFC3339 DATE TIME")
|
.value_name("RFC3339 DATE TIME")
|
||||||
|
.validator(is_rfc3339_datetime)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("The date and time at which this account will be available for withdrawal")
|
.help("The date and time at which this account will be available for withdrawal")
|
||||||
)
|
)
|
||||||
|
@ -367,7 +368,7 @@ impl StakeSubCommands for App<'_, '_> {
|
||||||
pub fn parse_stake_create_account(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
|
pub fn parse_stake_create_account(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
|
||||||
let stake_account = keypair_of(matches, "stake_account").unwrap();
|
let stake_account = keypair_of(matches, "stake_account").unwrap();
|
||||||
let epoch = value_of(&matches, "lockup_epoch").unwrap_or(0);
|
let epoch = value_of(&matches, "lockup_epoch").unwrap_or(0);
|
||||||
let unix_timestamp = unix_timestamp_of(&matches, "lockup_date").unwrap_or(0);
|
let unix_timestamp = unix_timestamp_from_rfc3339_datetime(&matches, "lockup_date").unwrap_or(0);
|
||||||
let custodian = pubkey_of(matches, "custodian").unwrap_or_default();
|
let custodian = pubkey_of(matches, "custodian").unwrap_or_default();
|
||||||
let staker = pubkey_of(matches, "authorized_staker");
|
let staker = pubkey_of(matches, "authorized_staker");
|
||||||
let withdrawer = pubkey_of(matches, "authorized_withdrawer");
|
let withdrawer = pubkey_of(matches, "authorized_withdrawer");
|
||||||
|
|
|
@ -11,6 +11,7 @@ homepage = "https://solana.com/"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64 = "0.11.0"
|
base64 = "0.11.0"
|
||||||
clap = "2.33.0"
|
clap = "2.33.0"
|
||||||
|
chrono = "0.4"
|
||||||
hex = "0.4.0"
|
hex = "0.4.0"
|
||||||
serde = "1.0.104"
|
serde = "1.0.104"
|
||||||
serde_derive = "1.0.103"
|
serde_derive = "1.0.103"
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
//! A command-line executable for generating the chain's genesis config.
|
//! A command-line executable for generating the chain's genesis config.
|
||||||
|
|
||||||
|
use chrono::{TimeZone, Utc};
|
||||||
use clap::{crate_description, crate_name, value_t, value_t_or_exit, App, Arg, ArgMatches};
|
use clap::{crate_description, crate_name, value_t, value_t_or_exit, App, Arg, ArgMatches};
|
||||||
use solana_clap_utils::{
|
use solana_clap_utils::{
|
||||||
input_parsers::{pubkey_of, unix_timestamp_of},
|
input_parsers::{pubkey_of, unix_timestamp_from_rfc3339_datetime},
|
||||||
input_validators::is_valid_percentage,
|
input_validators::{is_rfc3339_datetime, is_valid_percentage},
|
||||||
};
|
};
|
||||||
use solana_genesis::{genesis_accounts::add_genesis_accounts, Base64Account};
|
use solana_genesis::{genesis_accounts::add_genesis_accounts, Base64Account};
|
||||||
use solana_ledger::{blocktree::create_new_ledger, poh::compute_hashes_per_tick};
|
use solana_ledger::{blocktree::create_new_ledger, poh::compute_hashes_per_tick};
|
||||||
|
@ -140,8 +141,9 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
Arg::with_name("creation_time")
|
Arg::with_name("creation_time")
|
||||||
.long("creation-time")
|
.long("creation-time")
|
||||||
.value_name("RFC3339 DATE TIME")
|
.value_name("RFC3339 DATE TIME")
|
||||||
|
.validator(is_rfc3339_datetime)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("Time when the bootrap leader will start, defaults to current system time"),
|
.help("Time when the bootstrap leader will start the cluster [default: current system time]"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("bootstrap_leader_pubkey_file")
|
Arg::with_name("bootstrap_leader_pubkey_file")
|
||||||
|
@ -246,7 +248,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
.default_value(default_lamports_per_byte_year)
|
.default_value(default_lamports_per_byte_year)
|
||||||
.help(
|
.help(
|
||||||
"The cost in lamports that the cluster will charge per byte per year \
|
"The cost in lamports that the cluster will charge per byte per year \
|
||||||
for accounts with data.",
|
for accounts with data",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -257,7 +259,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
.default_value(default_rent_exemption_threshold)
|
.default_value(default_rent_exemption_threshold)
|
||||||
.help(
|
.help(
|
||||||
"amount of time (in years) the balance has to include rent for \
|
"amount of time (in years) the balance has to include rent for \
|
||||||
to qualify as rent exempted account.",
|
to qualify as rent exempted account",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -486,7 +488,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
..GenesisConfig::default()
|
..GenesisConfig::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(creation_time) = unix_timestamp_of(&matches, "creation_time") {
|
if let Some(creation_time) = unix_timestamp_from_rfc3339_datetime(&matches, "creation_time") {
|
||||||
genesis_config.creation_time = creation_time;
|
genesis_config.creation_time = creation_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,8 +520,9 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
create_new_ledger(&ledger_path, &genesis_config)?;
|
create_new_ledger(&ledger_path, &genesis_config)?;
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"Genesis hash: {}\nOperating mode: {:?}\nHashes per tick: {:?}\nSlots per epoch: {}\nCapitalization: {} SOL in {} accounts",
|
"Genesis hash: {}\nCreation time: {}\nOperating mode: {:?}\nHashes per tick: {:?}\nSlots per epoch: {}\nCapitalization: {} SOL in {} accounts",
|
||||||
genesis_config.hash(),
|
genesis_config.hash(),
|
||||||
|
Utc.timestamp(genesis_config.creation_time, 0).to_rfc3339(),
|
||||||
operating_mode,
|
operating_mode,
|
||||||
genesis_config.poh_config.hashes_per_tick,
|
genesis_config.poh_config.hashes_per_tick,
|
||||||
slots_per_epoch,
|
slots_per_epoch,
|
||||||
|
|
Loading…
Reference in New Issue