refactor grid topology to expose more info to subsystems (#6140)

* refactor grid topology to expose more info to subsystems

* fix grid_topology test

* fix overseer test

* Update node/network/protocol/src/grid_topology.rs

Co-authored-by: Vsevolod Stakhov <vsevolod.stakhov@parity.io>

* Update node/network/protocol/src/grid_topology.rs

Co-authored-by: Andronik <write@reusable.software>

* Update node/network/protocol/src/grid_topology.rs

Co-authored-by: Andronik <write@reusable.software>

* fix bug in populating topology

* fmt

Co-authored-by: Vsevolod Stakhov <vsevolod.stakhov@parity.io>
Co-authored-by: Andronik <write@reusable.software>
This commit is contained in:
asynchronous rob
2022-10-12 18:30:12 -05:00
committed by GitHub
parent bccffcad12
commit a7780e0797
17 changed files with 614 additions and 328 deletions
@@ -20,6 +20,7 @@ use futures::executor::{self, block_on};
use futures_timer::Delay;
use parity_scale_codec::{Decode, Encode};
use polkadot_node_network_protocol::{
grid_topology::{SessionGridTopology, TopologyPeerInfo},
peer_set::ValidationVersion,
request_response::{
v1::{StatementFetchingRequest, StatementFetchingResponse},
@@ -509,7 +510,7 @@ fn peer_view_update_sends_messages() {
let peer = PeerId::random();
executor::block_on(async move {
let mut topology: SessionGridTopology = Default::default();
let mut topology = GridNeighbors::empty();
topology.peers_x = HashSet::from_iter(vec![peer.clone()].into_iter());
update_peer_view_and_maybe_send_unlocked(
peer.clone(),
@@ -639,7 +640,7 @@ fn circulated_statement_goes_to_all_peers_with_view() {
};
let statement = StoredStatement { comparator: &comparator, statement: &statement };
let mut topology: SessionGridTopology = Default::default();
let mut topology = GridNeighbors::empty();
topology.peers_x =
HashSet::from_iter(vec![peer_a.clone(), peer_b.clone(), peer_c.clone()].into_iter());
let needs_dependents = circulate_statement(
@@ -2019,42 +2020,77 @@ fn handle_multiple_seconded_statements() {
.await;
}
// Explicitly add all `lucky` peers to the gossip peers to ensure that neither `peerA` not `peerB`
// receive statements
// Set up a topology which puts peers a & b in a column together.
let gossip_topology = {
let mut t = network_bridge_event::NewGossipTopology {
session: 1,
our_neighbors_x: HashMap::new(),
our_neighbors_y: HashMap::new(),
};
// create a lucky_peers+1 * lucky_peers+1 grid topology where we are at index 2, sharing
// a row with peer_a (0) and peer_b (1) and a column with all the lucky peers.
// the rest is filled with junk.
// This is an absolute garbage hack depending on quirks of the implementation
// and not on sound architecture.
// Create a topology to ensure that we send messages not to `peer_a`/`peer_b`
for (i, peer) in lucky_peers.iter().enumerate() {
let authority_id = AuthorityPair::generate().0.public();
t.our_neighbors_y.insert(
authority_id,
network_bridge_event::TopologyPeerInfo {
peer_ids: vec![peer.clone()],
validator_index: (i as u32 + 2_u32).into(),
},
);
let n_lucky = lucky_peers.len();
let dim = n_lucky + 1;
let grid_size = dim * dim;
let topology_peer_info: Vec<_> = (0..grid_size)
.map(|i| {
if i == 0 {
TopologyPeerInfo {
peer_ids: vec![peer_a.clone()],
validator_index: ValidatorIndex(0),
discovery_id: AuthorityPair::generate().0.public(),
}
} else if i == 1 {
TopologyPeerInfo {
peer_ids: vec![peer_b.clone()],
validator_index: ValidatorIndex(1),
discovery_id: AuthorityPair::generate().0.public(),
}
} else if i == 2 {
TopologyPeerInfo {
peer_ids: vec![],
validator_index: ValidatorIndex(2),
discovery_id: AuthorityPair::generate().0.public(),
}
} else if (i - 2) % dim == 0 {
let lucky_index = ((i - 2) / dim) - 1;
TopologyPeerInfo {
peer_ids: vec![lucky_peers[lucky_index].clone()],
validator_index: ValidatorIndex(i as _),
discovery_id: AuthorityPair::generate().0.public(),
}
} else {
TopologyPeerInfo {
peer_ids: vec![PeerId::random()],
validator_index: ValidatorIndex(i as _),
discovery_id: AuthorityPair::generate().0.public(),
}
}
})
.collect();
// also a hack: this is only required to be accurate for
// the validator indices we compute grid neighbors for.
let mut shuffled_indices = vec![0; grid_size];
shuffled_indices[2] = 2;
// Some sanity checking to make sure this hack is set up correctly.
let topology = SessionGridTopology::new(shuffled_indices, topology_peer_info);
let grid_neighbors = topology.compute_grid_neighbors_for(ValidatorIndex(2)).unwrap();
assert_eq!(grid_neighbors.peers_x.len(), 25);
assert!(grid_neighbors.peers_x.contains(&peer_a));
assert!(grid_neighbors.peers_x.contains(&peer_b));
assert!(!grid_neighbors.peers_y.contains(&peer_b));
assert!(!grid_neighbors.route_to_peer(RequiredRouting::GridY, &peer_b));
assert_eq!(grid_neighbors.peers_y.len(), lucky_peers.len());
for lucky in &lucky_peers {
assert!(grid_neighbors.peers_y.contains(lucky));
}
t.our_neighbors_x.insert(
AuthorityPair::generate().0.public(),
network_bridge_event::TopologyPeerInfo {
peer_ids: vec![peer_a.clone()],
validator_index: 0_u32.into(),
},
);
t.our_neighbors_x.insert(
AuthorityPair::generate().0.public(),
network_bridge_event::TopologyPeerInfo {
peer_ids: vec![peer_b.clone()],
validator_index: 1_u32.into(),
},
);
t
network_bridge_event::NewGossipTopology {
session: 1,
topology,
local_index: Some(ValidatorIndex(2)),
}
};
handle