fn start(
        mint_address: Pubkey,
        config: &TestValidatorGenesis,
        socket_addr_space: SocketAddrSpace,
    ) -> Result<Self, Box<dyn std::error::Error>> {
        let preserve_ledger = config.ledger_path.is_some();
        let ledger_path = TestValidator::initialize_ledger(mint_address, config)?;

        let validator_identity =
            read_keypair_file(ledger_path.join("validator-keypair.json").to_str().unwrap())?;
        let validator_vote_account = read_keypair_file(
            ledger_path
                .join("vote-account-keypair.json")
                .to_str()
                .unwrap(),
        )?;

        let mut node = Node::new_single_bind(
            &validator_identity.pubkey(),
            &config.node_config.gossip_addr,
            config.node_config.port_range,
            config.node_config.bind_ip_addr,
        );
        if let Some((rpc, rpc_pubsub)) = config.rpc_ports {
            node.info.rpc = SocketAddr::new(node.info.gossip.ip(), rpc);
            node.info.rpc_pubsub = SocketAddr::new(node.info.gossip.ip(), rpc_pubsub);
        }

        let vote_account_address = validator_vote_account.pubkey();
        let rpc_url = format!("http://{}", node.info.rpc);
        let rpc_pubsub_url = format!("ws://{}/", node.info.rpc_pubsub);
        let tpu = node.info.tpu;
        let gossip = node.info.gossip;

        {
            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 mut validator_config = ValidatorConfig {
            accountsdb_plugin_config_files: config.accountsdb_plugin_config_files.clone(),
            accounts_db_caching_enabled: config.accounts_db_caching_enabled,
            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_pubsub.port(),
                ),
            )),
            rpc_config: config.rpc_config.clone(),
            accounts_hash_interval_slots: 100,
            account_paths: vec![ledger_path.join("accounts")],
            poh_verify: false, // Skip PoH verification of ledger on startup for speed
            snapshot_config: Some(SnapshotConfig {
                full_snapshot_archive_interval_slots: 100,
                incremental_snapshot_archive_interval_slots: Slot::MAX,
                bank_snapshots_dir: ledger_path.join("snapshot"),
                snapshot_archives_dir: ledger_path.to_path_buf(),
                ..SnapshotConfig::default()
            }),
            enforce_ulimit_nofile: false,
            warp_slot: config.warp_slot,
            bpf_jit: !config.no_bpf_jit,
            validator_exit: config.validator_exit.clone(),
            rocksdb_compaction_interval: Some(100), // Compact every 100 slots
            max_ledger_shreds: config.max_ledger_shreds,
            no_wait_for_vote_to_start_leader: true,
            ..ValidatorConfig::default()
        };
        if let Some(ref tower_storage) = config.tower_storage {
            validator_config.tower_storage = tower_storage.clone();
        }

        let validator = Some(Validator::new(
            node,
            Arc::new(validator_identity),
            &ledger_path,
            &vote_account_address,
            config.authorized_voter_keypairs.clone(),
            vec![],
            &validator_config,
            true, // should_check_duplicate_instance
            config.start_progress.clone(),
            socket_addr_space,
        ));

        // Needed to avoid panics in `solana-responder-gossip` in tests that create a number of
        // test validators concurrently...
        discover_cluster(&gossip, 1, socket_addr_space)
            .map_err(|err| format!("TestValidator startup failed: {:?}", err))?;

        // This is a hack to delay until the fees are non-zero for test consistency
        // (fees from genesis are zero until the first block with a transaction in it is completed
        //  due to a bug in the Bank)
        {
            let rpc_client =
                RpcClient::new_with_commitment(rpc_url.clone(), CommitmentConfig::processed());
            let mut message = Message::new(
                &[Instruction::new_with_bytes(
                    Pubkey::new_unique(),
                    &[],
                    vec![AccountMeta::new(Pubkey::new_unique(), true)],
                )],
                None,
            );
            const MAX_TRIES: u64 = 10;
            let mut num_tries = 0;
            loop {
                num_tries += 1;
                if num_tries > MAX_TRIES {
                    break;
                }
                println!("Waiting for fees to stabilize {:?}...", num_tries);
                match rpc_client.get_latest_blockhash() {
                    Ok(blockhash) => {
                        message.recent_blockhash = blockhash;
                        match rpc_client.get_fee_for_message(&message) {
                            Ok(fee) => {
                                if fee != 0 {
                                    break;
                                }
                            }
                            Err(err) => {
                                warn!("get_fee_for_message() failed: {:?}", err);
                                break;
                            }
                        }
                    }
                    Err(err) => {
                        warn!("get_latest_blockhash() failed: {:?}", err);
                        break;
                    }
                }
                sleep(Duration::from_millis(DEFAULT_MS_PER_SLOT));
            }
        }

        Ok(TestValidator {
            ledger_path,
            preserve_ledger,
            rpc_pubsub_url,
            rpc_url,
            tpu,
            gossip,
            validator,
            vote_account_address,
        })
    }
