diff --git a/core/src/rpc.rs b/core/src/rpc.rs index f24a7138f..4fc5d234e 100644 --- a/core/src/rpc.rs +++ b/core/src/rpc.rs @@ -45,21 +45,13 @@ fn new_response(bank: &Bank, value: T) -> RpcResponse { Ok(Response { context, value }) } -#[derive(Debug, Clone)] +#[derive(Debug, Default, Clone)] pub struct JsonRpcConfig { - pub enable_validator_exit: bool, // Enable the 'validatorExit' command + pub rpc_ports: Option<(u16, u16)>, // (API, PubSub) + pub enable_validator_exit: bool, // Enable the 'validatorExit' command pub faucet_addr: Option, } -impl Default for JsonRpcConfig { - fn default() -> Self { - Self { - enable_validator_exit: false, - faucet_addr: None, - } - } -} - #[derive(Clone)] pub struct JsonRpcRequestProcessor { bank_forks: Arc>, diff --git a/core/src/validator.rs b/core/src/validator.rs index ec2df2dc3..e56f81236 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -116,8 +116,7 @@ impl ValidatorExit { pub struct Validator { pub id: Pubkey, validator_exit: Arc>>, - rpc_service: Option, - rpc_pubsub_service: Option, + rpc_service: Option<(JsonRpcService, PubSubService)>, transaction_status_service: Option, gossip_service: GossipService, poh_recorder: Arc>, @@ -219,36 +218,32 @@ impl Validator { let blockstore = Arc::new(blockstore); - let rpc_service = if node.info.rpc.port() == 0 { - None - } else { - Some(JsonRpcService::new( - SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), node.info.rpc.port()), - config.rpc_config.clone(), - bank_forks.clone(), - block_commitment_cache.clone(), - blockstore.clone(), - cluster_info.clone(), - genesis_hash, - ledger_path, - storage_state.clone(), - validator_exit.clone(), - )) - }; - let subscriptions = Arc::new(RpcSubscriptions::new(&exit)); - let rpc_pubsub_service = if node.info.rpc_pubsub.port() == 0 { - None - } else { - Some(PubSubService::new( - &subscriptions, - SocketAddr::new( - IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), - node.info.rpc_pubsub.port(), - ), - &exit, - )) - }; + + let rpc_service = config + .rpc_config + .rpc_ports + .map(|(rpc_port, rpc_pubsub_port)| { + ( + JsonRpcService::new( + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), rpc_port), + config.rpc_config.clone(), + bank_forks.clone(), + block_commitment_cache.clone(), + blockstore.clone(), + cluster_info.clone(), + genesis_hash, + ledger_path, + storage_state.clone(), + validator_exit.clone(), + ), + PubSubService::new( + &subscriptions, + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), rpc_pubsub_port), + &exit, + ), + ) + }); let (transaction_status_sender, transaction_status_service) = if rpc_service.is_some() && !config.transaction_status_service_disabled { @@ -420,7 +415,6 @@ impl Validator { id, gossip_service, rpc_service, - rpc_pubsub_service, transaction_status_service, tpu, tvu, @@ -471,10 +465,8 @@ impl Validator { pub fn join(self) -> Result<()> { self.poh_service.join()?; drop(self.poh_recorder); - if let Some(rpc_service) = self.rpc_service { + if let Some((rpc_service, rpc_pubsub_service)) = self.rpc_service { rpc_service.join()?; - } - if let Some(rpc_pubsub_service) = self.rpc_pubsub_service { rpc_pubsub_service.join()?; } if let Some(transaction_status_service) = self.transaction_status_service { diff --git a/validator/src/main.rs b/validator/src/main.rs index 430f223a3..0583174fd 100644 --- a/validator/src/main.rs +++ b/validator/src/main.rs @@ -496,6 +496,12 @@ pub fn main() { .validator(port_validator) .help("RPC port to use for this node"), ) + .arg( + Arg::with_name("private_rpc") + .long("--private-rpc") + .takes_value(false) + .help("Do not publish the RPC port for use by other nodes") + ) .arg( Arg::with_name("enable_rpc_exit") .long("enable-rpc-exit") @@ -657,7 +663,7 @@ pub fn main() { let cuda = matches.is_present("cuda"); let no_genesis_fetch = matches.is_present("no_genesis_fetch"); let no_snapshot_fetch = matches.is_present("no_snapshot_fetch"); - let rpc_port = value_t!(matches, "rpc_port", u16); + let private_rpc = matches.is_present("private_rpc"); // Canonicalize ledger path to avoid issues with symlink creation let _ = fs::create_dir_all(&ledger_path); @@ -678,6 +684,9 @@ pub fn main() { expected_shred_version: value_t!(matches, "expected_shred_version", u16).ok(), new_hard_forks: hardforks_of(&matches, "hard_forks"), rpc_config: JsonRpcConfig { + rpc_ports: value_t!(matches, "rpc_port", u16) + .ok() + .map(|rpc_port| (rpc_port, rpc_port + 1)), enable_validator_exit: matches.is_present("enable_rpc_exit"), faucet_addr: matches.value_of("rpc_faucet_addr").map(|address| { solana_net_utils::parse_host_port(address).expect("failed to parse faucet address") @@ -852,12 +861,14 @@ pub fn main() { let mut tcp_ports = vec![]; let mut node = Node::new_with_external_ip(&identity_keypair.pubkey(), &gossip_addr, dynamic_port_range); - if let Ok(rpc_port) = rpc_port { - let rpc_pubsub_port = rpc_port + 1; - node.info.rpc = SocketAddr::new(node.info.gossip.ip(), rpc_port); - node.info.rpc_pubsub = SocketAddr::new(node.info.gossip.ip(), rpc_pubsub_port); - tcp_ports = vec![rpc_port, rpc_pubsub_port]; - }; + + if !private_rpc { + if let Some((rpc_port, rpc_pubsub_port)) = validator_config.rpc_config.rpc_ports { + node.info.rpc = SocketAddr::new(node.info.gossip.ip(), rpc_port); + node.info.rpc_pubsub = SocketAddr::new(node.info.gossip.ip(), rpc_pubsub_port); + tcp_ports = vec![rpc_port, rpc_pubsub_port]; + } + } if let Some(ref cluster_entrypoint) = cluster_entrypoint { let udp_sockets = vec![&node.sockets.gossip, &node.sockets.repair];