From 63a67f415ef3c5bb243b8b91d3c9b054dcdc2227 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Thu, 10 Sep 2020 13:15:22 -0700 Subject: [PATCH] Add --restricted-repair-only-mode flag --- validator/src/main.rs | 88 +++++++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 25 deletions(-) diff --git a/validator/src/main.rs b/validator/src/main.rs index bd0a97187c..81d21e14aa 100644 --- a/validator/src/main.rs +++ b/validator/src/main.rs @@ -607,6 +607,17 @@ pub fn main() { .requires("entrypoint") .help("Skip the RPC vote account sanity check") ) + .arg( + Arg::with_name("restricted_repair_only_mode") + .long("restricted-repair-only-mode") + .takes_value(false) + .help("Do not publish the Gossip, TPU, TVU or Repair Service ports causing \ + the validator to operate in a limited capacity that reduces its \ + exposure to the rest of the cluster. \ + \ + The --no-voting flag is implicit when this flag is enabled \ + "), + ) .arg( Arg::with_name("dev_halt_at_slot") .long("dev-halt-at-slot") @@ -815,7 +826,8 @@ pub fn main() { .requires("expected_bank_hash") .value_name("SLOT") .validator(is_slot) - .help("After processing the ledger and the next slot is SLOT, wait until a supermajority of stake is visible on gossip before starting PoH"), + .help("After processing the ledger and the next slot is SLOT, wait until a \ + supermajority of stake is visible on gossip before starting PoH"), ) .arg( Arg::with_name("hard_forks") @@ -977,6 +989,8 @@ pub fn main() { bind_address }; + let restricted_repair_only_mode = matches.is_present("restricted_repair_only_mode"); + let mut validator_config = ValidatorConfig { dev_halt_at_slot: value_t!(matches, "dev_halt_at_slot", Slot).ok(), expected_genesis_hash: matches @@ -1011,7 +1025,7 @@ pub fn main() { SocketAddr::new(rpc_bind_address, rpc_port + 3), ) }), - voting_disabled: matches.is_present("no_voting"), + voting_disabled: matches.is_present("no_voting") || restricted_repair_only_mode, wait_for_supermajority: value_t!(matches, "wait_for_supermajority", Slot).ok(), trusted_validators, repair_validators, @@ -1022,8 +1036,10 @@ pub fn main() { }; let vote_account = pubkey_of(&matches, "vote_account").unwrap_or_else(|| { - warn!("--vote-account not specified, validator will not vote"); - validator_config.voting_disabled = true; + if !validator_config.voting_disabled { + warn!("--vote-account not specified, validator will not vote"); + validator_config.voting_disabled = true; + } Keypair::new().pubkey() }); @@ -1223,6 +1239,18 @@ pub fn main() { bind_address, ); + if restricted_repair_only_mode { + let any = SocketAddr::new(std::net::IpAddr::V4(std::net::Ipv4Addr::new(0, 0, 0, 0)), 0); + // When in --restricted_repair_only_mode is enabled only the gossip and repair ports + // need to be reachable by the entrypoint to respond to gossip pull requests and repair + // requests initiated by the node. All other ports are unused. + node.info.tpu = any; + node.info.tpu_forwards = any; + node.info.tvu = any; + node.info.tvu_forwards = any; + node.info.serve_repair = any; + } + if !private_rpc { if let Some((rpc_addr, rpc_pubsub_addr, rpc_banks_addr)) = validator_config.rpc_addrs { node.info.rpc = SocketAddr::new(node.info.gossip.ip(), rpc_addr.port()); @@ -1232,26 +1260,34 @@ pub fn main() { } if let Some(ref cluster_entrypoint) = cluster_entrypoint { - let mut udp_sockets = vec![ - &node.sockets.gossip, - &node.sockets.repair, - &node.sockets.serve_repair, - ]; - udp_sockets.extend(node.sockets.tpu.iter()); - udp_sockets.extend(node.sockets.tpu_forwards.iter()); - udp_sockets.extend(node.sockets.tvu.iter()); - udp_sockets.extend(node.sockets.tvu_forwards.iter()); - udp_sockets.extend(node.sockets.broadcast.iter()); - udp_sockets.extend(node.sockets.retransmit_sockets.iter()); + let mut udp_sockets = vec![&node.sockets.gossip, &node.sockets.repair]; + + if ContactInfo::is_valid_address(&node.info.serve_repair) { + udp_sockets.push(&node.sockets.serve_repair); + } + if ContactInfo::is_valid_address(&node.info.tpu) { + udp_sockets.extend(node.sockets.tpu.iter()); + } + if ContactInfo::is_valid_address(&node.info.tpu_forwards) { + udp_sockets.extend(node.sockets.tpu_forwards.iter()); + } + if ContactInfo::is_valid_address(&node.info.tvu) { + udp_sockets.extend(node.sockets.tvu.iter()); + udp_sockets.extend(node.sockets.broadcast.iter()); + udp_sockets.extend(node.sockets.retransmit_sockets.iter()); + } + if ContactInfo::is_valid_address(&node.info.tvu_forwards) { + udp_sockets.extend(node.sockets.tvu_forwards.iter()); + } let mut tcp_listeners = vec![]; - if !private_rpc { - if let Some((rpc_addr, rpc_pubsub_addr, rpc_banks_addr)) = validator_config.rpc_addrs { - for (purpose, addr) in &[ - ("RPC", rpc_addr), - ("RPC pubsub", rpc_pubsub_addr), - ("RPC banks", rpc_banks_addr), - ] { + if let Some((rpc_addr, rpc_pubsub_addr, rpc_banks_addr)) = validator_config.rpc_addrs { + for (purpose, addr) in &[ + ("RPC", rpc_addr), + ("RPC pubsub", rpc_pubsub_addr), + ("RPC banks", rpc_banks_addr), + ] { + if ContactInfo::is_valid_address(&addr) { tcp_listeners.push(( addr.port(), TcpListener::bind(addr).unwrap_or_else(|err| { @@ -1268,9 +1304,11 @@ pub fn main() { } } - if let Some(ip_echo) = &node.sockets.ip_echo { - let ip_echo = ip_echo.try_clone().expect("unable to clone tcp_listener"); - tcp_listeners.push((node.info.gossip.port(), ip_echo)); + if !restricted_repair_only_mode { + if let Some(ip_echo) = &node.sockets.ip_echo { + let ip_echo = ip_echo.try_clone().expect("unable to clone tcp_listener"); + tcp_listeners.push((ip_echo.local_addr().unwrap().port(), ip_echo)); + } } if !solana_net_utils::verify_reachable_ports(