mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 16:57:58 +00:00
Implement grid topology routing for the statement distribution subsystem (#5476)
* Move NewGossipTopology -> SessionGridTopology outside as this implementation is shared * Add method to return peers difference between topologies * Implement basic grid topology usage for the bitfield distribution * Fix tests * Oops, fix tests * Add some tests for random routing * Add a unit test for topology distribution * Store the current and the previous topology to match sessions boundaries * Update tests * Update node/network/bitfield-distribution/src/lib.rs Co-authored-by: Andronik <write@reusable.software> * Update node/network/protocol/src/grid_topology.rs Co-authored-by: Andronik <write@reusable.software> * Update node/network/bitfield-distribution/src/lib.rs Co-authored-by: Andronik <write@reusable.software> * Add some debug * Fix tests as HashSet order is undefined * Move session bounded topology to the common code part * Fix tests * Allow to select routing by peer index * Implement grid topology in the statement distribution subsystem * Fix tests compilation * Fix test * Refactor API slightly * Address review comments * Reduce runtime error logging severity * Update node/network/protocol/src/grid_topology.rs Co-authored-by: Bernhard Schuster <bernhard@ahoi.io> * Update node/network/bitfield-distribution/src/tests.rs Co-authored-by: Bernhard Schuster <bernhard@ahoi.io> * Fmt run * Use named struct * Fix logging stuff * One more accidental fmt damage * Increase active queue size and add metrics Signed-off-by: Andrei Sandu <andrei-mihail@parity.io> * Revert "Increase active queue size and add metrics" This reverts commit c4f48e8bded6dfeb9c62814ba2f8d815c34b04cf. * Use validator index to choose the routing strategy Noted by: @rphmeier * Fix test after distribution logic fix Co-authored-by: Andronik <write@reusable.software> Co-authored-by: Bernhard Schuster <bernhard@ahoi.io> Co-authored-by: Andrei Sandu <andrei-mihail@parity.io>
This commit is contained in:
@@ -37,6 +37,8 @@ use std::{
|
||||
fmt::Debug,
|
||||
};
|
||||
|
||||
const LOG_TARGET: &str = "parachain::grid-topology";
|
||||
|
||||
/// The sample rate for randomly propagating messages. This
|
||||
/// reduces the left tail of the binomial distribution but also
|
||||
/// introduces a bias towards peers who we sample before others
|
||||
@@ -60,9 +62,13 @@ pub struct SessionGridTopology {
|
||||
}
|
||||
|
||||
impl SessionGridTopology {
|
||||
/// Given the originator of a message, indicates the part of the topology
|
||||
/// Given the originator of a message as a validator index, indicates the part of the topology
|
||||
/// we're meant to send the message to.
|
||||
pub fn required_routing_for(&self, originator: ValidatorIndex, local: bool) -> RequiredRouting {
|
||||
pub fn required_routing_by_index(
|
||||
&self,
|
||||
originator: ValidatorIndex,
|
||||
local: bool,
|
||||
) -> RequiredRouting {
|
||||
if local {
|
||||
return RequiredRouting::GridXY
|
||||
}
|
||||
@@ -78,6 +84,31 @@ impl SessionGridTopology {
|
||||
}
|
||||
}
|
||||
|
||||
/// Given the originator of a message as a peer index, indicates the part of the topology
|
||||
/// we're meant to send the message to.
|
||||
pub fn required_routing_by_peer_id(&self, originator: PeerId, local: bool) -> RequiredRouting {
|
||||
if local {
|
||||
return RequiredRouting::GridXY
|
||||
}
|
||||
|
||||
let grid_x = self.peers_x.contains(&originator);
|
||||
let grid_y = self.peers_y.contains(&originator);
|
||||
|
||||
match (grid_x, grid_y) {
|
||||
(false, false) => RequiredRouting::None,
|
||||
(true, false) => RequiredRouting::GridY, // messages from X go to Y
|
||||
(false, true) => RequiredRouting::GridX, // messages from Y go to X
|
||||
(true, true) => {
|
||||
gum::debug!(
|
||||
target: LOG_TARGET,
|
||||
?originator,
|
||||
"Grid topology is unexpected, play it safe and send to X AND Y"
|
||||
);
|
||||
RequiredRouting::GridXY
|
||||
}, // if the grid works as expected, this shouldn't happen.
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a filter function based on this topology and the required routing
|
||||
/// which returns `true` for peers that are within the required routing set
|
||||
/// and false otherwise.
|
||||
@@ -142,6 +173,59 @@ impl SessionGridTopologies {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A simple storage for a topology and the corresponding session index
|
||||
#[derive(Default, Debug)]
|
||||
pub struct GridTopologySessionBound {
|
||||
topology: SessionGridTopology,
|
||||
session_index: SessionIndex,
|
||||
}
|
||||
|
||||
/// A storage for the current and maybe previous topology
|
||||
#[derive(Default, Debug)]
|
||||
pub struct SessionBoundGridTopologyStorage {
|
||||
current_topology: GridTopologySessionBound,
|
||||
prev_topology: Option<GridTopologySessionBound>,
|
||||
}
|
||||
|
||||
impl SessionBoundGridTopologyStorage {
|
||||
/// Return a grid topology based on the session index:
|
||||
/// If we need a previous session and it is registered in the storage, then return that session.
|
||||
/// Otherwise, return a current session to have some grid topology in any case
|
||||
pub fn get_topology_or_fallback(&self, idx: SessionIndex) -> &SessionGridTopology {
|
||||
self.get_topology(idx).unwrap_or(&self.current_topology.topology)
|
||||
}
|
||||
|
||||
/// Return the grid topology for the specific session index, if no such a session is stored
|
||||
/// returns `None`.
|
||||
pub fn get_topology(&self, idx: SessionIndex) -> Option<&SessionGridTopology> {
|
||||
if let Some(prev_topology) = &self.prev_topology {
|
||||
if idx == prev_topology.session_index {
|
||||
return Some(&prev_topology.topology)
|
||||
}
|
||||
}
|
||||
if self.current_topology.session_index == idx {
|
||||
return Some(&self.current_topology.topology)
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Update the current topology preserving the previous one
|
||||
pub fn update_topology(&mut self, session_index: SessionIndex, topology: SessionGridTopology) {
|
||||
let old_current = std::mem::replace(
|
||||
&mut self.current_topology,
|
||||
GridTopologySessionBound { topology, session_index },
|
||||
);
|
||||
self.prev_topology.replace(old_current);
|
||||
}
|
||||
|
||||
/// Returns a current grid topology
|
||||
pub fn get_current_topology(&self) -> &SessionGridTopology {
|
||||
&self.current_topology.topology
|
||||
}
|
||||
}
|
||||
|
||||
/// A representation of routing based on sample
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct RandomRouting {
|
||||
|
||||
Reference in New Issue
Block a user