From 23355189922757e41423df2df647717ab046cf2d Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 18 Oct 2022 20:58:37 +0000 Subject: [PATCH] enforces hash domain for ping-pong protocol (backport #28433) (#28453) enforces hash domain for ping-pong protocol (#28433) https://github.com/solana-labs/solana/pull/27193 added hash domain to ping-pong protocol. For backward compatibility responses both with and without domain were generated and accepted. Now that all clusters are upgraded, this commit enforces the hash domain by removing the response without the domain. (cherry picked from commit e283461d9901ccd3c845c21521aae7a3ff23695d) Co-authored-by: behzad nouri --- core/src/ancestor_hashes_service.rs | 13 ++++--------- core/src/serve_repair.rs | 15 +++++---------- gossip/src/cluster_info.rs | 30 ++++++++++++----------------- gossip/src/ping_pong.rs | 29 ++++------------------------ 4 files changed, 25 insertions(+), 62 deletions(-) diff --git a/core/src/ancestor_hashes_service.rs b/core/src/ancestor_hashes_service.rs index 98972928cee7e5..f8e3eb1dcb49c0 100644 --- a/core/src/ancestor_hashes_service.rs +++ b/core/src/ancestor_hashes_service.rs @@ -430,15 +430,10 @@ impl AncestorHashesService { return None; } stats.ping_count += 1; - // Respond both with and without domain so that the other node - // will accept the response regardless of its upgrade status. - // TODO: remove domain = false once cluster is upgraded. - for domain in [false, true] { - if let Ok(pong) = Pong::new(domain, &ping, keypair) { - let pong = RepairProtocol::Pong(pong); - if let Ok(pong_bytes) = serialize(&pong) { - let _ignore = ancestor_socket.send_to(&pong_bytes[..], from_addr); - } + if let Ok(pong) = Pong::new(&ping, keypair) { + let pong = RepairProtocol::Pong(pong); + if let Ok(pong_bytes) = serialize(&pong) { + let _ignore = ancestor_socket.send_to(&pong_bytes[..], from_addr); } } None diff --git a/core/src/serve_repair.rs b/core/src/serve_repair.rs index f90489e4c09ef2..a34ec4a3e81768 100644 --- a/core/src/serve_repair.rs +++ b/core/src/serve_repair.rs @@ -900,16 +900,11 @@ impl ServeRepair { } packet.meta.set_discard(true); stats.ping_count += 1; - // Respond both with and without domain so that the other node - // will accept the response regardless of its upgrade status. - // TODO: remove domain = false once cluster is upgraded. - for domain in [false, true] { - if let Ok(pong) = Pong::new(domain, &ping, keypair) { - let pong = RepairProtocol::Pong(pong); - if let Ok(pong_bytes) = serialize(&pong) { - let from_addr = packet.meta.socket_addr(); - pending_pongs.push((pong_bytes, from_addr)); - } + if let Ok(pong) = Pong::new(&ping, keypair) { + let pong = RepairProtocol::Pong(pong); + if let Ok(pong_bytes) = serialize(&pong) { + let from_addr = packet.meta.socket_addr(); + pending_pongs.push((pong_bytes, from_addr)); } } } diff --git a/gossip/src/cluster_info.rs b/gossip/src/cluster_info.rs index 466f75cfaf50e4..c8180b5864e872 100644 --- a/gossip/src/cluster_info.rs +++ b/gossip/src/cluster_info.rs @@ -2173,18 +2173,14 @@ impl ClusterInfo { I: IntoIterator, { let keypair = self.keypair(); - let mut pongs_and_dests = Vec::new(); - for (addr, ping) in pings { - // Respond both with and without domain so that the other node will - // accept the response regardless of its upgrade status. - // TODO: remove domain = false once cluster is upgraded. - for domain in [false, true] { - if let Ok(pong) = Pong::new(domain, &ping, &keypair) { - let pong = Protocol::PongMessage(pong); - pongs_and_dests.push((addr, pong)); - } - } - } + let pongs_and_dests: Vec<_> = pings + .into_iter() + .filter_map(|(addr, ping)| { + let pong = Pong::new(&ping, &keypair).ok()?; + let pong = Protocol::PongMessage(pong); + Some((addr, pong)) + }) + .collect(); if pongs_and_dests.is_empty() { None } else { @@ -3320,9 +3316,7 @@ RPC Enabled Nodes: 1"#; let pongs: Vec<(SocketAddr, Pong)> = pings .iter() .zip(&remote_nodes) - .map(|(ping, (keypair, socket))| { - (*socket, Pong::new(/*domain:*/ true, ping, keypair).unwrap()) - }) + .map(|(ping, (keypair, socket))| (*socket, Pong::new(ping, keypair).unwrap())) .collect(); let now = now + Duration::from_millis(1); cluster_info.handle_batch_pong_messages(pongs, now); @@ -3365,7 +3359,7 @@ RPC Enabled Nodes: 1"#; .collect(); let pongs: Vec<_> = pings .iter() - .map(|ping| Pong::new(/*domain:*/ false, ping, &this_node).unwrap()) + .map(|ping| Pong::new(ping, &this_node).unwrap()) .collect(); let recycler = PacketBatchRecycler::default(); let packets = cluster_info @@ -3377,9 +3371,9 @@ RPC Enabled Nodes: 1"#; &recycler, ) .unwrap(); - assert_eq!(remote_nodes.len() * 2, packets.len()); + assert_eq!(remote_nodes.len(), packets.len()); for (packet, (_, socket), pong) in izip!( - packets.into_iter().step_by(2), + packets.into_iter(), remote_nodes.into_iter(), pongs.into_iter() ) { diff --git a/gossip/src/ping_pong.rs b/gossip/src/ping_pong.rs index f6e47c6907eb0f..6c7399281e9913 100644 --- a/gossip/src/ping_pong.rs +++ b/gossip/src/ping_pong.rs @@ -104,17 +104,9 @@ impl Signable for Ping { } impl Pong { - pub fn new( - domain: bool, - ping: &Ping, - keypair: &Keypair, - ) -> Result { + pub fn new(ping: &Ping, keypair: &Keypair) -> Result { let token = serialize(&ping.token)?; - let hash = if domain { - hash::hashv(&[PING_PONG_HASH_PREFIX, &token]) - } else { - hash::hash(&token) - }; + let hash = hash::hashv(&[PING_PONG_HASH_PREFIX, &token]); let pong = Pong { from: keypair.pubkey(), hash, @@ -203,11 +195,6 @@ impl PingCache { _ => { let ping = pingf()?; let token = serialize(&ping.token).ok()?; - // For backward compatibility, for now responses both with and - // without domain are accepted. - // TODO: remove no domain case once cluster is upgraded. - let hash = hash::hash(&token); - self.pending_cache.put(hash, node); let hash = hash::hashv(&[PING_PONG_HASH_PREFIX, &token]); self.pending_cache.put(hash, node); self.pings.put(node, now); @@ -303,12 +290,7 @@ mod tests { assert!(ping.verify()); assert!(ping.sanitize().is_ok()); - let pong = Pong::new(/*domain:*/ false, &ping, &keypair).unwrap(); - assert!(pong.verify()); - assert!(pong.sanitize().is_ok()); - assert_eq!(hash::hash(&ping.token), pong.hash); - - let pong = Pong::new(/*domian:*/ true, &ping, &keypair).unwrap(); + let pong = Pong::new(&ping, &keypair).unwrap(); assert!(pong.verify()); assert!(pong.sanitize().is_ok()); assert_eq!( @@ -370,10 +352,7 @@ mod tests { assert!(ping.is_none()); } Some(ping) => { - let domain = rng.gen_ratio(1, 2); - let pong = Pong::new(domain, ping, keypair).unwrap(); - assert!(cache.add(&pong, *socket, now)); - let pong = Pong::new(!domain, ping, keypair).unwrap(); + let pong = Pong::new(ping, keypair).unwrap(); assert!(cache.add(&pong, *socket, now)); } }