/// Starts a TestValidator at the provided ledger directory
Starts a TestValidator at the provided ledger directory
Starts a TestValidator at the provided ledger directory
fn start(
        mint_address: Pubkey,
        config: &TestValidatorGenesis,
        socket_addr_space: SocketAddrSpace,
    ) -> Result<Self, Box<dyn std::error::Error>> {
        let preserve_ledger = config.ledger_path.is_some();
        let ledger_path = TestValidator::initialize_ledger(mint_address, config)?;
        let validator_identity =
            read_keypair_file(ledger_path.join("validator-keypair.json").to_str().unwrap())?;
        let validator_vote_account = read_keypair_file(
            ledger_path
                .join("vote-account-keypair.json")
                .to_str()
                .unwrap(),
        )?;
        let mut node = Node::new_single_bind(
            &validator_identity.pubkey(),
            &config.node_config.gossip_addr,
            config.node_config.port_range,
            config.node_config.bind_ip_addr,
        );
        if let Some((rpc, rpc_pubsub)) = config.rpc_ports {
            node.info.rpc = SocketAddr::new(node.info.gossip.ip(), rpc);
            node.info.rpc_pubsub = SocketAddr::new(node.info.gossip.ip(), rpc_pubsub);
        }
        let vote_account_address = validator_vote_account.pubkey();
        let rpc_url = format!("http://{}", node.info.rpc);
        let rpc_pubsub_url = format!("ws://{}/", node.info.rpc_pubsub);
        let tpu = node.info.tpu;
        let gossip = node.info.gossip;
        {
            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 mut validator_config = ValidatorConfig {
            accountsdb_plugin_config_files: config.accountsdb_plugin_config_files.clone(),
            accounts_db_caching_enabled: config.accounts_db_caching_enabled,
            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_pubsub.port(),
                ),
            )),
            rpc_config: config.rpc_config.clone(),
            accounts_hash_interval_slots: 100,
            account_paths: vec![ledger_path.join("accounts")],
            poh_verify: false, // Skip PoH verification of ledger on startup for speed
            snapshot_config: Some(SnapshotConfig {
                full_snapshot_archive_interval_slots: 100,
                incremental_snapshot_archive_interval_slots: Slot::MAX,
                bank_snapshots_dir: ledger_path.join("snapshot"),
                snapshot_archives_dir: ledger_path.to_path_buf(),
                ..SnapshotConfig::default()
            }),
            enforce_ulimit_nofile: false,
            warp_slot: config.warp_slot,
            bpf_jit: !config.no_bpf_jit,
            validator_exit: config.validator_exit.clone(),
            rocksdb_compaction_interval: Some(100), // Compact every 100 slots
            max_ledger_shreds: config.max_ledger_shreds,
            no_wait_for_vote_to_start_leader: true,
            ..ValidatorConfig::default()
        };
        if let Some(ref tower_storage) = config.tower_storage {
            validator_config.tower_storage = tower_storage.clone();
        }
        let validator = Some(Validator::new(
            node,
            Arc::new(validator_identity),
            &ledger_path,
            &vote_account_address,
            config.authorized_voter_keypairs.clone(),
            vec![],
            &validator_config,
            true, // should_check_duplicate_instance
            config.start_progress.clone(),
            socket_addr_space,
        ));
        // Needed to avoid panics in `solana-responder-gossip` in tests that create a number of
        // test validators concurrently...
        discover_cluster(&gossip, 1, socket_addr_space)
            .map_err(|err| format!("TestValidator startup failed: {:?}", err))?;
        // This is a hack to delay until the fees are non-zero for test consistency
        // (fees from genesis are zero until the first block with a transaction in it is completed
        //  due to a bug in the Bank)
        {
            let rpc_client =
                RpcClient::new_with_commitment(rpc_url.clone(), CommitmentConfig::processed());
            let mut message = Message::new(
                &[Instruction::new_with_bytes(
                    Pubkey::new_unique(),
                    &[],
                    vec![AccountMeta::new(Pubkey::new_unique(), true)],
                )],
                None,
            );
            const MAX_TRIES: u64 = 10;
            let mut num_tries = 0;
            loop {
                num_tries += 1;
                if num_tries > MAX_TRIES {
                    break;
                }
                println!("Waiting for fees to stabilize {:?}...", num_tries);
                match rpc_client.get_latest_blockhash() {
                    Ok(blockhash) => {
                        message.recent_blockhash = blockhash;
                        match rpc_client.get_fee_for_message(&message) {
                            Ok(fee) => {
                                if fee != 0 {
                                    break;
                                }
                            }
                            Err(err) => {
                                warn!("get_fee_for_message() failed: {:?}", err);
                                break;
                            }
                        }
                    }
                    Err(err) => {
                        warn!("get_latest_blockhash() failed: {:?}", err);
                        break;
                    }
                }
                sleep(Duration::from_millis(DEFAULT_MS_PER_SLOT));
            }
        }
        Ok(TestValidator {
            ledger_path,
            preserve_ledger,
            rpc_pubsub_url,
            rpc_url,
            tpu,
            gossip,
            validator,
            vote_account_address,
        })
    }
