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