diff --git a/client/src/http_sender.rs b/client/src/http_sender.rs index 0a7558c6f1..f8b4182135 100644 --- a/client/src/http_sender.rs +++ b/client/src/http_sender.rs @@ -37,14 +37,14 @@ impl HttpSender { /// /// The URL is an HTTP URL, usually for port 8899, as in /// "http://localhost:8899". The sender has a default timeout of 30 seconds. - pub fn new(url: String) -> Self { + pub fn new(url: U) -> Self { Self::new_with_timeout(url, Duration::from_secs(30)) } /// Create an HTTP RPC sender. /// /// The URL is an HTTP URL, usually for port 8899. - pub fn new_with_timeout(url: String, timeout: Duration) -> Self { + pub fn new_with_timeout(url: U, timeout: Duration) -> Self { // `reqwest::blocking::Client` panics if run in a tokio async context. Shuttle the // request to a different tokio thread to avoid this let client = Arc::new( @@ -58,7 +58,7 @@ impl HttpSender { Self { client, - url, + url: url.to_string(), request_id: AtomicU64::new(0), stats: RwLock::new(RpcTransportStats::default()), } diff --git a/client/src/mock_sender.rs b/client/src/mock_sender.rs index e5f282d658..dd9c3de04c 100644 --- a/client/src/mock_sender.rs +++ b/client/src/mock_sender.rs @@ -75,13 +75,13 @@ pub struct MockSender { /// from [`RpcRequest`] to a JSON [`Value`] response, Any entries in this map /// override the default behavior for the given request. impl MockSender { - pub fn new(url: String) -> Self { + pub fn new(url: U) -> Self { Self::new_with_mocks(url, Mocks::default()) } - pub fn new_with_mocks(url: String, mocks: Mocks) -> Self { + pub fn new_with_mocks(url: U, mocks: Mocks) -> Self { Self { - url, + url: url.to_string(), mocks: RwLock::new(mocks), } } diff --git a/client/src/rpc_client.rs b/client/src/rpc_client.rs index 759b4a3322..2ff752bd75 100644 --- a/client/src/rpc_client.rs +++ b/client/src/rpc_client.rs @@ -190,7 +190,7 @@ impl RpcClient { /// let url = "http://localhost:8899".to_string(); /// let client = RpcClient::new(url); /// ``` - pub fn new(url: String) -> Self { + pub fn new(url: U) -> Self { Self::new_with_commitment(url, CommitmentConfig::default()) } @@ -213,7 +213,7 @@ impl RpcClient { /// let commitment_config = CommitmentConfig::processed(); /// let client = RpcClient::new_with_commitment(url, commitment_config); /// ``` - pub fn new_with_commitment(url: String, commitment_config: CommitmentConfig) -> Self { + pub fn new_with_commitment(url: U, commitment_config: CommitmentConfig) -> Self { Self::new_sender( HttpSender::new(url), RpcClientConfig::with_commitment(commitment_config), @@ -239,7 +239,7 @@ impl RpcClient { /// let timeout = Duration::from_secs(1); /// let client = RpcClient::new_with_timeout(url, timeout); /// ``` - pub fn new_with_timeout(url: String, timeout: Duration) -> Self { + pub fn new_with_timeout(url: U, timeout: Duration) -> Self { Self::new_sender( HttpSender::new_with_timeout(url, timeout), RpcClientConfig::with_commitment(CommitmentConfig::default()), @@ -268,8 +268,8 @@ impl RpcClient { /// commitment_config, /// ); /// ``` - pub fn new_with_timeout_and_commitment( - url: String, + pub fn new_with_timeout_and_commitment( + url: U, timeout: Duration, commitment_config: CommitmentConfig, ) -> Self { @@ -311,8 +311,8 @@ impl RpcClient { /// confirm_transaction_initial_timeout, /// ); /// ``` - pub fn new_with_timeouts_and_commitment( - url: String, + pub fn new_with_timeouts_and_commitment( + url: U, timeout: Duration, commitment_config: CommitmentConfig, confirm_transaction_initial_timeout: Duration, @@ -346,7 +346,7 @@ impl RpcClient { /// let url = "fails".to_string(); /// let successful_client = RpcClient::new_mock(url); /// ``` - pub fn new_mock(url: String) -> Self { + pub fn new_mock(url: U) -> Self { Self::new_sender( MockSender::new(url), RpcClientConfig::with_commitment(CommitmentConfig::default()), @@ -380,7 +380,7 @@ impl RpcClient { /// let url = "succeeds".to_string(); /// let client = RpcClient::new_mock_with_mocks(url, mocks); /// ``` - pub fn new_mock_with_mocks(url: String, mocks: Mocks) -> Self { + pub fn new_mock_with_mocks(url: U, mocks: Mocks) -> Self { Self::new_sender( MockSender::new_with_mocks(url, mocks), RpcClientConfig::with_commitment(CommitmentConfig::default()), diff --git a/core/src/test_validator.rs b/core/src/test_validator.rs index 3d5ab92e48..a1bcd78c19 100644 --- a/core/src/test_validator.rs +++ b/core/src/test_validator.rs @@ -95,10 +95,7 @@ impl Default for TestValidatorGenesis { fee_rate_governor: FeeRateGovernor::default(), ledger_path: Option::::default(), rent: Rent::default(), - rpc_config: JsonRpcConfig { - full_api: true, - ..JsonRpcConfig::default() - }, + rpc_config: JsonRpcConfig::default_for_test(), rpc_ports: Option::<(u16, u16)>::default(), warp_slot: Option::::default(), no_bpf_jit: bool::default(), diff --git a/rpc/src/rpc.rs b/rpc/src/rpc.rs index de8fd8514c..618a2724e5 100644 --- a/rpc/src/rpc.rs +++ b/rpc/src/rpc.rs @@ -2318,6 +2318,9 @@ pub mod rpc_minimal { commitment: Option, ) -> Result; + #[rpc(meta, name = "getGenesisHash")] + fn get_genesis_hash(&self, meta: Self::Metadata) -> Result; + #[rpc(meta, name = "getHealth")] fn get_health(&self, meta: Self::Metadata) -> Result; @@ -2396,6 +2399,11 @@ pub mod rpc_minimal { Ok(bank.get_epoch_info()) } + fn get_genesis_hash(&self, meta: Self::Metadata) -> Result { + debug!("get_genesis_hash rpc request received"); + Ok(meta.genesis_hash.to_string()) + } + fn get_health(&self, meta: Self::Metadata) -> Result { match meta.health.check() { RpcHealthStatus::Ok => Ok("ok".to_string()), @@ -2591,9 +2599,6 @@ pub mod rpc_full { block: Slot, ) -> Result>; - #[rpc(meta, name = "getGenesisHash")] - fn get_genesis_hash(&self, meta: Self::Metadata) -> Result; - #[rpc(meta, name = "getRecentBlockhash")] fn get_recent_blockhash( &self, @@ -3001,11 +3006,6 @@ pub mod rpc_full { Ok(meta.get_block_commitment(block)) } - fn get_genesis_hash(&self, meta: Self::Metadata) -> Result { - debug!("get_genesis_hash rpc request received"); - Ok(meta.genesis_hash.to_string()) - } - fn get_recent_blockhash( &self, meta: Self::Metadata, diff --git a/validator/src/main.rs b/validator/src/main.rs index 4a48499c3b..2d80233e3a 100644 --- a/validator/src/main.rs +++ b/validator/src/main.rs @@ -745,7 +745,7 @@ struct RpcBootstrapConfig { no_snapshot_fetch: bool, only_known_rpc: bool, max_genesis_archive_unpacked_size: u64, - no_check_vote_account: bool, + check_vote_account: Option, } impl Default for RpcBootstrapConfig { @@ -755,7 +755,7 @@ impl Default for RpcBootstrapConfig { no_snapshot_fetch: true, only_known_rpc: true, max_genesis_archive_unpacked_size: MAX_GENESIS_ARCHIVE_UNPACKED_SIZE, - no_check_vote_account: true, + check_vote_account: None, } } } @@ -976,7 +976,8 @@ fn rpc_bootstrap( } }) .map(|_| { - if !validator_config.voting_disabled && !bootstrap_config.no_check_vote_account { + if let Some(url) = bootstrap_config.check_vote_account.as_ref() { + let rpc_client = RpcClient::new(url); check_vote_account( &rpc_client, &identity_keypair.pubkey(), @@ -1172,8 +1173,18 @@ pub fn main() { .takes_value(false) .conflicts_with("no_voting") .requires("entrypoint") + .hidden(true) .help("Skip the RPC vote account sanity check") ) + .arg( + Arg::with_name("check_vote_account") + .long("check-vote-account") + .takes_value(true) + .value_name("RPC_URL") + .requires("entrypoint") + .conflicts_with_all(&["no_check_vote_account", "no_voting"]) + .help("Sanity check vote account state at startup. The JSON RPC endpoint at RPC_URL must expose `--full-rpc-api`") + ) .arg( Arg::with_name("restricted_repair_only_mode") .long("restricted-repair-only-mode") @@ -2310,10 +2321,15 @@ pub fn main() { let init_complete_file = matches.value_of("init_complete_file"); + if matches.is_present("no_check_vote_account") { + info!("vote account sanity checks are no longer performed by default. --no-check-vote-account is deprecated and can be removed from the command line"); + } let rpc_bootstrap_config = RpcBootstrapConfig { no_genesis_fetch: matches.is_present("no_genesis_fetch"), no_snapshot_fetch: matches.is_present("no_snapshot_fetch"), - no_check_vote_account: matches.is_present("no_check_vote_account"), + check_vote_account: matches + .value_of("check_vote_account") + .map(|url| url.to_string()), only_known_rpc: matches.is_present("only_known_rpc"), max_genesis_archive_unpacked_size: value_t_or_exit!( matches,