From 31d9396395e6422af6f9511b864afa5bbb020df3 Mon Sep 17 00:00:00 2001
From: Robert Habermeier <rphmeier@gmail.com>
Date: Sat, 6 Feb 2021 05:26:45 -0600
Subject: [PATCH] Send view to new peers (#2392)

* send our view to new peers immediately

* guide: update

* Fix tests by expecting the view updates

* Add test that we send our view on connection

Co-authored-by: Sergei Shulepov <sergei@parity.io>
---
 polkadot/node/network/bridge/src/lib.rs       | 120 ++++++++++++++----
 .../src/node/utility/network-bridge.md        |   2 +-
 2 files changed, 97 insertions(+), 25 deletions(-)

diff --git a/polkadot/node/network/bridge/src/lib.rs b/polkadot/node/network/bridge/src/lib.rs
index 4e1c179e008..41fec833209 100644
--- a/polkadot/node/network/bridge/src/lib.rs
+++ b/polkadot/node/network/bridge/src/lib.rs
@@ -306,26 +306,48 @@ where
 						});
 
 						match peer_set {
-							PeerSet::Validation => dispatch_validation_events_to_all(
-								vec![
-									NetworkBridgeEvent::PeerConnected(peer.clone(), role),
-									NetworkBridgeEvent::PeerViewChange(
-										peer,
-										View::default(),
+							PeerSet::Validation => {
+								dispatch_validation_events_to_all(
+									vec![
+										NetworkBridgeEvent::PeerConnected(peer.clone(), role),
+										NetworkBridgeEvent::PeerViewChange(
+											peer.clone(),
+											View::default(),
+										),
+									],
+									&mut ctx,
+								).await;
+
+								send_message(
+									&mut bridge.network_service,
+									vec![peer],
+									PeerSet::Validation,
+									WireMessage::<protocol_v1::ValidationProtocol>::ViewUpdate(
+										local_view.clone()
 									),
-								],
-								&mut ctx,
-							).await,
-							PeerSet::Collation => dispatch_collation_events_to_all(
-								vec![
-									NetworkBridgeEvent::PeerConnected(peer.clone(), role),
-									NetworkBridgeEvent::PeerViewChange(
-										peer,
-										View::default(),
+								).await?;
+							}
+							PeerSet::Collation => {
+								dispatch_collation_events_to_all(
+									vec![
+										NetworkBridgeEvent::PeerConnected(peer.clone(), role),
+										NetworkBridgeEvent::PeerViewChange(
+											peer.clone(),
+											View::default(),
+										),
+									],
+									&mut ctx,
+								).await;
+
+								send_message(
+									&mut bridge.network_service,
+									vec![peer],
+									PeerSet::Collation,
+									WireMessage::<protocol_v1::CollationProtocol>::ViewUpdate(
+										local_view.clone()
 									),
-								],
-								&mut ctx,
-							).await,
+								).await?;
+							}
 						}
 					}
 				}
@@ -831,6 +853,51 @@ mod tests {
 		)
 	}
 
