diff --git a/polkadot/node/network/bridge/src/lib.rs b/polkadot/node/network/bridge/src/lib.rs index 4e1c179e00875d440569410293588b55dc493918..41fec833209a8cbe908b1c63643426b28122532c 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 abcff82a16b69e2d7c2a089a705e534192952a22..7f3d3446d7e311cb21614f3b22c68afbb07fa6d9 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