Add authorized-voter add/remove-all commands
This commit is contained in:
parent
17a173ebb5
commit
2229b70c4e
|
@ -106,7 +106,7 @@ struct SkippedSlotsInfo {
|
||||||
pub struct ReplayStageConfig {
|
pub struct ReplayStageConfig {
|
||||||
pub my_pubkey: Pubkey,
|
pub my_pubkey: Pubkey,
|
||||||
pub vote_account: Pubkey,
|
pub vote_account: Pubkey,
|
||||||
pub authorized_voter_keypairs: Vec<Arc<Keypair>>,
|
pub authorized_voter_keypairs: Arc<RwLock<Vec<Arc<Keypair>>>>,
|
||||||
pub exit: Arc<AtomicBool>,
|
pub exit: Arc<AtomicBool>,
|
||||||
pub subscriptions: Arc<RpcSubscriptions>,
|
pub subscriptions: Arc<RpcSubscriptions>,
|
||||||
pub leader_schedule_cache: Arc<LeaderScheduleCache>,
|
pub leader_schedule_cache: Arc<LeaderScheduleCache>,
|
||||||
|
@ -531,7 +531,7 @@ impl ReplayStage {
|
||||||
&mut tower,
|
&mut tower,
|
||||||
&mut progress,
|
&mut progress,
|
||||||
&vote_account,
|
&vote_account,
|
||||||
&authorized_voter_keypairs,
|
&authorized_voter_keypairs.read().unwrap(),
|
||||||
&cluster_info,
|
&cluster_info,
|
||||||
&blockstore,
|
&blockstore,
|
||||||
&leader_schedule_cache,
|
&leader_schedule_cache,
|
||||||
|
|
|
@ -56,6 +56,7 @@ pub struct TestValidatorGenesis {
|
||||||
epoch_schedule: Option<EpochSchedule>,
|
epoch_schedule: Option<EpochSchedule>,
|
||||||
pub validator_exit: Arc<RwLock<ValidatorExit>>,
|
pub validator_exit: Arc<RwLock<ValidatorExit>>,
|
||||||
pub start_progress: Arc<RwLock<ValidatorStartProgress>>,
|
pub start_progress: Arc<RwLock<ValidatorStartProgress>>,
|
||||||
|
pub authorized_voter_keypairs: Arc<RwLock<Vec<Arc<Keypair>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestValidatorGenesis {
|
impl TestValidatorGenesis {
|
||||||
|
@ -399,6 +400,16 @@ impl TestValidator {
|
||||||
let mut rpc_config = config.rpc_config.clone();
|
let mut rpc_config = config.rpc_config.clone();
|
||||||
rpc_config.identity_pubkey = validator_identity.pubkey();
|
rpc_config.identity_pubkey = validator_identity.pubkey();
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut authorized_voter_keypairs = config.authorized_voter_keypairs.write().unwrap();
|
||||||
|
if !authorized_voter_keypairs
|
||||||
|
.iter()
|
||||||
|
.any(|x| x.pubkey() == vote_account_address)
|
||||||
|
{
|
||||||
|
authorized_voter_keypairs.push(Arc::new(validator_vote_account))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let validator_config = ValidatorConfig {
|
let validator_config = ValidatorConfig {
|
||||||
rpc_addrs: Some((
|
rpc_addrs: Some((
|
||||||
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), node.info.rpc.port()),
|
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), node.info.rpc.port()),
|
||||||
|
@ -434,8 +445,8 @@ impl TestValidator {
|
||||||
node,
|
node,
|
||||||
&Arc::new(validator_identity),
|
&Arc::new(validator_identity),
|
||||||
&ledger_path,
|
&ledger_path,
|
||||||
&validator_vote_account.pubkey(),
|
&vote_account_address,
|
||||||
vec![Arc::new(validator_vote_account)],
|
config.authorized_voter_keypairs.clone(),
|
||||||
vec![],
|
vec![],
|
||||||
&validator_config,
|
&validator_config,
|
||||||
true, // should_check_duplicate_instance
|
true, // should_check_duplicate_instance
|
||||||
|
|
|
@ -100,7 +100,7 @@ impl Tvu {
|
||||||
#[allow(clippy::new_ret_no_self, clippy::too_many_arguments)]
|
#[allow(clippy::new_ret_no_self, clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
vote_account: &Pubkey,
|
vote_account: &Pubkey,
|
||||||
authorized_voter_keypairs: Vec<Arc<Keypair>>,
|
authorized_voter_keypairs: Arc<RwLock<Vec<Arc<Keypair>>>>,
|
||||||
bank_forks: &Arc<RwLock<BankForks>>,
|
bank_forks: &Arc<RwLock<BankForks>>,
|
||||||
cluster_info: &Arc<ClusterInfo>,
|
cluster_info: &Arc<ClusterInfo>,
|
||||||
sockets: Sockets,
|
sockets: Sockets,
|
||||||
|
@ -389,7 +389,7 @@ pub mod tests {
|
||||||
let tower = Tower::new_with_key(&target1_keypair.pubkey());
|
let tower = Tower::new_with_key(&target1_keypair.pubkey());
|
||||||
let tvu = Tvu::new(
|
let tvu = Tvu::new(
|
||||||
&vote_keypair.pubkey(),
|
&vote_keypair.pubkey(),
|
||||||
vec![Arc::new(vote_keypair)],
|
Arc::new(RwLock::new(vec![Arc::new(vote_keypair)])),
|
||||||
&bank_forks,
|
&bank_forks,
|
||||||
&cref1,
|
&cref1,
|
||||||
{
|
{
|
||||||
|
|
|
@ -297,7 +297,7 @@ impl Validator {
|
||||||
identity_keypair: &Arc<Keypair>,
|
identity_keypair: &Arc<Keypair>,
|
||||||
ledger_path: &Path,
|
ledger_path: &Path,
|
||||||
vote_account: &Pubkey,
|
vote_account: &Pubkey,
|
||||||
mut authorized_voter_keypairs: Vec<Arc<Keypair>>,
|
authorized_voter_keypairs: Arc<RwLock<Vec<Arc<Keypair>>>>,
|
||||||
cluster_entrypoints: Vec<ContactInfo>,
|
cluster_entrypoints: Vec<ContactInfo>,
|
||||||
config: &ValidatorConfig,
|
config: &ValidatorConfig,
|
||||||
should_check_duplicate_instance: bool,
|
should_check_duplicate_instance: bool,
|
||||||
|
@ -311,12 +311,13 @@ impl Validator {
|
||||||
|
|
||||||
if config.voting_disabled {
|
if config.voting_disabled {
|
||||||
warn!("voting disabled");
|
warn!("voting disabled");
|
||||||
authorized_voter_keypairs.clear();
|
authorized_voter_keypairs.write().unwrap().clear();
|
||||||
} else {
|
} else {
|
||||||
for authorized_voter_keypair in &authorized_voter_keypairs {
|
for authorized_voter_keypair in authorized_voter_keypairs.read().unwrap().iter() {
|
||||||
warn!("authorized voter: {}", authorized_voter_keypair.pubkey());
|
warn!("authorized voter: {}", authorized_voter_keypair.pubkey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
report_target_features();
|
report_target_features();
|
||||||
|
|
||||||
for cluster_entrypoint in &cluster_entrypoints {
|
for cluster_entrypoint in &cluster_entrypoints {
|
||||||
|
@ -1559,7 +1560,7 @@ mod tests {
|
||||||
&Arc::new(validator_keypair),
|
&Arc::new(validator_keypair),
|
||||||
&validator_ledger_path,
|
&validator_ledger_path,
|
||||||
&voting_keypair.pubkey(),
|
&voting_keypair.pubkey(),
|
||||||
vec![voting_keypair.clone()],
|
Arc::new(RwLock::new(vec![voting_keypair.clone()])),
|
||||||
vec![leader_node.info],
|
vec![leader_node.info],
|
||||||
&config,
|
&config,
|
||||||
true, // should_check_duplicate_instance
|
true, // should_check_duplicate_instance
|
||||||
|
@ -1635,7 +1636,7 @@ mod tests {
|
||||||
&Arc::new(validator_keypair),
|
&Arc::new(validator_keypair),
|
||||||
&validator_ledger_path,
|
&validator_ledger_path,
|
||||||
&vote_account_keypair.pubkey(),
|
&vote_account_keypair.pubkey(),
|
||||||
vec![Arc::new(vote_account_keypair)],
|
Arc::new(RwLock::new(vec![Arc::new(vote_account_keypair)])),
|
||||||
vec![leader_node.info.clone()],
|
vec![leader_node.info.clone()],
|
||||||
&config,
|
&config,
|
||||||
true, // should_check_duplicate_instance
|
true, // should_check_duplicate_instance
|
||||||
|
|
|
@ -213,7 +213,7 @@ impl LocalCluster {
|
||||||
&leader_keypair,
|
&leader_keypair,
|
||||||
&leader_ledger_path,
|
&leader_ledger_path,
|
||||||
&leader_vote_keypair.pubkey(),
|
&leader_vote_keypair.pubkey(),
|
||||||
vec![leader_vote_keypair.clone()],
|
Arc::new(RwLock::new(vec![leader_vote_keypair.clone()])),
|
||||||
vec![],
|
vec![],
|
||||||
&leader_config,
|
&leader_config,
|
||||||
true, // should_check_duplicate_instance
|
true, // should_check_duplicate_instance
|
||||||
|
@ -355,7 +355,7 @@ impl LocalCluster {
|
||||||
&validator_keypair,
|
&validator_keypair,
|
||||||
&ledger_path,
|
&ledger_path,
|
||||||
&voting_keypair.pubkey(),
|
&voting_keypair.pubkey(),
|
||||||
vec![voting_keypair.clone()],
|
Arc::new(RwLock::new(vec![voting_keypair.clone()])),
|
||||||
vec![self.entry_point_info.clone()],
|
vec![self.entry_point_info.clone()],
|
||||||
&config,
|
&config,
|
||||||
true, // should_check_duplicate_instance
|
true, // should_check_duplicate_instance
|
||||||
|
@ -670,7 +670,7 @@ impl Cluster for LocalCluster {
|
||||||
&validator_info.keypair,
|
&validator_info.keypair,
|
||||||
&validator_info.ledger_path,
|
&validator_info.ledger_path,
|
||||||
&validator_info.voting_keypair.pubkey(),
|
&validator_info.voting_keypair.pubkey(),
|
||||||
vec![validator_info.voting_keypair.clone()],
|
Arc::new(RwLock::new(vec![validator_info.voting_keypair.clone()])),
|
||||||
entry_point_info
|
entry_point_info
|
||||||
.map(|entry_point_info| vec![entry_point_info])
|
.map(|entry_point_info| vec![entry_point_info])
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
|
|
|
@ -6,6 +6,7 @@ use {
|
||||||
jsonrpc_server_utils::tokio,
|
jsonrpc_server_utils::tokio,
|
||||||
log::*,
|
log::*,
|
||||||
solana_core::validator::{ValidatorExit, ValidatorStartProgress},
|
solana_core::validator::{ValidatorExit, ValidatorStartProgress},
|
||||||
|
solana_sdk::signature::{read_keypair_file, Keypair, Signer},
|
||||||
std::{
|
std::{
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
path::Path,
|
path::Path,
|
||||||
|
@ -21,6 +22,7 @@ pub struct AdminRpcRequestMetadata {
|
||||||
pub start_time: SystemTime,
|
pub start_time: SystemTime,
|
||||||
pub start_progress: Arc<RwLock<ValidatorStartProgress>>,
|
pub start_progress: Arc<RwLock<ValidatorStartProgress>>,
|
||||||
pub validator_exit: Arc<RwLock<ValidatorExit>>,
|
pub validator_exit: Arc<RwLock<ValidatorExit>>,
|
||||||
|
pub authorized_voter_keypairs: Arc<RwLock<Vec<Arc<Keypair>>>>,
|
||||||
}
|
}
|
||||||
impl Metadata for AdminRpcRequestMetadata {}
|
impl Metadata for AdminRpcRequestMetadata {}
|
||||||
|
|
||||||
|
@ -42,6 +44,12 @@ pub trait AdminRpc {
|
||||||
|
|
||||||
#[rpc(meta, name = "startProgress")]
|
#[rpc(meta, name = "startProgress")]
|
||||||
fn start_progress(&self, meta: Self::Metadata) -> Result<ValidatorStartProgress>;
|
fn start_progress(&self, meta: Self::Metadata) -> Result<ValidatorStartProgress>;
|
||||||
|
|
||||||
|
#[rpc(meta, name = "addAuthorizedVoter")]
|
||||||
|
fn add_authorized_voter(&self, meta: Self::Metadata, keypair_file: String) -> Result<()>;
|
||||||
|
|
||||||
|
#[rpc(meta, name = "removeAllAuthorizedVoters")]
|
||||||
|
fn remove_all_authorized_voters(&self, meta: Self::Metadata) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AdminRpcImpl;
|
pub struct AdminRpcImpl;
|
||||||
|
@ -78,6 +86,39 @@ impl AdminRpc for AdminRpcImpl {
|
||||||
debug!("start_progress admin rpc request received");
|
debug!("start_progress admin rpc request received");
|
||||||
Ok(*meta.start_progress.read().unwrap())
|
Ok(*meta.start_progress.read().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_authorized_voter(&self, meta: Self::Metadata, keypair_file: String) -> Result<()> {
|
||||||
|
debug!("add_authorized_voter request received");
|
||||||
|
|
||||||
|
let authorized_voter = read_keypair_file(keypair_file)
|
||||||
|
.map_err(|err| jsonrpc_core::error::Error::invalid_params(format!("{}", err)))?;
|
||||||
|
|
||||||
|
let mut authorized_voter_keypairs = meta.authorized_voter_keypairs.write().unwrap();
|
||||||
|
|
||||||
|
if authorized_voter_keypairs
|
||||||
|
.iter()
|
||||||
|
.any(|x| x.pubkey() == authorized_voter.pubkey())
|
||||||
|
{
|
||||||
|
Err(jsonrpc_core::error::Error::invalid_params(
|
||||||
|
"Authorized voter already present",
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
authorized_voter_keypairs.push(Arc::new(authorized_voter));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_all_authorized_voters(&self, meta: Self::Metadata) -> Result<()> {
|
||||||
|
debug!("remove_all_authorized_voters received");
|
||||||
|
let mut a = meta.authorized_voter_keypairs.write().unwrap();
|
||||||
|
|
||||||
|
error!("authorized_voter_keypairs pre len: {}", a.len());
|
||||||
|
a.clear();
|
||||||
|
error!("authorized_voter_keypairs post len: {}", a.len());
|
||||||
|
|
||||||
|
//meta.authorized_voter_keypairs.write().unwrap().clear();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the Admin RPC interface
|
// Start the Admin RPC interface
|
||||||
|
|
|
@ -403,6 +403,7 @@ fn main() {
|
||||||
start_progress: genesis.start_progress.clone(),
|
start_progress: genesis.start_progress.clone(),
|
||||||
start_time: std::time::SystemTime::now(),
|
start_time: std::time::SystemTime::now(),
|
||||||
validator_exit: genesis.validator_exit.clone(),
|
validator_exit: genesis.validator_exit.clone(),
|
||||||
|
authorized_voter_keypairs: genesis.authorized_voter_keypairs.clone(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let dashboard = if output == Output::Dashboard {
|
let dashboard = if output == Output::Dashboard {
|
||||||
|
|
|
@ -11,7 +11,8 @@ use {
|
||||||
solana_clap_utils::{
|
solana_clap_utils::{
|
||||||
input_parsers::{keypair_of, keypairs_of, pubkey_of, value_of},
|
input_parsers::{keypair_of, keypairs_of, pubkey_of, value_of},
|
||||||
input_validators::{
|
input_validators::{
|
||||||
is_keypair_or_ask_keyword, is_parsable, is_pubkey, is_pubkey_or_keypair, is_slot,
|
is_keypair, is_keypair_or_ask_keyword, is_parsable, is_pubkey, is_pubkey_or_keypair,
|
||||||
|
is_slot,
|
||||||
},
|
},
|
||||||
keypair::SKIP_SEED_PHRASE_VALIDATION_ARG,
|
keypair::SKIP_SEED_PHRASE_VALIDATION_ARG,
|
||||||
},
|
},
|
||||||
|
@ -804,7 +805,7 @@ fn rpc_bootstrap(
|
||||||
ledger_path: &Path,
|
ledger_path: &Path,
|
||||||
snapshot_output_dir: &Path,
|
snapshot_output_dir: &Path,
|
||||||
vote_account: &Pubkey,
|
vote_account: &Pubkey,
|
||||||
authorized_voter_keypairs: &[Arc<Keypair>],
|
authorized_voter_keypairs: Arc<RwLock<Vec<Arc<Keypair>>>>,
|
||||||
cluster_entrypoints: &[ContactInfo],
|
cluster_entrypoints: &[ContactInfo],
|
||||||
validator_config: &mut ValidatorConfig,
|
validator_config: &mut ValidatorConfig,
|
||||||
bootstrap_config: RpcBootstrapConfig,
|
bootstrap_config: RpcBootstrapConfig,
|
||||||
|
@ -969,6 +970,8 @@ fn rpc_bootstrap(
|
||||||
&identity_keypair.pubkey(),
|
&identity_keypair.pubkey(),
|
||||||
&vote_account,
|
&vote_account,
|
||||||
&authorized_voter_keypairs
|
&authorized_voter_keypairs
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|k| k.pubkey())
|
.map(|k| k.pubkey())
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
|
@ -1766,6 +1769,32 @@ pub fn main() {
|
||||||
.help("Minimum time that the validator should not be leader before restarting")
|
.help("Minimum time that the validator should not be leader before restarting")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
.subcommand(
|
||||||
|
SubCommand::with_name("authorized-voter")
|
||||||
|
.about("Adjust the validator authorized voters")
|
||||||
|
.setting(AppSettings::SubcommandRequiredElseHelp)
|
||||||
|
.setting(AppSettings::InferSubcommands)
|
||||||
|
.subcommand(
|
||||||
|
SubCommand::with_name("add")
|
||||||
|
.about("Add an authorized voter")
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("authorized_voter_keypair")
|
||||||
|
.index(1)
|
||||||
|
.value_name("KEYPAIR")
|
||||||
|
.takes_value(true)
|
||||||
|
.validator(is_keypair)
|
||||||
|
.help("Keypair of the authorized voter to add"),
|
||||||
|
)
|
||||||
|
.after_help("Note: the new authorized voter only applies to the \
|
||||||
|
currently running validator instance")
|
||||||
|
)
|
||||||
|
.subcommand(
|
||||||
|
SubCommand::with_name("remove-all")
|
||||||
|
.about("Remove all authorized voters")
|
||||||
|
.after_help("Note: the removal only applies to the \
|
||||||
|
currently running validator instance")
|
||||||
|
)
|
||||||
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("init")
|
SubCommand::with_name("init")
|
||||||
.about("Initialize the ledger directory then exit")
|
.about("Initialize the ledger directory then exit")
|
||||||
|
@ -1810,6 +1839,43 @@ pub fn main() {
|
||||||
|
|
||||||
let operation = match matches.subcommand() {
|
let operation = match matches.subcommand() {
|
||||||
("", _) | ("run", _) => Operation::Run,
|
("", _) | ("run", _) => Operation::Run,
|
||||||
|
("authorized-voter", Some(authorized_voter_subcommand_matches)) => {
|
||||||
|
match authorized_voter_subcommand_matches.subcommand() {
|
||||||
|
("add", Some(subcommand_matches)) => {
|
||||||
|
let authorized_voter_keypair =
|
||||||
|
value_t_or_exit!(subcommand_matches, "authorized_voter_keypair", String);
|
||||||
|
println!("Adding authorized voter: {}", authorized_voter_keypair);
|
||||||
|
|
||||||
|
let admin_client = admin_rpc_service::connect(&ledger_path);
|
||||||
|
admin_rpc_service::runtime()
|
||||||
|
.block_on(async move {
|
||||||
|
admin_client
|
||||||
|
.await?
|
||||||
|
.add_authorized_voter(authorized_voter_keypair)
|
||||||
|
.await
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|err| {
|
||||||
|
println!("addAuthorizedVoter request failed: {}", err);
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
("remove-all", _) => {
|
||||||
|
let admin_client = admin_rpc_service::connect(&ledger_path);
|
||||||
|
admin_rpc_service::runtime()
|
||||||
|
.block_on(async move {
|
||||||
|
admin_client.await?.remove_all_authorized_voters().await
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|err| {
|
||||||
|
println!("removeAllAuthorizedVoters request failed: {}", err);
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
println!("All authorized voters removed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
("init", _) => Operation::Initialize,
|
("init", _) => Operation::Initialize,
|
||||||
("exit", Some(subcommand_matches)) => {
|
("exit", Some(subcommand_matches)) => {
|
||||||
let min_idle_time = value_t_or_exit!(subcommand_matches, "min_idle_time", usize);
|
let min_idle_time = value_t_or_exit!(subcommand_matches, "min_idle_time", usize);
|
||||||
|
@ -1874,6 +1940,7 @@ pub fn main() {
|
||||||
let authorized_voter_keypairs = keypairs_of(&matches, "authorized_voter_keypairs")
|
let authorized_voter_keypairs = keypairs_of(&matches, "authorized_voter_keypairs")
|
||||||
.map(|keypairs| keypairs.into_iter().map(Arc::new).collect())
|
.map(|keypairs| keypairs.into_iter().map(Arc::new).collect())
|
||||||
.unwrap_or_else(|| vec![identity_keypair.clone()]);
|
.unwrap_or_else(|| vec![identity_keypair.clone()]);
|
||||||
|
let authorized_voter_keypairs = Arc::new(RwLock::new(authorized_voter_keypairs));
|
||||||
|
|
||||||
let init_complete_file = matches.value_of("init_complete_file");
|
let init_complete_file = matches.value_of("init_complete_file");
|
||||||
|
|
||||||
|
@ -2261,6 +2328,7 @@ pub fn main() {
|
||||||
start_time: std::time::SystemTime::now(),
|
start_time: std::time::SystemTime::now(),
|
||||||
validator_exit: validator_config.validator_exit.clone(),
|
validator_exit: validator_config.validator_exit.clone(),
|
||||||
start_progress: start_progress.clone(),
|
start_progress: start_progress.clone(),
|
||||||
|
authorized_voter_keypairs: authorized_voter_keypairs.clone(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2371,7 +2439,7 @@ pub fn main() {
|
||||||
&ledger_path,
|
&ledger_path,
|
||||||
&snapshot_output_dir,
|
&snapshot_output_dir,
|
||||||
&vote_account,
|
&vote_account,
|
||||||
&authorized_voter_keypairs,
|
authorized_voter_keypairs.clone(),
|
||||||
&cluster_entrypoints,
|
&cluster_entrypoints,
|
||||||
&mut validator_config,
|
&mut validator_config,
|
||||||
rpc_bootstrap_config,
|
rpc_bootstrap_config,
|
||||||
|
@ -2388,6 +2456,7 @@ pub fn main() {
|
||||||
info!("Validator ledger initialization complete");
|
info!("Validator ledger initialization complete");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let validator = Validator::new(
|
let validator = Validator::new(
|
||||||
node,
|
node,
|
||||||
&identity_keypair,
|
&identity_keypair,
|
||||||
|
|
Loading…
Reference in New Issue