+	#[test]
+	fn send_our_view_upon_connection() {
+		test_harness(|test_harness| async move {
+			let TestHarness {
+				mut network_handle,
+				mut virtual_overseer,
+			} = test_harness;
+
+			let peer = PeerId::random();
+
+			let head = Hash::repeat_byte(1);
+			virtual_overseer.send(
+				FromOverseer::Signal(OverseerSignal::ActiveLeaves(
+					ActiveLeavesUpdate::start_work(head, Arc::new(JaegerSpan::Disabled)),
+				))
+			).await;
+
+			network_handle.connect_peer(peer.clone(), PeerSet::Validation, ObservedRole::Full).await;
+			network_handle.connect_peer(peer.clone(), PeerSet::Collation, ObservedRole::Full).await;
+
+			let view = view![head];
+			let actions = network_handle.next_network_actions(2).await;
+			assert_network_actions_contains(
+				&actions,
+				&NetworkAction::WriteNotification(
+					peer.clone(),
+					PeerSet::Validation,
+					WireMessage::<protocol_v1::ValidationProtocol>::ViewUpdate(
+						view.clone(),
+					).encode(),
+				),
+			);
+			assert_network_actions_contains(
+				&actions,
+				&NetworkAction::WriteNotification(
+					peer.clone(),
+					PeerSet::Collation,
+					WireMessage::<protocol_v1::CollationProtocol>::ViewUpdate(
+						view.clone(),
+					).encode(),
+				),
+			);
+		});
+	}
+
 	#[test]
 	fn sends_view_updates_to_peers() {
 		test_harness(|test_harness| async move {
@@ -858,7 +925,7 @@ mod tests {
 				))
 			).await;
 
-			let actions = network_handle.next_network_actions(2).await;
+			let actions = network_handle.next_network_actions(4).await;
 			let wire_message = WireMessage::<protocol_v1::ValidationProtocol>::ViewUpdate(
 				view![hash_a]
 			).encode();
@@ -920,7 +987,7 @@ mod tests {
 				))
 			).await;
 
-			let actions = network_handle.next_network_actions(2).await;
+			let actions = network_handle.next_network_actions(4).await;
 			let wire_message = WireMessage::<protocol_v1::ValidationProtocol>::ViewUpdate(
 				View { heads: vec![hash_a], finalized_number: 5 }
 			).encode();
@@ -1110,7 +1177,7 @@ mod tests {
 				))
 			).await;
 
-			let actions = network_handle.next_network_actions(1).await;
+			let actions = network_handle.next_network_actions(3).await;
 			let wire_message = WireMessage::<protocol_v1::ValidationProtocol>::ViewUpdate(
 				view![hash_a]
 			).encode();
@@ -1181,7 +1248,7 @@ mod tests {
 				WireMessage::ProtocolMessage(message.clone()).encode(),
 			).await;
 
-			let actions = network_handle.next_network_actions(1).await;
+			let actions = network_handle.next_network_actions(3).await;
 			assert_network_actions_contains(
 				&actions,
 				&NetworkAction::ReputationChange(
@@ -1302,7 +1369,7 @@ mod tests {
 				))
 			).await;
 
-			let actions = network_handle.next_network_actions(1).await;
+			let actions = network_handle.next_network_actions(2).await;
 			let wire_message = WireMessage::<protocol_v1::ValidationProtocol>::ViewUpdate(
 				View {
 					heads: vec![hash_b],
@@ -1350,7 +1417,7 @@ mod tests {
 				).encode(),
 			).await;
 
-			let actions = network_handle.next_network_actions(1).await;
+			let actions = network_handle.next_network_actions(2).await;
 			assert_network_actions_contains(
 				&actions,
 				&NetworkAction::ReputationChange(
@@ -1399,6 +1466,11 @@ mod tests {
 				).await;
 			}
 
+			// consume peer view changes
+			{
+				let _peer_view_changes = network_handle.next_network_actions(2).await;
+			}
+
 			// send a validation protocol message.
 
 			{
diff --git a/polkadot/roadmap/implementers-guide/src/node/utility/network-bridge.md b/polkadot/roadmap/implementers-guide/src/node/utility/network-bridge.md
index abcff82a16b..7f3d3446d7e 100644
--- a/polkadot/roadmap/implementers-guide/src/node/utility/network-bridge.md
+++ b/polkadot/roadmap/implementers-guide/src/node/utility/network-bridge.md
@@ -67,7 +67,7 @@ We update our view's `finalized_number` to the provided one and delay `ProtocolM
 
 ### Network Event: Peer Connected
 
-Issue a `NetworkBridgeEvent::PeerConnected` for each [Event Handler](#event-handlers) of the peer-set and negotiated protocol version of the peer.
+Issue a `NetworkBridgeEvent::PeerConnected` for each [Event Handler](#event-handlers) of the peer-set and negotiated protocol version of the peer. Also issue a `NetworkBridgeEvent::PeerViewChange` and send the peer our current view.
 
 ### Network Event: Peer Disconnected
 
-- 
GitLab