mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 14:37:57 +00:00
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:
@@ -525,73 +525,37 @@ async fn update_gossip_topology(
|
||||
sp_core::blake2_256(&subject)
|
||||
};
|
||||
|
||||
// shuffle the indices
|
||||
let mut rng: ChaCha20Rng = SeedableRng::from_seed(random_seed);
|
||||
let len = authorities.len();
|
||||
let mut indices: Vec<usize> = (0..len).collect();
|
||||
indices.shuffle(&mut rng);
|
||||
let our_shuffled_position = indices
|
||||
.iter()
|
||||
.position(|i| *i == our_index)
|
||||
.expect("our_index < len; indices contains it; qed");
|
||||
// shuffle the validators and create the index mapping
|
||||
let (shuffled_indices, canonical_shuffling) = {
|
||||
let mut rng: ChaCha20Rng = SeedableRng::from_seed(random_seed);
|
||||
let len = authorities.len();
|
||||
let mut shuffled_indices = vec![0; len];
|
||||
let mut canonical_shuffling: Vec<_> = authorities
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, a)| (a.clone(), ValidatorIndex(i as _)))
|
||||
.collect();
|
||||
|
||||
let neighbors = matrix_neighbors(our_shuffled_position, len);
|
||||
let row_neighbors = neighbors
|
||||
.row_neighbors
|
||||
.map(|i| indices[i])
|
||||
.map(|i| (authorities[i].clone(), ValidatorIndex::from(i as u32)))
|
||||
.collect();
|
||||
canonical_shuffling.shuffle(&mut rng);
|
||||
for (i, (_, validator_index)) in canonical_shuffling.iter().enumerate() {
|
||||
shuffled_indices[validator_index.0 as usize] = i;
|
||||
}
|
||||
|
||||
let column_neighbors = neighbors
|
||||
.column_neighbors
|
||||
.map(|i| indices[i])
|
||||
.map(|i| (authorities[i].clone(), ValidatorIndex::from(i as u32)))
|
||||
.collect();
|
||||
(shuffled_indices, canonical_shuffling)
|
||||
};
|
||||
|
||||
sender
|
||||
.send_message(NetworkBridgeRxMessage::NewGossipTopology {
|
||||
session: session_index,
|
||||
our_neighbors_x: row_neighbors,
|
||||
our_neighbors_y: column_neighbors,
|
||||
local_index: Some(ValidatorIndex(our_index as _)),
|
||||
canonical_shuffling,
|
||||
shuffled_indices,
|
||||
})
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct MatrixNeighbors<R, C> {
|
||||
row_neighbors: R,
|
||||
column_neighbors: C,
|
||||
}
|
||||
|
||||
/// Compute our row and column neighbors in a matrix
|
||||
fn matrix_neighbors(
|
||||
our_index: usize,
|
||||
len: usize,
|
||||
) -> MatrixNeighbors<impl Iterator<Item = usize>, impl Iterator<Item = usize>> {
|
||||
assert!(our_index < len, "our_index is computed using `enumerate`; qed");
|
||||
|
||||
// e.g. for size 11 the matrix would be
|
||||
//
|
||||
// 0 1 2
|
||||
// 3 4 5
|
||||
// 6 7 8
|
||||
// 9 10
|
||||
//
|
||||
// and for index 10, the neighbors would be 1, 4, 7, 9
|
||||
|
||||
let sqrt = (len as f64).sqrt() as usize;
|
||||
let our_row = our_index / sqrt;
|
||||
let our_column = our_index % sqrt;
|
||||
let row_neighbors = our_row * sqrt..std::cmp::min(our_row * sqrt + sqrt, len);
|
||||
let column_neighbors = (our_column..len).step_by(sqrt);
|
||||
|
||||
MatrixNeighbors {
|
||||
row_neighbors: row_neighbors.filter(move |i| *i != our_index),
|
||||
column_neighbors: column_neighbors.filter(move |i| *i != our_index),
|
||||
}
|
||||
}
|
||||
|
||||
#[overseer::subsystem(GossipSupport, error = SubsystemError, prefix = self::overseer)]
|
||||
impl<Context, AD> GossipSupport<AD>
|
||||
where
|
||||
|
||||
@@ -29,6 +29,7 @@ use sp_consensus_babe::{AllowedSlots, BabeEpochConfiguration, Epoch as BabeEpoch
|
||||
use sp_core::crypto::Pair as PairT;
|
||||
use sp_keyring::Sr25519Keyring;
|
||||
|
||||
use polkadot_node_network_protocol::grid_topology::{SessionGridTopology, TopologyPeerInfo};
|
||||
use polkadot_node_subsystem::{
|
||||
jaeger,
|
||||
messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest},
|
||||
@@ -73,13 +74,15 @@ lazy_static! {
|
||||
// [1 3]
|
||||
// [0 ]
|
||||
|
||||
static ref ROW_NEIGHBORS: Vec<(AuthorityDiscoveryId, ValidatorIndex)> = vec![
|
||||
(Sr25519Keyring::Charlie.public().into(), ValidatorIndex::from(2)),
|
||||
static ref EXPECTED_SHUFFLING: Vec<usize> = vec![6, 4, 0, 5, 2, 3, 1];
|
||||
|
||||
static ref ROW_NEIGHBORS: Vec<ValidatorIndex> = vec![
|
||||
ValidatorIndex::from(2),
|
||||
];
|
||||
|
||||
static ref COLUMN_NEIGHBORS: Vec<(AuthorityDiscoveryId, ValidatorIndex)> = vec![
|
||||
(Sr25519Keyring::Two.public().into(), ValidatorIndex::from(5)),
|
||||
(Sr25519Keyring::Eve.public().into(), ValidatorIndex::from(3)),
|
||||
static ref COLUMN_NEIGHBORS: Vec<ValidatorIndex> = vec![
|
||||
ValidatorIndex::from(3),
|
||||
ValidatorIndex::from(5),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -257,12 +260,31 @@ async fn test_neighbors(overseer: &mut VirtualOverseer, expected_session: Sessio
|
||||
overseer_recv(overseer).await,
|
||||
AllMessages::NetworkBridgeRx(NetworkBridgeRxMessage::NewGossipTopology {
|
||||
session: got_session,
|
||||
our_neighbors_x,
|
||||
our_neighbors_y,
|
||||
local_index,
|
||||
canonical_shuffling,
|
||||
shuffled_indices,
|
||||
}) => {
|
||||
assert_eq!(expected_session, got_session);
|
||||
let mut got_row: Vec<_> = our_neighbors_x.into_iter().collect();
|
||||
let mut got_column: Vec<_> = our_neighbors_y.into_iter().collect();
|
||||
assert_eq!(local_index, Some(ValidatorIndex(6)));
|
||||
assert_eq!(shuffled_indices, EXPECTED_SHUFFLING.clone());
|
||||
|
||||
let grid_topology = SessionGridTopology::new(
|
||||
shuffled_indices,
|
||||
canonical_shuffling.into_iter()
|
||||
.map(|(a, v)| TopologyPeerInfo {
|
||||
validator_index: v,
|
||||
discovery_id: a,
|
||||
peer_ids: Vec::new(),
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
|
||||
let grid_neighbors = grid_topology
|
||||
.compute_grid_neighbors_for(local_index.unwrap())
|
||||
.unwrap();
|
||||
|
||||
let mut got_row: Vec<_> = grid_neighbors.validator_indices_x.into_iter().collect();
|
||||
let mut got_column: Vec<_> = grid_neighbors.validator_indices_y.into_iter().collect();
|
||||
got_row.sort();
|
||||
got_column.sort();
|
||||
assert_eq!(got_row, ROW_NEIGHBORS.clone());
|
||||
@@ -694,26 +716,3 @@ fn issues_a_connection_request_when_last_request_was_mostly_unresolved() {
|
||||
assert_eq!(state.last_session_index, Some(1));
|
||||
assert!(state.last_failure.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_matrix_neighbors() {
|
||||
for (our_index, len, expected_row, expected_column) in vec![
|
||||
(0usize, 1usize, vec![], vec![]),
|
||||
(1, 2, vec![], vec![0usize]),
|
||||
(0, 9, vec![1, 2], vec![3, 6]),
|
||||
(9, 10, vec![], vec![0, 3, 6]),
|
||||
(10, 11, vec![9], vec![1, 4, 7]),
|
||||
(7, 11, vec![6, 8], vec![1, 4, 10]),
|
||||
]
|
||||
.into_iter()
|
||||
{
|
||||
let matrix = matrix_neighbors(our_index, len);
|
||||
let mut row_result: Vec<_> = matrix.row_neighbors.collect();
|
||||
let mut column_result: Vec<_> = matrix.column_neighbors.collect();
|
||||
row_result.sort();
|
||||
column_result.sort();
|
||||
|
||||
assert_eq!(row_result, expected_row);
|
||||
assert_eq!(column_result, expected_column);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user