adds flag to disable duplicate instance check (#15006)
This commit is contained in:
parent
971c222cf7
commit
0ad063f4e9
|
@ -2540,6 +2540,7 @@ impl ClusterInfo {
|
||||||
stakes: HashMap<Pubkey, u64>,
|
stakes: HashMap<Pubkey, u64>,
|
||||||
feature_set: Option<&FeatureSet>,
|
feature_set: Option<&FeatureSet>,
|
||||||
epoch_time_ms: u64,
|
epoch_time_ms: u64,
|
||||||
|
should_check_duplicate_instance: bool,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let _st = ScopedTimer::from(&self.stats.process_gossip_packets_time);
|
let _st = ScopedTimer::from(&self.stats.process_gossip_packets_time);
|
||||||
let packets: Vec<_> = thread_pool.install(|| {
|
let packets: Vec<_> = thread_pool.install(|| {
|
||||||
|
@ -2557,11 +2558,13 @@ impl ClusterInfo {
|
||||||
// Check if there is a duplicate instance of
|
// Check if there is a duplicate instance of
|
||||||
// this node with more recent timestamp.
|
// this node with more recent timestamp.
|
||||||
let check_duplicate_instance = |values: &[CrdsValue]| {
|
let check_duplicate_instance = |values: &[CrdsValue]| {
|
||||||
|
if should_check_duplicate_instance {
|
||||||
for value in values {
|
for value in values {
|
||||||
if self.instance.check_duplicate(value) {
|
if self.instance.check_duplicate(value) {
|
||||||
return Err(Error::DuplicateNodeInstance);
|
return Err(Error::DuplicateNodeInstance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
// Split packets based on their types.
|
// Split packets based on their types.
|
||||||
|
@ -2620,6 +2623,7 @@ impl ClusterInfo {
|
||||||
response_sender: &PacketSender,
|
response_sender: &PacketSender,
|
||||||
thread_pool: &ThreadPool,
|
thread_pool: &ThreadPool,
|
||||||
last_print: &mut Instant,
|
last_print: &mut Instant,
|
||||||
|
should_check_duplicate_instance: bool,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
const RECV_TIMEOUT: Duration = Duration::from_secs(1);
|
const RECV_TIMEOUT: Duration = Duration::from_secs(1);
|
||||||
let packets: Vec<_> = requests_receiver.recv_timeout(RECV_TIMEOUT)?.packets.into();
|
let packets: Vec<_> = requests_receiver.recv_timeout(RECV_TIMEOUT)?.packets.into();
|
||||||
|
@ -2655,6 +2659,7 @@ impl ClusterInfo {
|
||||||
stakes,
|
stakes,
|
||||||
feature_set.as_deref(),
|
feature_set.as_deref(),
|
||||||
epoch_time_ms,
|
epoch_time_ms,
|
||||||
|
should_check_duplicate_instance,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.print_reset_stats(last_print);
|
self.print_reset_stats(last_print);
|
||||||
|
@ -2900,6 +2905,7 @@ impl ClusterInfo {
|
||||||
bank_forks: Option<Arc<RwLock<BankForks>>>,
|
bank_forks: Option<Arc<RwLock<BankForks>>>,
|
||||||
requests_receiver: PacketReceiver,
|
requests_receiver: PacketReceiver,
|
||||||
response_sender: PacketSender,
|
response_sender: PacketSender,
|
||||||
|
should_check_duplicate_instance: bool,
|
||||||
exit: &Arc<AtomicBool>,
|
exit: &Arc<AtomicBool>,
|
||||||
) -> JoinHandle<()> {
|
) -> JoinHandle<()> {
|
||||||
let exit = exit.clone();
|
let exit = exit.clone();
|
||||||
|
@ -2921,6 +2927,7 @@ impl ClusterInfo {
|
||||||
&response_sender,
|
&response_sender,
|
||||||
&thread_pool,
|
&thread_pool,
|
||||||
&mut last_print,
|
&mut last_print,
|
||||||
|
should_check_duplicate_instance,
|
||||||
) {
|
) {
|
||||||
match err {
|
match err {
|
||||||
Error::RecvTimeoutError(_) => {
|
Error::RecvTimeoutError(_) => {
|
||||||
|
|
|
@ -33,6 +33,7 @@ impl GossipService {
|
||||||
bank_forks: Option<Arc<RwLock<BankForks>>>,
|
bank_forks: Option<Arc<RwLock<BankForks>>>,
|
||||||
gossip_socket: UdpSocket,
|
gossip_socket: UdpSocket,
|
||||||
gossip_validators: Option<HashSet<Pubkey>>,
|
gossip_validators: Option<HashSet<Pubkey>>,
|
||||||
|
should_check_duplicate_instance: bool,
|
||||||
exit: &Arc<AtomicBool>,
|
exit: &Arc<AtomicBool>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let (request_sender, request_receiver) = channel();
|
let (request_sender, request_receiver) = channel();
|
||||||
|
@ -56,6 +57,7 @@ impl GossipService {
|
||||||
bank_forks.clone(),
|
bank_forks.clone(),
|
||||||
request_receiver,
|
request_receiver,
|
||||||
response_sender.clone(),
|
response_sender.clone(),
|
||||||
|
should_check_duplicate_instance,
|
||||||
exit,
|
exit,
|
||||||
);
|
);
|
||||||
let t_gossip = ClusterInfo::gossip(
|
let t_gossip = ClusterInfo::gossip(
|
||||||
|
@ -108,8 +110,14 @@ pub fn discover(
|
||||||
let keypair = keypair.unwrap_or_else(|| Arc::new(Keypair::new()));
|
let keypair = keypair.unwrap_or_else(|| Arc::new(Keypair::new()));
|
||||||
|
|
||||||
let exit = Arc::new(AtomicBool::new(false));
|
let exit = Arc::new(AtomicBool::new(false));
|
||||||
let (gossip_service, ip_echo, spy_ref) =
|
let (gossip_service, ip_echo, spy_ref) = make_gossip_node(
|
||||||
make_gossip_node(keypair, entrypoint, &exit, my_gossip_addr, my_shred_version);
|
keypair,
|
||||||
|
entrypoint,
|
||||||
|
&exit,
|
||||||
|
my_gossip_addr,
|
||||||
|
my_shred_version,
|
||||||
|
true, // should_check_duplicate_instance,
|
||||||
|
);
|
||||||
|
|
||||||
let id = spy_ref.id();
|
let id = spy_ref.id();
|
||||||
info!("Entrypoint: {:?}", entrypoint);
|
info!("Entrypoint: {:?}", entrypoint);
|
||||||
|
@ -268,6 +276,7 @@ fn make_gossip_node(
|
||||||
exit: &Arc<AtomicBool>,
|
exit: &Arc<AtomicBool>,
|
||||||
gossip_addr: Option<&SocketAddr>,
|
gossip_addr: Option<&SocketAddr>,
|
||||||
shred_version: u16,
|
shred_version: u16,
|
||||||
|
should_check_duplicate_instance: bool,
|
||||||
) -> (GossipService, Option<TcpListener>, Arc<ClusterInfo>) {
|
) -> (GossipService, Option<TcpListener>, Arc<ClusterInfo>) {
|
||||||
let (node, gossip_socket, ip_echo) = if let Some(gossip_addr) = gossip_addr {
|
let (node, gossip_socket, ip_echo) = if let Some(gossip_addr) = gossip_addr {
|
||||||
ClusterInfo::gossip_node(&keypair.pubkey(), gossip_addr, shred_version)
|
ClusterInfo::gossip_node(&keypair.pubkey(), gossip_addr, shred_version)
|
||||||
|
@ -279,7 +288,14 @@ fn make_gossip_node(
|
||||||
cluster_info.set_entrypoint(ContactInfo::new_gossip_entry_point(entrypoint));
|
cluster_info.set_entrypoint(ContactInfo::new_gossip_entry_point(entrypoint));
|
||||||
}
|
}
|
||||||
let cluster_info = Arc::new(cluster_info);
|
let cluster_info = Arc::new(cluster_info);
|
||||||
let gossip_service = GossipService::new(&cluster_info, None, gossip_socket, None, &exit);
|
let gossip_service = GossipService::new(
|
||||||
|
&cluster_info,
|
||||||
|
None,
|
||||||
|
gossip_socket,
|
||||||
|
None,
|
||||||
|
should_check_duplicate_instance,
|
||||||
|
&exit,
|
||||||
|
);
|
||||||
(gossip_service, ip_echo, cluster_info)
|
(gossip_service, ip_echo, cluster_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +314,14 @@ mod tests {
|
||||||
let tn = Node::new_localhost();
|
let tn = Node::new_localhost();
|
||||||
let cluster_info = ClusterInfo::new_with_invalid_keypair(tn.info.clone());
|
let cluster_info = ClusterInfo::new_with_invalid_keypair(tn.info.clone());
|
||||||
let c = Arc::new(cluster_info);
|
let c = Arc::new(cluster_info);
|
||||||
let d = GossipService::new(&c, None, tn.sockets.gossip, None, &exit);
|
let d = GossipService::new(
|
||||||
|
&c,
|
||||||
|
None,
|
||||||
|
tn.sockets.gossip,
|
||||||
|
None,
|
||||||
|
true, // should_check_duplicate_instance
|
||||||
|
&exit,
|
||||||
|
);
|
||||||
exit.store(true, Ordering::Relaxed);
|
exit.store(true, Ordering::Relaxed);
|
||||||
d.join().unwrap();
|
d.join().unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -405,6 +405,7 @@ impl TestValidator {
|
||||||
vec![Arc::new(validator_vote_account)],
|
vec![Arc::new(validator_vote_account)],
|
||||||
vec![],
|
vec![],
|
||||||
&validator_config,
|
&validator_config,
|
||||||
|
true, // should_check_duplicate_instance
|
||||||
));
|
));
|
||||||
|
|
||||||
// Needed to avoid panics in `solana-responder-gossip` in tests that create a number of
|
// Needed to avoid panics in `solana-responder-gossip` in tests that create a number of
|
||||||
|
|
|
@ -247,6 +247,7 @@ impl Validator {
|
||||||
mut authorized_voter_keypairs: Vec<Arc<Keypair>>,
|
mut authorized_voter_keypairs: Vec<Arc<Keypair>>,
|
||||||
cluster_entrypoints: Vec<ContactInfo>,
|
cluster_entrypoints: Vec<ContactInfo>,
|
||||||
config: &ValidatorConfig,
|
config: &ValidatorConfig,
|
||||||
|
should_check_duplicate_instance: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let id = identity_keypair.pubkey();
|
let id = identity_keypair.pubkey();
|
||||||
assert_eq!(id, node.info.id);
|
assert_eq!(id, node.info.id);
|
||||||
|
@ -517,6 +518,7 @@ impl Validator {
|
||||||
Some(bank_forks.clone()),
|
Some(bank_forks.clone()),
|
||||||
node.sockets.gossip,
|
node.sockets.gossip,
|
||||||
config.gossip_validators.clone(),
|
config.gossip_validators.clone(),
|
||||||
|
should_check_duplicate_instance,
|
||||||
&exit,
|
&exit,
|
||||||
);
|
);
|
||||||
let serve_repair = Arc::new(RwLock::new(ServeRepair::new(cluster_info.clone())));
|
let serve_repair = Arc::new(RwLock::new(ServeRepair::new(cluster_info.clone())));
|
||||||
|
@ -1419,6 +1421,7 @@ mod tests {
|
||||||
vec![voting_keypair.clone()],
|
vec![voting_keypair.clone()],
|
||||||
vec![leader_node.info],
|
vec![leader_node.info],
|
||||||
&config,
|
&config,
|
||||||
|
true, // should_check_duplicate_instance
|
||||||
);
|
);
|
||||||
validator.close();
|
validator.close();
|
||||||
remove_dir_all(validator_ledger_path).unwrap();
|
remove_dir_all(validator_ledger_path).unwrap();
|
||||||
|
@ -1489,6 +1492,7 @@ mod tests {
|
||||||
vec![Arc::new(vote_account_keypair)],
|
vec![Arc::new(vote_account_keypair)],
|
||||||
vec![leader_node.info.clone()],
|
vec![leader_node.info.clone()],
|
||||||
&config,
|
&config,
|
||||||
|
true, // should_check_duplicate_instance
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
|
@ -25,8 +25,14 @@ fn test_node(exit: &Arc<AtomicBool>) -> (Arc<ClusterInfo>, GossipService, UdpSoc
|
||||||
let keypair = Arc::new(Keypair::new());
|
let keypair = Arc::new(Keypair::new());
|
||||||
let mut test_node = Node::new_localhost_with_pubkey(&keypair.pubkey());
|
let mut test_node = Node::new_localhost_with_pubkey(&keypair.pubkey());
|
||||||
let cluster_info = Arc::new(ClusterInfo::new(test_node.info.clone(), keypair));
|
let cluster_info = Arc::new(ClusterInfo::new(test_node.info.clone(), keypair));
|
||||||
let gossip_service =
|
let gossip_service = GossipService::new(
|
||||||
GossipService::new(&cluster_info, None, test_node.sockets.gossip, None, exit);
|
&cluster_info,
|
||||||
|
None,
|
||||||
|
test_node.sockets.gossip,
|
||||||
|
None,
|
||||||
|
true, // should_check_duplicate_instance
|
||||||
|
exit,
|
||||||
|
);
|
||||||
let _ = cluster_info.my_contact_info();
|
let _ = cluster_info.my_contact_info();
|
||||||
(
|
(
|
||||||
cluster_info,
|
cluster_info,
|
||||||
|
@ -47,6 +53,7 @@ fn test_node_with_bank(
|
||||||
Some(bank_forks),
|
Some(bank_forks),
|
||||||
test_node.sockets.gossip,
|
test_node.sockets.gossip,
|
||||||
None,
|
None,
|
||||||
|
true, // should_check_duplicate_instance
|
||||||
exit,
|
exit,
|
||||||
);
|
);
|
||||||
let _ = cluster_info.my_contact_info();
|
let _ = cluster_info.my_contact_info();
|
||||||
|
|
|
@ -207,6 +207,7 @@ impl LocalCluster {
|
||||||
vec![leader_vote_keypair.clone()],
|
vec![leader_vote_keypair.clone()],
|
||||||
vec![],
|
vec![],
|
||||||
&leader_config,
|
&leader_config,
|
||||||
|
true, // should_check_duplicate_instance
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut validators = HashMap::new();
|
let mut validators = HashMap::new();
|
||||||
|
@ -350,6 +351,7 @@ impl LocalCluster {
|
||||||
vec![voting_keypair.clone()],
|
vec![voting_keypair.clone()],
|
||||||
vec![self.entry_point_info.clone()],
|
vec![self.entry_point_info.clone()],
|
||||||
&config,
|
&config,
|
||||||
|
true, // should_check_duplicate_instance
|
||||||
);
|
);
|
||||||
|
|
||||||
let validator_pubkey = validator_keypair.pubkey();
|
let validator_pubkey = validator_keypair.pubkey();
|
||||||
|
@ -665,6 +667,7 @@ impl Cluster for LocalCluster {
|
||||||
.map(|entry_point_info| vec![entry_point_info])
|
.map(|entry_point_info| vec![entry_point_info])
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
&cluster_validator_info.config,
|
&cluster_validator_info.config,
|
||||||
|
true, // should_check_duplicate_instance
|
||||||
);
|
);
|
||||||
cluster_validator_info.validator = Some(restarted_node);
|
cluster_validator_info.validator = Some(restarted_node);
|
||||||
cluster_validator_info
|
cluster_validator_info
|
||||||
|
|
|
@ -121,6 +121,7 @@ fn start_gossip_node(
|
||||||
gossip_socket: UdpSocket,
|
gossip_socket: UdpSocket,
|
||||||
expected_shred_version: Option<u16>,
|
expected_shred_version: Option<u16>,
|
||||||
gossip_validators: Option<HashSet<Pubkey>>,
|
gossip_validators: Option<HashSet<Pubkey>>,
|
||||||
|
should_check_duplicate_instance: bool,
|
||||||
) -> (Arc<ClusterInfo>, Arc<AtomicBool>, GossipService) {
|
) -> (Arc<ClusterInfo>, Arc<AtomicBool>, GossipService) {
|
||||||
let mut cluster_info = ClusterInfo::new(
|
let mut cluster_info = ClusterInfo::new(
|
||||||
ClusterInfo::gossip_contact_info(
|
ClusterInfo::gossip_contact_info(
|
||||||
|
@ -140,6 +141,7 @@ fn start_gossip_node(
|
||||||
None,
|
None,
|
||||||
gossip_socket,
|
gossip_socket,
|
||||||
gossip_validators,
|
gossip_validators,
|
||||||
|
should_check_duplicate_instance,
|
||||||
&gossip_exit_flag,
|
&gossip_exit_flag,
|
||||||
);
|
);
|
||||||
(cluster_info, gossip_exit_flag, gossip_service)
|
(cluster_info, gossip_exit_flag, gossip_service)
|
||||||
|
@ -577,6 +579,7 @@ fn rpc_bootstrap(
|
||||||
no_port_check: bool,
|
no_port_check: bool,
|
||||||
use_progress_bar: bool,
|
use_progress_bar: bool,
|
||||||
maximum_local_snapshot_age: Slot,
|
maximum_local_snapshot_age: Slot,
|
||||||
|
should_check_duplicate_instance: bool,
|
||||||
) {
|
) {
|
||||||
if !no_port_check {
|
if !no_port_check {
|
||||||
let mut order: Vec<_> = (0..cluster_entrypoints.len()).collect();
|
let mut order: Vec<_> = (0..cluster_entrypoints.len()).collect();
|
||||||
|
@ -605,6 +608,7 @@ fn rpc_bootstrap(
|
||||||
node.sockets.gossip.try_clone().unwrap(),
|
node.sockets.gossip.try_clone().unwrap(),
|
||||||
validator_config.expected_shred_version,
|
validator_config.expected_shred_version,
|
||||||
validator_config.gossip_validators.clone(),
|
validator_config.gossip_validators.clone(),
|
||||||
|
should_check_duplicate_instance,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1421,6 +1425,13 @@ pub fn main() {
|
||||||
.conflicts_with("no_accounts_db_caching")
|
.conflicts_with("no_accounts_db_caching")
|
||||||
.hidden(true)
|
.hidden(true)
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("no_duplicate_instance_check")
|
||||||
|
.long("no-duplicate-instance-check")
|
||||||
|
.takes_value(false)
|
||||||
|
.help("Disables duplicate instance check")
|
||||||
|
.hidden(true),
|
||||||
|
)
|
||||||
.after_help("The default subcommand is run")
|
.after_help("The default subcommand is run")
|
||||||
.subcommand(
|
.subcommand(
|
||||||
SubCommand::with_name("init")
|
SubCommand::with_name("init")
|
||||||
|
@ -1896,6 +1907,7 @@ pub fn main() {
|
||||||
solana_ledger::entry::init_poh();
|
solana_ledger::entry::init_poh();
|
||||||
solana_runtime::snapshot_utils::remove_tmp_snapshot_archives(&ledger_path);
|
solana_runtime::snapshot_utils::remove_tmp_snapshot_archives(&ledger_path);
|
||||||
|
|
||||||
|
let should_check_duplicate_instance = !matches.is_present("no_duplicate_instance_check");
|
||||||
if !cluster_entrypoints.is_empty() {
|
if !cluster_entrypoints.is_empty() {
|
||||||
rpc_bootstrap(
|
rpc_bootstrap(
|
||||||
&node,
|
&node,
|
||||||
|
@ -1909,6 +1921,7 @@ pub fn main() {
|
||||||
no_port_check,
|
no_port_check,
|
||||||
use_progress_bar,
|
use_progress_bar,
|
||||||
maximum_local_snapshot_age,
|
maximum_local_snapshot_age,
|
||||||
|
should_check_duplicate_instance,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1916,7 +1929,6 @@ 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,
|
||||||
|
@ -1925,6 +1937,7 @@ pub fn main() {
|
||||||
authorized_voter_keypairs,
|
authorized_voter_keypairs,
|
||||||
cluster_entrypoints,
|
cluster_entrypoints,
|
||||||
&validator_config,
|
&validator_config,
|
||||||
|
should_check_duplicate_instance,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(filename) = init_complete_file {
|
if let Some(filename) = init_complete_file {
|
||||||
|
|
Loading…
Reference in New Issue