From 8fd839df9d689822fdd830aa1c78099f342ea58f Mon Sep 17 00:00:00 2001
From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com>
Date: Wed, 17 Apr 2024 11:29:08 +0300
Subject: [PATCH] grandpa: Send neighbor packet to lightclients with every
 finalized head (#4135)

This PR sends the GrandpaNeighbor packet to lightclients similarly to
the full-nodes.

Previously, the lightclient would receive a GrandpaNeigbor packet only
when the note set changed.

Related to: https://github.com/paritytech/polkadot-sdk/issues/4120

Next steps:
-  [ ] check with lightclient

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
---
 .../grandpa/src/communication/gossip.rs       | 34 +++++--------------
 1 file changed, 8 insertions(+), 26 deletions(-)

diff --git a/substrate/client/consensus/grandpa/src/communication/gossip.rs b/substrate/client/consensus/grandpa/src/communication/gossip.rs
index 88821faf0ab..c7fe5a46a5e 100644
--- a/substrate/client/consensus/grandpa/src/communication/gossip.rs
+++ b/substrate/client/consensus/grandpa/src/communication/gossip.rs
@@ -810,7 +810,7 @@ impl<Block: BlockT> Inner<Block> {
 		self.live_topics.push(round, set_id);
 		self.peers.reshuffle();
 
-		self.multicast_neighbor_packet(false)
+		self.multicast_neighbor_packet()
 	}
 
 	/// Note that a voter set with given ID has started. Does nothing if the last
@@ -847,10 +847,7 @@ impl<Block: BlockT> Inner<Block> {
 		self.live_topics.push(Round(1), set_id);
 		self.authorities = authorities;
 
-		// when transitioning to a new set we also want to send neighbor packets to light clients,
-		// this is so that they know who to ask justifications from in order to finalize the last
-		// block in the previous set.
-		self.multicast_neighbor_packet(true)
+		self.multicast_neighbor_packet()
 	}
 
 	/// Note that we've imported a commit finalizing a given block. Does nothing if the last
@@ -869,7 +866,7 @@ impl<Block: BlockT> Inner<Block> {
 			return None
 		}
 
-		self.multicast_neighbor_packet(false)
+		self.multicast_neighbor_packet()
 	}
 
 	fn consider_vote(&self, round: Round, set_id: SetId) -> Consider {
@@ -1183,7 +1180,7 @@ impl<Block: BlockT> Inner<Block> {
 		(neighbor_topics, action, catch_up, report)
 	}
 
-	fn multicast_neighbor_packet(&self, force_light: bool) -> MaybeMessage<Block> {
+	fn multicast_neighbor_packet(&self) -> MaybeMessage<Block> {
 		self.local_view.as_ref().map(|local_view| {
 			let packet = NeighborPacket {
 				round: local_view.round,
@@ -1191,22 +1188,7 @@ impl<Block: BlockT> Inner<Block> {
 				commit_finalized_height: *local_view.last_commit_height().unwrap_or(&Zero::zero()),
 			};
 
-			let peers = self
-				.peers
-				.inner
-				.iter()
-				.filter_map(|(id, info)| {
-					// light clients don't participate in the full GRANDPA voter protocol
-					// and therefore don't need to be informed about all view updates unless
-					// we explicitly require it (e.g. when transitioning to a new set)
-					if info.roles.is_light() && !force_light {
-						None
-					} else {
-						Some(id)
-					}
-				})
-				.cloned()
-				.collect();
+			let peers = self.peers.inner.iter().map(|(id, _)| id).cloned().collect();
 
 			(peers, packet)
 		})
@@ -2602,7 +2584,7 @@ mod tests {
 	}
 
 	#[test]
-	fn sends_neighbor_packets_to_non_light_peers_when_starting_a_new_round() {
+	fn sends_neighbor_packets_to_all_peers_when_starting_a_new_round() {
 		let (val, _) = GossipValidator::<Block>::new(config(), voter_set_state(), None, None);
 
 		// initialize the validator to a stable set id
@@ -2617,10 +2599,10 @@ mod tests {
 		val.inner.write().peers.new_peer(light_peer, ObservedRole::Light);
 
 		val.note_round(Round(2), |peers, message| {
-			assert_eq!(peers.len(), 2);
+			assert_eq!(peers.len(), 3);
 			assert!(peers.contains(&authority_peer));
 			assert!(peers.contains(&full_peer));
-			assert!(!peers.contains(&light_peer));
+			assert!(peers.contains(&light_peer));
 			assert!(matches!(message, NeighborPacket { set_id: SetId(1), round: Round(2), .. }));
 		});
 	}
-- 
GitLab