`solana-gossip spy` can now specify a shred version (#10040)
This commit is contained in:
parent
c5460e7fee
commit
4e4a21f9b7
|
@ -1849,39 +1849,39 @@ impl ClusterInfo {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gossip_contact_info(id: &Pubkey, gossip: SocketAddr) -> ContactInfo {
|
pub fn gossip_contact_info(id: &Pubkey, gossip: SocketAddr, shred_version: u16) -> ContactInfo {
|
||||||
ContactInfo {
|
ContactInfo {
|
||||||
id: *id,
|
id: *id,
|
||||||
gossip,
|
gossip,
|
||||||
wallclock: timestamp(),
|
wallclock: timestamp(),
|
||||||
|
shred_version,
|
||||||
..ContactInfo::default()
|
..ContactInfo::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spy_contact_info(id: &Pubkey) -> ContactInfo {
|
|
||||||
let dummy_addr = socketaddr_any!();
|
|
||||||
|
|
||||||
Self::gossip_contact_info(id, dummy_addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An alternative to Spy Node that has a valid gossip address and fully participate in Gossip.
|
/// An alternative to Spy Node that has a valid gossip address and fully participate in Gossip.
|
||||||
pub fn gossip_node(
|
pub fn gossip_node(
|
||||||
id: &Pubkey,
|
id: &Pubkey,
|
||||||
gossip_addr: &SocketAddr,
|
gossip_addr: &SocketAddr,
|
||||||
|
shred_version: u16,
|
||||||
) -> (ContactInfo, UdpSocket, Option<TcpListener>) {
|
) -> (ContactInfo, UdpSocket, Option<TcpListener>) {
|
||||||
let bind_ip_addr = IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0));
|
let bind_ip_addr = IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0));
|
||||||
let (port, (gossip_socket, ip_echo)) =
|
let (port, (gossip_socket, ip_echo)) =
|
||||||
Node::get_gossip_port(gossip_addr, VALIDATOR_PORT_RANGE, bind_ip_addr);
|
Node::get_gossip_port(gossip_addr, VALIDATOR_PORT_RANGE, bind_ip_addr);
|
||||||
let contact_info = Self::gossip_contact_info(id, SocketAddr::new(gossip_addr.ip(), port));
|
let contact_info =
|
||||||
|
Self::gossip_contact_info(id, SocketAddr::new(gossip_addr.ip(), port), shred_version);
|
||||||
|
|
||||||
(contact_info, gossip_socket, Some(ip_echo))
|
(contact_info, gossip_socket, Some(ip_echo))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A Node with dummy ports to spy on gossip via pull requests
|
/// A Node with dummy ports to spy on gossip via pull requests
|
||||||
pub fn spy_node(id: &Pubkey) -> (ContactInfo, UdpSocket, Option<TcpListener>) {
|
pub fn spy_node(
|
||||||
|
id: &Pubkey,
|
||||||
|
shred_version: u16,
|
||||||
|
) -> (ContactInfo, UdpSocket, Option<TcpListener>) {
|
||||||
let bind_ip_addr = IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0));
|
let bind_ip_addr = IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0));
|
||||||
let (_, gossip_socket) = bind_in_range(bind_ip_addr, VALIDATOR_PORT_RANGE).unwrap();
|
let (_, gossip_socket) = bind_in_range(bind_ip_addr, VALIDATOR_PORT_RANGE).unwrap();
|
||||||
let contact_info = Self::spy_contact_info(id);
|
let contact_info = Self::gossip_contact_info(id, socketaddr_any!(), shred_version);
|
||||||
|
|
||||||
(contact_info, gossip_socket, None)
|
(contact_info, gossip_socket, None)
|
||||||
}
|
}
|
||||||
|
@ -2181,10 +2181,10 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_gossip_node() {
|
fn test_gossip_node() {
|
||||||
//check that a gossip nodes always show up as spies
|
//check that a gossip nodes always show up as spies
|
||||||
let (node, _, _) = ClusterInfo::spy_node(&Pubkey::new_rand());
|
let (node, _, _) = ClusterInfo::spy_node(&Pubkey::new_rand(), 0);
|
||||||
assert!(ClusterInfo::is_spy_node(&node));
|
assert!(ClusterInfo::is_spy_node(&node));
|
||||||
let (node, _, _) =
|
let (node, _, _) =
|
||||||
ClusterInfo::gossip_node(&Pubkey::new_rand(), &"1.1.1.1:1111".parse().unwrap());
|
ClusterInfo::gossip_node(&Pubkey::new_rand(), &"1.1.1.1:1111".parse().unwrap(), 0);
|
||||||
assert!(ClusterInfo::is_spy_node(&node));
|
assert!(ClusterInfo::is_spy_node(&node));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2192,7 +2192,7 @@ mod tests {
|
||||||
fn test_cluster_spy_gossip() {
|
fn test_cluster_spy_gossip() {
|
||||||
//check that gossip doesn't try to push to invalid addresses
|
//check that gossip doesn't try to push to invalid addresses
|
||||||
let node = Node::new_localhost();
|
let node = Node::new_localhost();
|
||||||
let (spy, _, _) = ClusterInfo::spy_node(&Pubkey::new_rand());
|
let (spy, _, _) = ClusterInfo::spy_node(&Pubkey::new_rand(), 0);
|
||||||
let cluster_info = Arc::new(ClusterInfo::new_with_invalid_keypair(node.info));
|
let cluster_info = Arc::new(ClusterInfo::new_with_invalid_keypair(node.info));
|
||||||
cluster_info.insert_info(spy);
|
cluster_info.insert_info(spy);
|
||||||
cluster_info
|
cluster_info
|
||||||
|
|
|
@ -75,6 +75,7 @@ pub fn discover_cluster(
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
0,
|
||||||
)
|
)
|
||||||
.map(|(_all_peers, validators, archivers)| (validators, archivers))
|
.map(|(_all_peers, validators, archivers)| (validators, archivers))
|
||||||
}
|
}
|
||||||
|
@ -86,9 +87,11 @@ pub fn discover(
|
||||||
find_node_by_pubkey: Option<Pubkey>,
|
find_node_by_pubkey: Option<Pubkey>,
|
||||||
find_node_by_gossip_addr: Option<&SocketAddr>,
|
find_node_by_gossip_addr: Option<&SocketAddr>,
|
||||||
my_gossip_addr: Option<&SocketAddr>,
|
my_gossip_addr: Option<&SocketAddr>,
|
||||||
|
my_shred_version: u16,
|
||||||
) -> std::io::Result<(Vec<ContactInfo>, Vec<ContactInfo>, Vec<ContactInfo>)> {
|
) -> std::io::Result<(Vec<ContactInfo>, Vec<ContactInfo>, Vec<ContactInfo>)> {
|
||||||
let exit = Arc::new(AtomicBool::new(false));
|
let exit = Arc::new(AtomicBool::new(false));
|
||||||
let (gossip_service, ip_echo, spy_ref) = make_gossip_node(entrypoint, &exit, my_gossip_addr);
|
let (gossip_service, ip_echo, spy_ref) =
|
||||||
|
make_gossip_node(entrypoint, &exit, my_gossip_addr, my_shred_version);
|
||||||
|
|
||||||
let id = spy_ref.id();
|
let id = spy_ref.id();
|
||||||
info!("Entrypoint: {:?}", entrypoint);
|
info!("Entrypoint: {:?}", entrypoint);
|
||||||
|
@ -260,12 +263,13 @@ fn make_gossip_node(
|
||||||
entrypoint: Option<&SocketAddr>,
|
entrypoint: Option<&SocketAddr>,
|
||||||
exit: &Arc<AtomicBool>,
|
exit: &Arc<AtomicBool>,
|
||||||
gossip_addr: Option<&SocketAddr>,
|
gossip_addr: Option<&SocketAddr>,
|
||||||
|
shred_version: u16,
|
||||||
) -> (GossipService, Option<TcpListener>, Arc<ClusterInfo>) {
|
) -> (GossipService, Option<TcpListener>, Arc<ClusterInfo>) {
|
||||||
let keypair = Arc::new(Keypair::new());
|
let keypair = Arc::new(Keypair::new());
|
||||||
let (node, gossip_socket, ip_echo) = if let Some(gossip_addr) = gossip_addr {
|
let (node, gossip_socket, ip_echo) = if let Some(gossip_addr) = gossip_addr {
|
||||||
ClusterInfo::gossip_node(&keypair.pubkey(), gossip_addr)
|
ClusterInfo::gossip_node(&keypair.pubkey(), gossip_addr, shred_version)
|
||||||
} else {
|
} else {
|
||||||
ClusterInfo::spy_node(&keypair.pubkey())
|
ClusterInfo::spy_node(&keypair.pubkey(), shred_version)
|
||||||
};
|
};
|
||||||
let cluster_info = ClusterInfo::new(node, keypair);
|
let cluster_info = ClusterInfo::new(node, keypair);
|
||||||
if let Some(entrypoint) = entrypoint {
|
if let Some(entrypoint) = entrypoint {
|
||||||
|
|
|
@ -155,6 +155,7 @@ fn main() {
|
||||||
None,
|
None,
|
||||||
Some(&entrypoint_addr),
|
Some(&entrypoint_addr),
|
||||||
None,
|
None,
|
||||||
|
0,
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|err| {
|
.unwrap_or_else(|err| {
|
||||||
eprintln!("Failed to discover {} node: {:?}", entrypoint_addr, err);
|
eprintln!("Failed to discover {} node: {:?}", entrypoint_addr, err);
|
||||||
|
|
|
@ -15,6 +15,13 @@ use std::process::exit;
|
||||||
fn main() -> Result<(), Box<dyn error::Error>> {
|
fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
solana_logger::setup_with_default("solana=info");
|
solana_logger::setup_with_default("solana=info");
|
||||||
|
|
||||||
|
let shred_version_arg = Arg::with_name("shred_version")
|
||||||
|
.long("shred-version")
|
||||||
|
.value_name("VERSION")
|
||||||
|
.takes_value(true)
|
||||||
|
.default_value("0")
|
||||||
|
.help("Filter gossip nodes by this shred version");
|
||||||
|
|
||||||
let matches = App::new(crate_name!())
|
let matches = App::new(crate_name!())
|
||||||
.about(crate_description!())
|
.about(crate_description!())
|
||||||
.version(solana_version::version!())
|
.version(solana_version::version!())
|
||||||
|
@ -53,6 +60,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
.default_value("5")
|
.default_value("5")
|
||||||
.help("Timeout in seconds"),
|
.help("Timeout in seconds"),
|
||||||
)
|
)
|
||||||
|
.arg(&shred_version_arg)
|
||||||
.setting(AppSettings::DisableVersion),
|
.setting(AppSettings::DisableVersion),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
|
@ -110,6 +118,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
.validator(is_pubkey)
|
.validator(is_pubkey)
|
||||||
.help("Public key of a specific node to wait for"),
|
.help("Public key of a specific node to wait for"),
|
||||||
)
|
)
|
||||||
|
.arg(&shred_version_arg)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("timeout")
|
Arg::with_name("timeout")
|
||||||
.long("timeout")
|
.long("timeout")
|
||||||
|
@ -167,6 +176,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
let pubkey = matches
|
let pubkey = matches
|
||||||
.value_of("node_pubkey")
|
.value_of("node_pubkey")
|
||||||
.map(|pubkey_str| pubkey_str.parse::<Pubkey>().unwrap());
|
.map(|pubkey_str| pubkey_str.parse::<Pubkey>().unwrap());
|
||||||
|
let shred_version = value_t_or_exit!(matches, "shred_version", u16);
|
||||||
|
|
||||||
let entrypoint_addr = parse_entrypoint(&matches);
|
let entrypoint_addr = parse_entrypoint(&matches);
|
||||||
|
|
||||||
|
@ -212,6 +222,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
pubkey,
|
pubkey,
|
||||||
None,
|
None,
|
||||||
Some(&gossip_addr),
|
Some(&gossip_addr),
|
||||||
|
shred_version,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if timeout.is_some() {
|
if timeout.is_some() {
|
||||||
|
@ -251,6 +262,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
let all = matches.is_present("all");
|
let all = matches.is_present("all");
|
||||||
let entrypoint_addr = parse_entrypoint(&matches);
|
let entrypoint_addr = parse_entrypoint(&matches);
|
||||||
let timeout = value_t_or_exit!(matches, "timeout", u64);
|
let timeout = value_t_or_exit!(matches, "timeout", u64);
|
||||||
|
let shred_version = value_t_or_exit!(matches, "shred_version", u16);
|
||||||
let (_all_peers, validators, _archivers) = discover(
|
let (_all_peers, validators, _archivers) = discover(
|
||||||
entrypoint_addr.as_ref(),
|
entrypoint_addr.as_ref(),
|
||||||
Some(1),
|
Some(1),
|
||||||
|
@ -258,6 +270,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
None,
|
None,
|
||||||
entrypoint_addr.as_ref(),
|
entrypoint_addr.as_ref(),
|
||||||
None,
|
None,
|
||||||
|
shred_version,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let rpc_addrs: Vec<_> = validators
|
let rpc_addrs: Vec<_> = validators
|
||||||
|
@ -298,6 +311,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
Some(pubkey),
|
Some(pubkey),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
0,
|
||||||
)?;
|
)?;
|
||||||
let validator = validators.iter().find(|x| x.id == pubkey).unwrap();
|
let validator = validators.iter().find(|x| x.id == pubkey).unwrap();
|
||||||
|
|
||||||
|
|
|
@ -138,9 +138,14 @@ fn start_gossip_node(
|
||||||
entrypoint_gossip: &SocketAddr,
|
entrypoint_gossip: &SocketAddr,
|
||||||
gossip_addr: &SocketAddr,
|
gossip_addr: &SocketAddr,
|
||||||
gossip_socket: UdpSocket,
|
gossip_socket: UdpSocket,
|
||||||
|
expected_shred_version: Option<u16>,
|
||||||
) -> (Arc<ClusterInfo>, Arc<AtomicBool>, GossipService) {
|
) -> (Arc<ClusterInfo>, Arc<AtomicBool>, GossipService) {
|
||||||
let cluster_info = ClusterInfo::new(
|
let cluster_info = ClusterInfo::new(
|
||||||
ClusterInfo::gossip_contact_info(&identity_keypair.pubkey(), *gossip_addr),
|
ClusterInfo::gossip_contact_info(
|
||||||
|
&identity_keypair.pubkey(),
|
||||||
|
*gossip_addr,
|
||||||
|
expected_shred_version.unwrap_or(0),
|
||||||
|
),
|
||||||
identity_keypair.clone(),
|
identity_keypair.clone(),
|
||||||
);
|
);
|
||||||
cluster_info.set_entrypoint(ContactInfo::new_gossip_entry_point(entrypoint_gossip));
|
cluster_info.set_entrypoint(ContactInfo::new_gossip_entry_point(entrypoint_gossip));
|
||||||
|
@ -1129,6 +1134,7 @@ pub fn main() {
|
||||||
&cluster_entrypoint.gossip,
|
&cluster_entrypoint.gossip,
|
||||||
&node.info.gossip,
|
&node.info.gossip,
|
||||||
node.sockets.gossip.try_clone().unwrap(),
|
node.sockets.gossip.try_clone().unwrap(),
|
||||||
|
validator_config.expected_shred_version,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut blacklisted_rpc_nodes = HashSet::new();
|
let mut blacklisted_rpc_nodes = HashSet::new();
|
||||||
|
|
Loading…
Reference in New Issue