genesis: Add support for multiple bootstrap validators (#8656)
automerge
This commit is contained in:
		| @@ -2,8 +2,8 @@ | |||||||
|  |  | ||||||
| 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_from_rfc3339_datetime}, |     input_parsers::{pubkey_of, pubkeys_of, unix_timestamp_from_rfc3339_datetime}, | ||||||
|     input_validators::{is_rfc3339_datetime, is_valid_percentage}, |     input_validators::{is_pubkey_or_keypair, 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::{blockstore::create_new_ledger, poh::compute_hashes_per_tick}; | use solana_ledger::{blockstore::create_new_ledger, poh::compute_hashes_per_tick}; | ||||||
| @@ -21,16 +21,9 @@ use solana_sdk::{ | |||||||
|     system_program, timing, |     system_program, timing, | ||||||
| }; | }; | ||||||
| use solana_stake_program::stake_state::{self, StakeState}; | use solana_stake_program::stake_state::{self, StakeState}; | ||||||
| use solana_storage_program::storage_contract; |  | ||||||
| use solana_vote_program::vote_state::{self, VoteState}; | use solana_vote_program::vote_state::{self, VoteState}; | ||||||
| use std::{ | use std::{ | ||||||
|     collections::{BTreeMap, HashMap}, |     collections::HashMap, error, fs::File, io, path::PathBuf, process, str::FromStr, time::Duration, | ||||||
|     error, |  | ||||||
|     fs::File, |  | ||||||
|     io, |  | ||||||
|     path::PathBuf, |  | ||||||
|     str::FromStr, |  | ||||||
|     time::Duration, |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| pub enum AccountFileFormat { | pub enum AccountFileFormat { | ||||||
| @@ -38,16 +31,6 @@ pub enum AccountFileFormat { | |||||||
|     Keypair, |     Keypair, | ||||||
| } | } | ||||||
|  |  | ||||||
| fn required_pubkey(matches: &ArgMatches<'_>, name: &str) -> Result<Pubkey, Box<dyn error::Error>> { |  | ||||||
|     pubkey_of(matches, name).ok_or_else(|| { |  | ||||||
|         format!( |  | ||||||
|             "Invalid pubkey or file: {}", |  | ||||||
|             matches.value_of(name).unwrap() |  | ||||||
|         ) |  | ||||||
|         .into() |  | ||||||
|     }) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| fn pubkey_from_str(key_str: &str) -> Result<Pubkey, Box<dyn error::Error>> { | fn pubkey_from_str(key_str: &str) -> Result<Pubkey, Box<dyn error::Error>> { | ||||||
|     Pubkey::from_str(key_str).or_else(|_| { |     Pubkey::from_str(key_str).or_else(|_| { | ||||||
|         let bytes: Vec<u8> = serde_json::from_str(key_str)?; |         let bytes: Vec<u8> = serde_json::from_str(key_str)?; | ||||||
| @@ -151,13 +134,16 @@ fn main() -> Result<(), Box<dyn error::Error>> { | |||||||
|                 .help("Time when the bootstrap validator will start the cluster [default: current system time]"), |                 .help("Time when the bootstrap validator will start the cluster [default: current system time]"), | ||||||
|         ) |         ) | ||||||
|         .arg( |         .arg( | ||||||
|             Arg::with_name("bootstrap_validator_pubkey_file") |             Arg::with_name("bootstrap_validator") | ||||||
|                 .short("b") |                 .short("b") | ||||||
|                 .long("bootstrap-validator-pubkey") |                 .long("bootstrap-validator") | ||||||
|                 .value_name("BOOTSTRAP VALIDATOR PUBKEY") |                 .value_name("IDENTITY_PUBKEY VOTE_PUBKEY STAKE_PUBKEY") | ||||||
|                 .takes_value(true) |                 .takes_value(true) | ||||||
|  |                 .validator(is_pubkey_or_keypair) | ||||||
|  |                 .number_of_values(3) | ||||||
|  |                 .multiple(true) | ||||||
|                 .required(true) |                 .required(true) | ||||||
|                 .help("Path to file containing the bootstrap validator's pubkey"), |                 .help("The bootstrap validator's identity, vote and stake pubkeys"), | ||||||
|         ) |         ) | ||||||
|         .arg( |         .arg( | ||||||
|             Arg::with_name("ledger_path") |             Arg::with_name("ledger_path") | ||||||
| @@ -174,58 +160,36 @@ fn main() -> Result<(), Box<dyn error::Error>> { | |||||||
|                 .long("faucet-lamports") |                 .long("faucet-lamports") | ||||||
|                 .value_name("LAMPORTS") |                 .value_name("LAMPORTS") | ||||||
|                 .takes_value(true) |                 .takes_value(true) | ||||||
|                 .requires("faucet_pubkey_file") |                 .requires("faucet_pubkey") | ||||||
|                 .help("Number of lamports to assign to the faucet"), |                 .help("Number of lamports to assign to the faucet"), | ||||||
|         ) |         ) | ||||||
|         .arg( |         .arg( | ||||||
|             Arg::with_name("faucet_pubkey_file") |             Arg::with_name("faucet_pubkey") | ||||||
|                 .short("m") |                 .short("m") | ||||||
|                 .long("faucet-pubkey") |                 .long("faucet-pubkey") | ||||||
|                 .value_name("PUBKEY") |                 .value_name("PUBKEY") | ||||||
|                 .takes_value(true) |                 .takes_value(true) | ||||||
|  |                 .validator(is_pubkey_or_keypair) | ||||||
|                 .requires("faucet_lamports") |                 .requires("faucet_lamports") | ||||||
|                 .help("Path to file containing the faucet's pubkey"), |                 .help("Path to file containing the faucet's pubkey"), | ||||||
|         ) |         ) | ||||||
|         .arg( |         .arg( | ||||||
|             Arg::with_name("bootstrap_vote_pubkey_file") |             Arg::with_name("bootstrap_stake_authorized_pubkey") | ||||||
|                 .long("bootstrap-vote-pubkey") |  | ||||||
|                 .value_name("BOOTSTRAP VOTE PUBKEY") |  | ||||||
|                 .takes_value(true) |  | ||||||
|                 .required(true) |  | ||||||
|                 .help("Path to file containing the bootstrap validator's voting pubkey"), |  | ||||||
|         ) |  | ||||||
|         .arg( |  | ||||||
|             Arg::with_name("bootstrap_stake_pubkey_file") |  | ||||||
|                 .long("bootstrap-stake-pubkey") |  | ||||||
|                 .value_name("BOOTSTRAP STAKE PUBKEY") |  | ||||||
|                 .takes_value(true) |  | ||||||
|                 .required(true) |  | ||||||
|                 .help("Path to file containing the bootstrap validator's staking pubkey"), |  | ||||||
|         ) |  | ||||||
|         .arg( |  | ||||||
|             Arg::with_name("bootstrap_stake_authorized_pubkey_file") |  | ||||||
|                 .long("bootstrap-stake-authorized-pubkey") |                 .long("bootstrap-stake-authorized-pubkey") | ||||||
|                 .value_name("BOOTSTRAP STAKE AUTHORIZED PUBKEY") |                 .value_name("BOOTSTRAP STAKE AUTHORIZED PUBKEY") | ||||||
|                 .takes_value(true) |                 .takes_value(true) | ||||||
|  |                 .validator(is_pubkey_or_keypair) | ||||||
|                 .help( |                 .help( | ||||||
|                     "Path to file containing the pubkey authorized to manage the bootstrap \ |                     "Path to file containing the pubkey authorized to manage the bootstrap \ | ||||||
|                      validator's stake [default: --bootstrap-validator-pubkey]", |                      validator's stake [default: --bootstrap-validator-pubkey]", | ||||||
|                 ), |                 ), | ||||||
|         ) |         ) | ||||||
|         .arg( |  | ||||||
|             Arg::with_name("bootstrap_storage_pubkey_file") |  | ||||||
|                 .long("bootstrap-storage-pubkey") |  | ||||||
|                 .value_name("BOOTSTRAP STORAGE PUBKEY") |  | ||||||
|                 .takes_value(true) |  | ||||||
|                 .help("Path to file containing the bootstrap validator's storage pubkey"), |  | ||||||
|         ) |  | ||||||
|         .arg( |         .arg( | ||||||
|             Arg::with_name("bootstrap_validator_lamports") |             Arg::with_name("bootstrap_validator_lamports") | ||||||
|                 .long("bootstrap-validator-lamports") |                 .long("bootstrap-validator-lamports") | ||||||
|                 .value_name("LAMPORTS") |                 .value_name("LAMPORTS") | ||||||
|                 .takes_value(true) |                 .takes_value(true) | ||||||
|                 .default_value(default_bootstrap_validator_lamports) |                 .default_value(default_bootstrap_validator_lamports) | ||||||
|                 .required(true) |  | ||||||
|                 .help("Number of lamports to assign to the bootstrap validator"), |                 .help("Number of lamports to assign to the bootstrap validator"), | ||||||
|         ) |         ) | ||||||
|         .arg( |         .arg( | ||||||
| @@ -234,7 +198,6 @@ fn main() -> Result<(), Box<dyn error::Error>> { | |||||||
|                 .value_name("LAMPORTS") |                 .value_name("LAMPORTS") | ||||||
|                 .takes_value(true) |                 .takes_value(true) | ||||||
|                 .default_value(default_bootstrap_validator_stake_lamports) |                 .default_value(default_bootstrap_validator_stake_lamports) | ||||||
|                 .required(true) |  | ||||||
|                 .help("Number of lamports to assign to the bootstrap validator's stake account"), |                 .help("Number of lamports to assign to the bootstrap validator's stake account"), | ||||||
|         ) |         ) | ||||||
|         .arg( |         .arg( | ||||||
| @@ -391,6 +354,20 @@ fn main() -> Result<(), Box<dyn error::Error>> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     let bootstrap_validator_pubkeys = pubkeys_of(&matches, "bootstrap_validator").unwrap(); | ||||||
|  |     assert_eq!(bootstrap_validator_pubkeys.len() % 3, 0); | ||||||
|  |  | ||||||
|  |     // Ensure there are no duplicated pubkeys in the --bootstrap-validator list | ||||||
|  |     { | ||||||
|  |         let mut v = bootstrap_validator_pubkeys.clone(); | ||||||
|  |         v.sort(); | ||||||
|  |         v.dedup(); | ||||||
|  |         if v.len() != bootstrap_validator_pubkeys.len() { | ||||||
|  |             eprintln!("Error: --bootstrap-validator pubkeys cannot be duplicated"); | ||||||
|  |             process::exit(1); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     let bootstrap_validator_lamports = |     let bootstrap_validator_lamports = | ||||||
|         value_t_or_exit!(matches, "bootstrap_validator_lamports", u64); |         value_t_or_exit!(matches, "bootstrap_validator_lamports", u64); | ||||||
|  |  | ||||||
| @@ -400,52 +377,9 @@ fn main() -> Result<(), Box<dyn error::Error>> { | |||||||
|         StakeState::get_rent_exempt_reserve(&rent), |         StakeState::get_rent_exempt_reserve(&rent), | ||||||
|     )?; |     )?; | ||||||
|  |  | ||||||
|     let bootstrap_validator_pubkey = required_pubkey(&matches, "bootstrap_validator_pubkey_file")?; |  | ||||||
|     let bootstrap_vote_pubkey = required_pubkey(&matches, "bootstrap_vote_pubkey_file")?; |  | ||||||
|     let bootstrap_stake_pubkey = required_pubkey(&matches, "bootstrap_stake_pubkey_file")?; |  | ||||||
|     let bootstrap_stake_authorized_pubkey = |     let bootstrap_stake_authorized_pubkey = | ||||||
|         pubkey_of(&matches, "bootstrap_stake_authorized_pubkey_file"); |         pubkey_of(&matches, "bootstrap_stake_authorized_pubkey"); | ||||||
|     let bootstrap_storage_pubkey = pubkey_of(&matches, "bootstrap_storage_pubkey_file"); |     let faucet_pubkey = pubkey_of(&matches, "faucet_pubkey"); | ||||||
|     let faucet_pubkey = pubkey_of(&matches, "faucet_pubkey_file"); |  | ||||||
|  |  | ||||||
|     let bootstrap_validator_vote_account = vote_state::create_account( |  | ||||||
|         &bootstrap_vote_pubkey, |  | ||||||
|         &bootstrap_validator_pubkey, |  | ||||||
|         100, |  | ||||||
|         VoteState::get_rent_exempt_reserve(&rent).max(1), |  | ||||||
|     ); |  | ||||||
|  |  | ||||||
|     let bootstrap_validator_stake_account = stake_state::create_account( |  | ||||||
|         bootstrap_stake_authorized_pubkey |  | ||||||
|             .as_ref() |  | ||||||
|             .unwrap_or(&bootstrap_validator_pubkey), |  | ||||||
|         &bootstrap_vote_pubkey, |  | ||||||
|         &bootstrap_validator_vote_account, |  | ||||||
|         &rent, |  | ||||||
|         bootstrap_validator_stake_lamports, |  | ||||||
|     ); |  | ||||||
|  |  | ||||||
|     let mut accounts: BTreeMap<Pubkey, Account> = [ |  | ||||||
|         // node needs an account to issue votes from |  | ||||||
|         ( |  | ||||||
|             bootstrap_validator_pubkey, |  | ||||||
|             Account::new(bootstrap_validator_lamports, 0, &system_program::id()), |  | ||||||
|         ), |  | ||||||
|         // where votes go to |  | ||||||
|         (bootstrap_vote_pubkey, bootstrap_validator_vote_account), |  | ||||||
|         // bootstrap validator stake |  | ||||||
|         (bootstrap_stake_pubkey, bootstrap_validator_stake_account), |  | ||||||
|     ] |  | ||||||
|     .iter() |  | ||||||
|     .cloned() |  | ||||||
|     .collect(); |  | ||||||
|  |  | ||||||
|     if let Some(bootstrap_storage_pubkey) = bootstrap_storage_pubkey { |  | ||||||
|         accounts.insert( |  | ||||||
|             bootstrap_storage_pubkey, |  | ||||||
|             storage_contract::create_validator_storage_account(bootstrap_validator_pubkey, 1), |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     let ticks_per_slot = value_t_or_exit!(matches, "ticks_per_slot", u64); |     let ticks_per_slot = value_t_or_exit!(matches, "ticks_per_slot", u64); | ||||||
|  |  | ||||||
| @@ -508,7 +442,6 @@ fn main() -> Result<(), Box<dyn error::Error>> { | |||||||
|     let inflation = solana_genesis_programs::get_inflation(operating_mode, 0).unwrap(); |     let inflation = solana_genesis_programs::get_inflation(operating_mode, 0).unwrap(); | ||||||
|  |  | ||||||
|     let mut genesis_config = GenesisConfig { |     let mut genesis_config = GenesisConfig { | ||||||
|         accounts, |  | ||||||
|         native_instruction_processors, |         native_instruction_processors, | ||||||
|         ticks_per_slot, |         ticks_per_slot, | ||||||
|         epoch_schedule, |         epoch_schedule, | ||||||
| @@ -520,6 +453,43 @@ fn main() -> Result<(), Box<dyn error::Error>> { | |||||||
|         ..GenesisConfig::default() |         ..GenesisConfig::default() | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  |     let mut bootstrap_validator_pubkeys_iter = bootstrap_validator_pubkeys.iter(); | ||||||
|  |     loop { | ||||||
|  |         let identity_pubkey = match bootstrap_validator_pubkeys_iter.next() { | ||||||
|  |             None => break, | ||||||
|  |             Some(identity_pubkey) => identity_pubkey, | ||||||
|  |         }; | ||||||
|  |         let vote_pubkey = bootstrap_validator_pubkeys_iter.next().unwrap(); | ||||||
|  |         let stake_pubkey = bootstrap_validator_pubkeys_iter.next().unwrap(); | ||||||
|  |  | ||||||
|  |         genesis_config.add_account( | ||||||
|  |             *identity_pubkey, | ||||||
|  |             Account::new(bootstrap_validator_lamports, 0, &system_program::id()), | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         let vote_account = vote_state::create_account( | ||||||
|  |             &vote_pubkey, | ||||||
|  |             &identity_pubkey, | ||||||
|  |             100, | ||||||
|  |             VoteState::get_rent_exempt_reserve(&rent).max(1), | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         genesis_config.add_account( | ||||||
|  |             *stake_pubkey, | ||||||
|  |             stake_state::create_account( | ||||||
|  |                 bootstrap_stake_authorized_pubkey | ||||||
|  |                     .as_ref() | ||||||
|  |                     .unwrap_or(&identity_pubkey), | ||||||
|  |                 &vote_pubkey, | ||||||
|  |                 &vote_account, | ||||||
|  |                 &rent, | ||||||
|  |                 bootstrap_validator_stake_lamports, | ||||||
|  |             ), | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         genesis_config.add_account(*vote_pubkey, vote_account); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if let Some(creation_time) = unix_timestamp_from_rfc3339_datetime(&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; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -66,7 +66,6 @@ done | |||||||
| # These keypairs are created by ./setup.sh and included in the genesis config | # These keypairs are created by ./setup.sh and included in the genesis config | ||||||
| identity_keypair=$SOLANA_CONFIG_DIR/bootstrap-validator/identity-keypair.json | identity_keypair=$SOLANA_CONFIG_DIR/bootstrap-validator/identity-keypair.json | ||||||
| vote_keypair="$SOLANA_CONFIG_DIR"/bootstrap-validator/vote-keypair.json | vote_keypair="$SOLANA_CONFIG_DIR"/bootstrap-validator/vote-keypair.json | ||||||
| storage_keypair=$SOLANA_CONFIG_DIR/bootstrap-validator/storage-keypair.json |  | ||||||
|  |  | ||||||
| ledger_dir="$SOLANA_CONFIG_DIR"/bootstrap-validator | ledger_dir="$SOLANA_CONFIG_DIR"/bootstrap-validator | ||||||
| [[ -d "$ledger_dir" ]] || { | [[ -d "$ledger_dir" ]] || { | ||||||
| @@ -82,7 +81,6 @@ args+=( | |||||||
|   --rpc-port 8899 |   --rpc-port 8899 | ||||||
|   --snapshot-interval-slots 100 |   --snapshot-interval-slots 100 | ||||||
|   --identity-keypair "$identity_keypair" |   --identity-keypair "$identity_keypair" | ||||||
|   --storage-keypair "$storage_keypair" |  | ||||||
|   --voting-keypair "$vote_keypair" |   --voting-keypair "$vote_keypair" | ||||||
|   --rpc-faucet-address 127.0.0.1:9900 |   --rpc-faucet-address 127.0.0.1:9900 | ||||||
| ) | ) | ||||||
| @@ -90,7 +88,6 @@ default_arg --gossip-port 8001 | |||||||
| default_arg --log - | default_arg --log - | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| pid= | pid= | ||||||
| kill_node() { | kill_node() { | ||||||
|   # Note: do not echo anything from this function to ensure $pid is actually |   # Note: do not echo anything from this function to ensure $pid is actually | ||||||
|   | |||||||
| @@ -24,14 +24,14 @@ fi | |||||||
|  |  | ||||||
| $solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-validator/vote-keypair.json | $solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-validator/vote-keypair.json | ||||||
| $solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-validator/stake-keypair.json | $solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-validator/stake-keypair.json | ||||||
| $solana_keygen new --no-passphrase -so "$SOLANA_CONFIG_DIR"/bootstrap-validator/storage-keypair.json |  | ||||||
|  |  | ||||||
| args=("$@") | args=( | ||||||
| default_arg --enable-warmup-epochs |   "$@" | ||||||
| default_arg --bootstrap-validator-pubkey "$SOLANA_CONFIG_DIR"/bootstrap-validator/identity-keypair.json |   --enable-warmup-epochs | ||||||
| default_arg --bootstrap-vote-pubkey "$SOLANA_CONFIG_DIR"/bootstrap-validator/vote-keypair.json |   --bootstrap-validator "$SOLANA_CONFIG_DIR"/bootstrap-validator/identity-keypair.json | ||||||
| default_arg --bootstrap-stake-pubkey "$SOLANA_CONFIG_DIR"/bootstrap-validator/stake-keypair.json |                         "$SOLANA_CONFIG_DIR"/bootstrap-validator/vote-keypair.json | ||||||
| default_arg --bootstrap-storage-pubkey "$SOLANA_CONFIG_DIR"/bootstrap-validator/storage-keypair.json |                         "$SOLANA_CONFIG_DIR"/bootstrap-validator/stake-keypair.json | ||||||
|  | ) | ||||||
| default_arg --ledger "$SOLANA_CONFIG_DIR"/bootstrap-validator | default_arg --ledger "$SOLANA_CONFIG_DIR"/bootstrap-validator | ||||||
| default_arg --faucet-pubkey "$SOLANA_CONFIG_DIR"/faucet-keypair.json | default_arg --faucet-pubkey "$SOLANA_CONFIG_DIR"/faucet-keypair.json | ||||||
| default_arg --faucet-lamports 500000000000000000 | default_arg --faucet-lamports 500000000000000000 | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								run.sh
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								run.sh
									
									
									
									
									
								
							| @@ -70,12 +70,6 @@ if [[ -e $faucet_keypair ]]; then | |||||||
| else | else | ||||||
|   solana-keygen new --no-passphrase -fso "$faucet_keypair" |   solana-keygen new --no-passphrase -fso "$faucet_keypair" | ||||||
| fi | fi | ||||||
| leader_storage_account_keypair="$dataDir"/leader-storage-account-keypair.json |  | ||||||
| if [[ -e $leader_storage_account_keypair ]]; then |  | ||||||
|   echo "Use existing leader storage account keypair" |  | ||||||
| else |  | ||||||
|   solana-keygen new --no-passphrase -fso "$leader_storage_account_keypair" |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| if [[ -e "$ledgerDir"/genesis.bin ]]; then | if [[ -e "$ledgerDir"/genesis.bin ]]; then | ||||||
|   echo "Use existing genesis" |   echo "Use existing genesis" | ||||||
| @@ -84,10 +78,10 @@ else | |||||||
|     --hashes-per-tick sleep \ |     --hashes-per-tick sleep \ | ||||||
|     --faucet-pubkey "$dataDir"/faucet-keypair.json \ |     --faucet-pubkey "$dataDir"/faucet-keypair.json \ | ||||||
|     --faucet-lamports 500000000000000000 \ |     --faucet-lamports 500000000000000000 \ | ||||||
|     --bootstrap-validator-pubkey "$dataDir"/leader-keypair.json \ |     --bootstrap-validator \ | ||||||
|     --bootstrap-vote-pubkey "$dataDir"/leader-vote-account-keypair.json \ |       "$dataDir"/leader-keypair.json \ | ||||||
|     --bootstrap-stake-pubkey "$dataDir"/leader-stake-account-keypair.json \ |       "$dataDir"/leader-vote-account-keypair.json \ | ||||||
|     --bootstrap-storage-pubkey "$dataDir"/leader-storage-account-keypair.json \ |       "$dataDir"/leader-stake-account-keypair.json \ | ||||||
|     --ledger "$ledgerDir" \ |     --ledger "$ledgerDir" \ | ||||||
|     --operating-mode development |     --operating-mode development | ||||||
| fi | fi | ||||||
| @@ -104,7 +98,6 @@ faucet=$! | |||||||
|  |  | ||||||
| args=( | args=( | ||||||
|   --identity-keypair "$dataDir"/leader-keypair.json |   --identity-keypair "$dataDir"/leader-keypair.json | ||||||
|   --storage-keypair "$dataDir"/leader-storage-account-keypair.json |  | ||||||
|   --voting-keypair "$dataDir"/leader-vote-account-keypair.json |   --voting-keypair "$dataDir"/leader-vote-account-keypair.json | ||||||
|   --ledger "$ledgerDir" |   --ledger "$ledgerDir" | ||||||
|   --gossip-port 8001 |   --gossip-port 8001 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user