fn start ( mint_address : Pubkey , config : & TestValidatorGenesis , socket_addr_space : SocketAddrSpace , ) -> Result < Self , Box < dyn std :: error :: Error > > { let preserve_ledger = config . ledger_path . is_some ( ) ; let ledger_path = TestValidator :: initialize_ledger ( mint_address , config ) ? ; let validator_identity = read_keypair_file ( ledger_path . join ( " " ) . to_str ( ) . unwrap ( ) ) ? ; let validator_vote_account = read_keypair_file ( ledger_path . join ( " " ) . to_str ( ) . unwrap ( ) , ) ? ; let mut node = Node :: new_single_bind ( & validator_identity . pubkey ( ) , & config . node_config . gossip_addr , config . node_config . port_range , config . node_config . bind_ip_addr , ) ; if let Some ( ( rpc , rpc_pubsub ) ) = config . rpc_ports { node . info . rpc = SocketAddr :: new ( node . info . gossip . ip ( ) , rpc ) ; node . info . rpc_pubsub = SocketAddr :: new ( node . info . gossip . ip ( ) , rpc_pubsub ) ; } let vote_account_address = validator_vote_account . pubkey ( ) ; let rpc_url = format ! ( " " node info rpc ) ; let rpc_pubsub_url = format ! ( " " node info rpc_pubsub ) ; let tpu = node . info . tpu ; let gossip = node . info . gossip ; { 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 mut validator_config = ValidatorConfig { accountsdb_plugin_config_files : config . accountsdb_plugin_config_files . clone ( ) , accounts_db_caching_enabled : config . accounts_db_caching_enabled , 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_pubsub . port ( ) , ) , ) ) , rpc_config : config . rpc_config . clone ( ) , accounts_hash_interval_slots : 100 , account_paths : vec ! [ ledger_path join ( " " ) ] , poh_verify : false , // Skip PoH verification of ledger on startup for speed snapshot_config : Some ( SnapshotConfig { full_snapshot_archive_interval_slots : 100 , incremental_snapshot_archive_interval_slots : Slot :: MAX , bank_snapshots_dir : ledger_path . join ( " " ) , snapshot_archives_dir : ledger_path . to_path_buf ( ) , .. SnapshotConfig :: default ( ) } ) , enforce_ulimit_nofile : false , warp_slot : config . warp_slot , bpf_jit : ! config . no_bpf_jit , validator_exit : config . validator_exit . clone ( ) , rocksdb_compaction_interval : Some ( 100 ) , // Compact every 100 slots max_ledger_shreds : config . max_ledger_shreds , no_wait_for_vote_to_start_leader : true , .. ValidatorConfig :: default ( ) } ; if let Some ( ref tower_storage ) = config . tower_storage { validator_config . tower_storage = tower_storage . clone ( ) ; } let validator = Some ( Validator :: new ( node , Arc :: new ( validator_identity ) , & ledger_path , & vote_account_address , config . authorized_voter_keypairs . clone ( ) , vec ! [ ] , & validator_config , true , // should_check_duplicate_instance config . start_progress . clone ( ) , socket_addr_space , ) ) ; // Needed to avoid panics in `solana-responder-gossip` in tests that create a number of // test validators concurrently... discover_cluster ( & gossip , 1 , socket_addr_space ) . map_err ( | err | format ! ( " " err ) ) ? ; // This is a hack to delay until the fees are non-zero for test consistency // (fees from genesis are zero until the first block with a transaction in it is completed //  due to a bug in the Bank) { let rpc_client = RpcClient :: new_with_commitment ( rpc_url . clone ( ) , CommitmentConfig :: processed ( ) ) ; let mut message = Message :: new ( & [ Instruction :: new_with_bytes ( Pubkey :: new_unique ( ) , & [ ] , vec ! [ AccountMeta new ( Pubkey new_unique ( ) true ) ] , ) ] , None , ) ; const MAX_TRIES : u64 = 10 ; let mut num_tries = 0 ; loop { num_tries += 1 ; if num_tries > MAX_TRIES { break ; } println ! ( " " num_tries ) ; match rpc_client . get_latest_blockhash ( ) { Ok ( blockhash ) => { message . recent_blockhash = blockhash ; match rpc_client . get_fee_for_message ( & message ) { Ok ( fee ) => { if fee != 0 { break ; } } Err ( err ) => { warn ! ( " " err ) ; break ; } } } Err ( err ) => { warn ! ( " " err ) ; break ; } } sleep ( Duration :: from_millis ( DEFAULT_MS_PER_SLOT ) ) ; } } Ok ( TestValidator { ledger_path , preserve_ledger , rpc_pubsub_url , rpc_url , tpu , gossip , validator , vote_account_address , } ) }
Starts a TestValidator at the provided ledger directory
Starts a TestValidator at the provided ledger directory
mint_address
Pubkey
config
&TestValidatorGenesis
socket_addr_space
SocketAddrSpace