Approve multiple candidates with a single signature (#1191)

Initial implementation for the plan discussed here: https://github.com/paritytech/polkadot-sdk/issues/701
Built on top of https://github.com/paritytech/polkadot-sdk/pull/1178
v0: https://github.com/paritytech/polkadot/pull/7554,

## Overall idea

When approval-voting checks a candidate and is ready to advertise the
approval, defer it in a per-relay chain block until we either have
MAX_APPROVAL_COALESCE_COUNT candidates to sign or a candidate has stayed
MAX_APPROVALS_COALESCE_TICKS in the queue, in both cases we sign what
candidates we have available.

This should allow us to reduce the number of approvals messages we have
to create/send/verify. The parameters are configurable, so we should
find some values that balance:

- Security of the network: Delaying broadcasting of an approval
shouldn't but the finality at risk and to make sure that never happens
we won't delay sending a vote if we are past 2/3 from the no-show time.
- Scalability of the network: MAX_APPROVAL_COALESCE_COUNT = 1 &
MAX_APPROVALS_COALESCE_TICKS =0, is what we have now and we know from
the measurements we did on versi, it bottlenecks
approval-distribution/approval-voting when increase significantly the
number of validators and parachains
- Block storage: In case of disputes we have to import this votes on
chain and that increase the necessary storage with
MAX_APPROVAL_COALESCE_COUNT * CandidateHash per vote. Given that
disputes are not the normal way of the network functioning and we will
limit MAX_APPROVAL_COALESCE_COUNT in the single digits numbers, this
should be good enough. Alternatively, we could try to create a better
way to store this on-chain through indirection, if that's needed.

## Other fixes:
- Fixed the fact that we were sending random assignments to
non-validators, that was wrong because those won't do anything with it
and they won't gossip it either because they do not have a grid topology
set, so we would waste the random assignments.
- Added metrics to be able to debug potential no-shows and
mis-processing of approvals/assignments.

## TODO:
- [x] Get feedback, that this is moving in the right direction. @ordian
@sandreim @eskimor @burdges, let me know what you think.
- [x] More and more testing.
- [x]  Test in versi.
- [x] Make MAX_APPROVAL_COALESCE_COUNT &
MAX_APPROVAL_COALESCE_WAIT_MILLIS a parachain host configuration.
- [x] Make sure the backwards compatibility works correctly
- [x] Make sure this direction is compatible with other streams of work:
https://github.com/paritytech/polkadot-sdk/issues/635 &
https://github.com/paritytech/polkadot-sdk/issues/742
- [x] Final versi burn-in before merging

---------

Signed-off-by: Alexandru Gheorghe <alexandru.gheorghe@parity.io>
This commit is contained in:
Alexandru Gheorghe
2023-12-13 08:43:15 +02:00
committed by GitHub
parent d18a682bf7
commit a84dd0dba5
82 changed files with 5883 additions and 1483 deletions
File diff suppressed because it is too large Load Diff
@@ -31,6 +31,8 @@ struct MetricsInner {
time_unify_with_peer: prometheus::Histogram,
time_import_pending_now_known: prometheus::Histogram,
time_awaiting_approval_voting: prometheus::Histogram,
assignments_received_result: prometheus::CounterVec<prometheus::U64>,
approvals_received_result: prometheus::CounterVec<prometheus::U64>,
}
trait AsLabel {
@@ -78,6 +80,132 @@ impl Metrics {
.map(|metrics| metrics.time_import_pending_now_known.start_timer())
}
pub fn on_approval_already_known(&self) {
if let Some(metrics) = &self.0 {
metrics.approvals_received_result.with_label_values(&["known"]).inc()
}
}
pub fn on_approval_entry_not_found(&self) {
if let Some(metrics) = &self.0 {
metrics.approvals_received_result.with_label_values(&["noapprovalentry"]).inc()
}
}
pub fn on_approval_recent_outdated(&self) {
if let Some(metrics) = &self.0 {
metrics.approvals_received_result.with_label_values(&["outdated"]).inc()
}
}
pub fn on_approval_invalid_block(&self) {
if let Some(metrics) = &self.0 {
metrics.approvals_received_result.with_label_values(&["invalidblock"]).inc()
}
}
pub fn on_approval_unknown_assignment(&self) {
if let Some(metrics) = &self.0 {
metrics
.approvals_received_result
.with_label_values(&["unknownassignment"])
.inc()
}
}
pub fn on_approval_duplicate(&self) {
if let Some(metrics) = &self.0 {
metrics.approvals_received_result.with_label_values(&["duplicate"]).inc()
}
}
pub fn on_approval_out_of_view(&self) {
if let Some(metrics) = &self.0 {
metrics.approvals_received_result.with_label_values(&["outofview"]).inc()
}
}
pub fn on_approval_good_known(&self) {
if let Some(metrics) = &self.0 {
metrics.approvals_received_result.with_label_values(&["goodknown"]).inc()
}
}
pub fn on_approval_bad(&self) {
if let Some(metrics) = &self.0 {
metrics.approvals_received_result.with_label_values(&["bad"]).inc()
}
}
pub fn on_approval_unexpected(&self) {
if let Some(metrics) = &self.0 {
metrics.approvals_received_result.with_label_values(&["unexpected"]).inc()
}
}
pub fn on_approval_bug(&self) {
if let Some(metrics) = &self.0 {
metrics.approvals_received_result.with_label_values(&["bug"]).inc()
}
}
pub fn on_assignment_already_known(&self) {
if let Some(metrics) = &self.0 {
metrics.assignments_received_result.with_label_values(&["known"]).inc()
}
}
pub fn on_assignment_recent_outdated(&self) {
if let Some(metrics) = &self.0 {
metrics.assignments_received_result.with_label_values(&["outdated"]).inc()
}
}
pub fn on_assignment_invalid_block(&self) {
if let Some(metrics) = &self.0 {
metrics.assignments_received_result.with_label_values(&["invalidblock"]).inc()
}
}
pub fn on_assignment_duplicate(&self) {
if let Some(metrics) = &self.0 {
metrics.assignments_received_result.with_label_values(&["duplicate"]).inc()
}
}
pub fn on_assignment_out_of_view(&self) {
if let Some(metrics) = &self.0 {
metrics.assignments_received_result.with_label_values(&["outofview"]).inc()
}
}
pub fn on_assignment_good_known(&self) {
if let Some(metrics) = &self.0 {
metrics.assignments_received_result.with_label_values(&["goodknown"]).inc()
}
}
pub fn on_assignment_bad(&self) {
if let Some(metrics) = &self.0 {
metrics.assignments_received_result.with_label_values(&["bad"]).inc()
}
}
pub fn on_assignment_duplicatevoting(&self) {
if let Some(metrics) = &self.0 {
metrics
.assignments_received_result
.with_label_values(&["duplicatevoting"])
.inc()
}
}
pub fn on_assignment_far(&self) {
if let Some(metrics) = &self.0 {
metrics.assignments_received_result.with_label_values(&["far"]).inc()
}
}
pub(crate) fn time_awaiting_approval_voting(
&self,
) -> Option<prometheus::prometheus::HistogramTimer> {
@@ -167,6 +295,26 @@ impl MetricsTrait for Metrics {
).buckets(vec![0.0001, 0.0004, 0.0016, 0.0064, 0.0256, 0.1024, 0.4096, 1.6384, 3.2768, 4.9152, 6.5536,]))?,
registry,
)?,
assignments_received_result: prometheus::register(
prometheus::CounterVec::new(
prometheus::Opts::new(
"polkadot_parachain_assignments_received_result",
"Result of a processed assignement",
),
&["status"]
)?,
registry,
)?,
approvals_received_result: prometheus::register(
prometheus::CounterVec::new(
prometheus::Opts::new(
"polkadot_parachain_approvals_received_result",
"Result of a processed approval",
),
&["status"]
)?,
registry,
)?,
};
Ok(Metrics(Some(metrics)))
}
File diff suppressed because it is too large Load Diff
@@ -32,7 +32,7 @@ use polkadot_node_network_protocol::{
GridNeighbors, RandomRouting, RequiredRouting, SessionBoundGridTopologyStorage,
},
peer_set::{ProtocolVersion, ValidationVersion},
v1 as protocol_v1, v2 as protocol_v2, vstaging as protocol_vstaging, OurView, PeerId,
v1 as protocol_v1, v2 as protocol_v2, v3 as protocol_v3, OurView, PeerId,
UnifiedReputationChange as Rep, Versioned, View,
};
use polkadot_node_subsystem::{
@@ -102,8 +102,8 @@ impl BitfieldGossipMessage {
self.relay_parent,
self.signed_availability.into(),
)),
Some(ValidationVersion::VStaging) =>
Versioned::VStaging(protocol_vstaging::BitfieldDistributionMessage::Bitfield(
Some(ValidationVersion::V3) =>
Versioned::V3(protocol_v3::BitfieldDistributionMessage::Bitfield(
self.relay_parent,
self.signed_availability.into(),
)),
@@ -503,8 +503,8 @@ async fn relay_message<Context>(
let v2_interested_peers =
filter_by_peer_version(&interested_peers, ValidationVersion::V2.into());
let vstaging_interested_peers =
filter_by_peer_version(&interested_peers, ValidationVersion::VStaging.into());
let v3_interested_peers =
filter_by_peer_version(&interested_peers, ValidationVersion::V3.into());
if !v1_interested_peers.is_empty() {
ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage(
@@ -522,10 +522,10 @@ async fn relay_message<Context>(
.await
}
if !vstaging_interested_peers.is_empty() {
if !v3_interested_peers.is_empty() {
ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage(
vstaging_interested_peers,
message.into_validation_protocol(ValidationVersion::VStaging.into()),
v3_interested_peers,
message.into_validation_protocol(ValidationVersion::V3.into()),
))
.await
}
@@ -551,7 +551,7 @@ async fn process_incoming_peer_message<Context>(
relay_parent,
bitfield,
)) |
Versioned::VStaging(protocol_vstaging::BitfieldDistributionMessage::Bitfield(
Versioned::V3(protocol_v3::BitfieldDistributionMessage::Bitfield(
relay_parent,
bitfield,
)) => (relay_parent, bitfield),
+6 -6
View File
@@ -33,7 +33,7 @@ use sc_network::{
use polkadot_node_network_protocol::{
peer_set::{CollationVersion, PeerSet, ProtocolVersion, ValidationVersion},
request_response::{OutgoingRequest, Recipient, ReqProtocolNames, Requests},
v1 as protocol_v1, v2 as protocol_v2, vstaging as protocol_vstaging, PeerId,
v1 as protocol_v1, v2 as protocol_v2, v3 as protocol_v3, PeerId,
};
use polkadot_primitives::{AuthorityDiscoveryId, Block, Hash};
@@ -62,20 +62,20 @@ pub(crate) fn send_validation_message_v1(
);
}
// Helper function to send a validation vstaging message to a list of peers.
// Helper function to send a validation v3 message to a list of peers.
// Messages are always sent via the main protocol, even legacy protocol messages.
pub(crate) fn send_validation_message_vstaging(
pub(crate) fn send_validation_message_v3(
peers: Vec<PeerId>,
message: WireMessage<protocol_vstaging::ValidationProtocol>,
message: WireMessage<protocol_v3::ValidationProtocol>,
metrics: &Metrics,
notification_sinks: &Arc<Mutex<HashMap<(PeerSet, PeerId), Box<dyn MessageSink>>>>,
) {
gum::trace!(target: LOG_TARGET, ?peers, ?message, "Sending validation vstaging message to peers",);
gum::trace!(target: LOG_TARGET, ?peers, ?message, "Sending validation v3 message to peers",);
send_message(
peers,
PeerSet::Validation,
ValidationVersion::VStaging.into(),
ValidationVersion::V3.into(),
message,
metrics,
notification_sinks,
+48 -49
View File
@@ -37,8 +37,8 @@ use polkadot_node_network_protocol::{
CollationVersion, PeerSet, PeerSetProtocolNames, PerPeerSet, ProtocolVersion,
ValidationVersion,
},
v1 as protocol_v1, v2 as protocol_v2, vstaging as protocol_vstaging, ObservedRole, OurView,
PeerId, UnifiedReputationChange as Rep, View,
v1 as protocol_v1, v2 as protocol_v2, v3 as protocol_v3, ObservedRole, OurView, PeerId,
UnifiedReputationChange as Rep, View,
};
use polkadot_node_subsystem::{
@@ -70,7 +70,7 @@ use super::validator_discovery;
/// Defines the `Network` trait with an implementation for an `Arc<NetworkService>`.
use crate::network::{
send_collation_message_v1, send_collation_message_v2, send_validation_message_v1,
send_validation_message_v2, send_validation_message_vstaging, Network,
send_validation_message_v2, send_validation_message_v3, Network,
};
use crate::{network::get_peer_id_by_authority_id, WireMessage};
@@ -294,9 +294,9 @@ async fn handle_validation_message<AD>(
metrics,
notification_sinks,
),
ValidationVersion::VStaging => send_validation_message_vstaging(
ValidationVersion::V3 => send_validation_message_v3(
vec![peer],
WireMessage::<protocol_vstaging::ValidationProtocol>::ViewUpdate(local_view),
WireMessage::<protocol_v3::ValidationProtocol>::ViewUpdate(local_view),
metrics,
notification_sinks,
),
@@ -360,48 +360,47 @@ async fn handle_validation_message<AD>(
?peer,
);
let (events, reports) =
if expected_versions[PeerSet::Validation] == Some(ValidationVersion::V1.into()) {
handle_peer_messages::<protocol_v1::ValidationProtocol, _>(
peer,
PeerSet::Validation,
&mut shared.0.lock().validation_peers,
vec![notification.into()],
metrics,
)
} else if expected_versions[PeerSet::Validation] ==
Some(ValidationVersion::V2.into())
{
handle_peer_messages::<protocol_v2::ValidationProtocol, _>(
peer,
PeerSet::Validation,
&mut shared.0.lock().validation_peers,
vec![notification.into()],
metrics,
)
} else if expected_versions[PeerSet::Validation] ==
Some(ValidationVersion::VStaging.into())
{
handle_peer_messages::<protocol_vstaging::ValidationProtocol, _>(
peer,
PeerSet::Validation,
&mut shared.0.lock().validation_peers,
vec![notification.into()],
metrics,
)
} else {
gum::warn!(
target: LOG_TARGET,
version = ?expected_versions[PeerSet::Validation],
"Major logic bug. Peer somehow has unsupported validation protocol version."
);
let (events, reports) = if expected_versions[PeerSet::Validation] ==
Some(ValidationVersion::V1.into())
{
handle_peer_messages::<protocol_v1::ValidationProtocol, _>(
peer,
PeerSet::Validation,
&mut shared.0.lock().validation_peers,
vec![notification.into()],
metrics,
)
} else if expected_versions[PeerSet::Validation] == Some(ValidationVersion::V2.into()) {
handle_peer_messages::<protocol_v2::ValidationProtocol, _>(
peer,
PeerSet::Validation,
&mut shared.0.lock().validation_peers,
vec![notification.into()],
metrics,
)
} else if expected_versions[PeerSet::Validation] == Some(ValidationVersion::V3.into()) {
handle_peer_messages::<protocol_v3::ValidationProtocol, _>(
peer,
PeerSet::Validation,
&mut shared.0.lock().validation_peers,
vec![notification.into()],
metrics,
)
} else {
gum::warn!(
target: LOG_TARGET,
version = ?expected_versions[PeerSet::Validation],
"Major logic bug. Peer somehow has unsupported validation protocol version."
);
never!("Only versions 1 and 2 are supported; peer set connection checked above; qed");
never!(
"Only versions 1 and 2 are supported; peer set connection checked above; qed"
);
// If a peer somehow triggers this, we'll disconnect them
// eventually.
(Vec::new(), vec![UNCONNECTED_PEERSET_COST])
};
// If a peer somehow triggers this, we'll disconnect them
// eventually.
(Vec::new(), vec![UNCONNECTED_PEERSET_COST])
};
for report in reports {
network_service.report_peer(peer, report.into());
@@ -980,8 +979,8 @@ fn update_our_view<Context>(
filter_by_peer_version(&validation_peers, ValidationVersion::V2.into());
let v2_collation_peers = filter_by_peer_version(&collation_peers, CollationVersion::V2.into());
let vstaging_validation_peers =
filter_by_peer_version(&validation_peers, ValidationVersion::VStaging.into());
let v3_validation_peers =
filter_by_peer_version(&validation_peers, ValidationVersion::V3.into());
send_validation_message_v1(
v1_validation_peers,
@@ -1011,8 +1010,8 @@ fn update_our_view<Context>(
notification_sinks,
);
send_validation_message_vstaging(
vstaging_validation_peers,
send_validation_message_v3(
v3_validation_peers,
WireMessage::ViewUpdate(new_view.clone()),
metrics,
notification_sinks,
+8 -8
View File
@@ -224,7 +224,7 @@ impl TestNetworkHandle {
PeerSet::Validation => Some(ProtocolName::from("/polkadot/validation/1")),
PeerSet::Collation => Some(ProtocolName::from("/polkadot/collation/1")),
},
ValidationVersion::VStaging => match peer_set {
ValidationVersion::V3 => match peer_set {
PeerSet::Validation => Some(ProtocolName::from("/polkadot/validation/3")),
PeerSet::Collation => unreachable!(),
},
@@ -1433,8 +1433,8 @@ fn network_protocol_versioning_view_update() {
ValidationVersion::V2 =>
WireMessage::<protocol_v2::ValidationProtocol>::ViewUpdate(view.clone())
.encode(),
ValidationVersion::VStaging =>
WireMessage::<protocol_vstaging::ValidationProtocol>::ViewUpdate(view.clone())
ValidationVersion::V3 =>
WireMessage::<protocol_v3::ValidationProtocol>::ViewUpdate(view.clone())
.encode(),
};
assert_network_actions_contains(
@@ -1469,7 +1469,7 @@ fn network_protocol_versioning_subsystem_msg() {
NetworkBridgeEvent::PeerConnected(
peer,
ObservedRole::Full,
ValidationVersion::V2.into(),
ValidationVersion::V3.into(),
None,
),
&mut virtual_overseer,
@@ -1484,9 +1484,9 @@ fn network_protocol_versioning_subsystem_msg() {
}
let approval_distribution_message =
protocol_v2::ApprovalDistributionMessage::Approvals(Vec::new());
protocol_v3::ApprovalDistributionMessage::Approvals(Vec::new());
let msg = protocol_v2::ValidationProtocol::ApprovalDistribution(
let msg = protocol_v3::ValidationProtocol::ApprovalDistribution(
approval_distribution_message.clone(),
);
@@ -1502,7 +1502,7 @@ fn network_protocol_versioning_subsystem_msg() {
virtual_overseer.recv().await,
AllMessages::ApprovalDistribution(
ApprovalDistributionMessage::NetworkBridgeUpdate(
NetworkBridgeEvent::PeerMessage(p, Versioned::V2(m))
NetworkBridgeEvent::PeerMessage(p, Versioned::V3(m))
)
) => {
assert_eq!(p, peer);
@@ -1536,7 +1536,7 @@ fn network_protocol_versioning_subsystem_msg() {
virtual_overseer.recv().await,
AllMessages::StatementDistribution(
StatementDistributionMessage::NetworkBridgeUpdate(
NetworkBridgeEvent::PeerMessage(p, Versioned::V2(m))
NetworkBridgeEvent::PeerMessage(p, Versioned::V3(m))
)
) => {
assert_eq!(p, peer);
+5 -5
View File
@@ -41,7 +41,7 @@ use crate::validator_discovery;
/// Defines the `Network` trait with an implementation for an `Arc<NetworkService>`.
use crate::network::{
send_collation_message_v1, send_collation_message_v2, send_validation_message_v1,
send_validation_message_v2, send_validation_message_vstaging, Network,
send_validation_message_v2, send_validation_message_v3, Network,
};
use crate::metrics::Metrics;
@@ -205,7 +205,7 @@ where
&metrics,
notification_sinks,
),
Versioned::VStaging(msg) => send_validation_message_vstaging(
Versioned::V3(msg) => send_validation_message_v3(
peers,
WireMessage::ProtocolMessage(msg),
&metrics,
@@ -235,7 +235,7 @@ where
&metrics,
notification_sinks,
),
Versioned::VStaging(msg) => send_validation_message_vstaging(
Versioned::V3(msg) => send_validation_message_v3(
peers,
WireMessage::ProtocolMessage(msg),
&metrics,
@@ -264,7 +264,7 @@ where
&metrics,
notification_sinks,
),
Versioned::V2(msg) | Versioned::VStaging(msg) => send_collation_message_v2(
Versioned::V2(msg) | Versioned::V3(msg) => send_collation_message_v2(
peers,
WireMessage::ProtocolMessage(msg),
&metrics,
@@ -287,7 +287,7 @@ where
&metrics,
notification_sinks,
),
Versioned::V2(msg) | Versioned::VStaging(msg) => send_collation_message_v2(
Versioned::V2(msg) | Versioned::V3(msg) => send_collation_message_v2(
peers,
WireMessage::ProtocolMessage(msg),
&metrics,
@@ -882,7 +882,7 @@ async fn handle_incoming_peer_message<Context>(
match msg {
Versioned::V1(V1::Declare(..)) |
Versioned::V2(V2::Declare(..)) |
Versioned::VStaging(V2::Declare(..)) => {
Versioned::V3(V2::Declare(..)) => {
gum::trace!(
target: LOG_TARGET,
?origin,
@@ -895,7 +895,7 @@ async fn handle_incoming_peer_message<Context>(
},
Versioned::V1(V1::AdvertiseCollation(_)) |
Versioned::V2(V2::AdvertiseCollation { .. }) |
Versioned::VStaging(V2::AdvertiseCollation { .. }) => {
Versioned::V3(V2::AdvertiseCollation { .. }) => {
gum::trace!(
target: LOG_TARGET,
?origin,
@@ -911,7 +911,7 @@ async fn handle_incoming_peer_message<Context>(
},
Versioned::V1(V1::CollationSeconded(relay_parent, statement)) |
Versioned::V2(V2::CollationSeconded(relay_parent, statement)) |
Versioned::VStaging(V2::CollationSeconded(relay_parent, statement)) => {
Versioned::V3(V2::CollationSeconded(relay_parent, statement)) => {
if !matches!(statement.unchecked_payload(), Statement::Seconded(_)) {
gum::warn!(
target: LOG_TARGET,
@@ -777,7 +777,7 @@ async fn process_incoming_peer_message<Context>(
match msg {
Versioned::V1(V1::Declare(collator_id, para_id, signature)) |
Versioned::V2(V2::Declare(collator_id, para_id, signature)) |
Versioned::VStaging(V2::Declare(collator_id, para_id, signature)) => {
Versioned::V3(V2::Declare(collator_id, para_id, signature)) => {
if collator_peer_id(&state.peer_data, &collator_id).is_some() {
modify_reputation(
&mut state.reputation,
@@ -894,7 +894,7 @@ async fn process_incoming_peer_message<Context>(
candidate_hash,
parent_head_data_hash,
}) |
Versioned::VStaging(V2::AdvertiseCollation {
Versioned::V3(V2::AdvertiseCollation {
relay_parent,
candidate_hash,
parent_head_data_hash,
@@ -923,7 +923,7 @@ async fn process_incoming_peer_message<Context>(
},
Versioned::V1(V1::CollationSeconded(..)) |
Versioned::V2(V2::CollationSeconded(..)) |
Versioned::VStaging(V2::CollationSeconded(..)) => {
Versioned::V3(V2::CollationSeconded(..)) => {
gum::warn!(
target: LOG_TARGET,
peer_id = ?origin,
@@ -477,7 +477,7 @@ where
match message {
Versioned::V1(m) => match m {},
Versioned::V2(m) => match m {},
Versioned::VStaging(m) => match m {},
Versioned::V3(m) => match m {},
}
},
}
@@ -27,6 +27,3 @@ bitvec = "1"
[dev-dependencies]
rand_chacha = "0.3.1"
[features]
network-protocol-staging = []
@@ -73,12 +73,20 @@ pub struct SessionGridTopology {
shuffled_indices: Vec<usize>,
/// The canonical shuffling of validators for the session.
canonical_shuffling: Vec<TopologyPeerInfo>,
/// The list of peer-ids in an efficient way to search.
peer_ids: HashSet<PeerId>,
}
impl SessionGridTopology {
/// Create a new session grid topology.
pub fn new(shuffled_indices: Vec<usize>, canonical_shuffling: Vec<TopologyPeerInfo>) -> Self {
SessionGridTopology { shuffled_indices, canonical_shuffling }
let mut peer_ids = HashSet::new();
for peer_info in canonical_shuffling.iter() {
for peer_id in peer_info.peer_ids.iter() {
peer_ids.insert(*peer_id);
}
}
SessionGridTopology { shuffled_indices, canonical_shuffling, peer_ids }
}
/// Produces the outgoing routing logic for a particular peer.
@@ -111,6 +119,11 @@ impl SessionGridTopology {
Some(grid_subset)
}
/// Tells if a given peer id is validator in a session
pub fn is_validator(&self, peer: &PeerId) -> bool {
self.peer_ids.contains(peer)
}
}
struct MatrixNeighbors<R, C> {
@@ -273,6 +286,11 @@ impl SessionGridTopologyEntry {
pub fn get(&self) -> &SessionGridTopology {
&self.topology
}
/// Tells if a given peer id is validator in a session
pub fn is_validator(&self, peer: &PeerId) -> bool {
self.topology.is_validator(peer)
}
}
/// A set of topologies indexed by session
@@ -347,6 +365,7 @@ impl Default for SessionBoundGridTopologyStorage {
topology: SessionGridTopology {
shuffled_indices: Vec::new(),
canonical_shuffling: Vec::new(),
peer_ids: Default::default(),
},
local_neighbors: GridNeighbors::empty(),
},
+29 -32
View File
@@ -253,29 +253,29 @@ impl View {
/// A protocol-versioned type.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Versioned<V1, V2, VStaging = V2> {
pub enum Versioned<V1, V2, V3 = V2> {
/// V1 type.
V1(V1),
/// V2 type.
V2(V2),
/// VStaging type
VStaging(VStaging),
/// V3 type
V3(V3),
}
impl<V1: Clone, V2: Clone, VStaging: Clone> Versioned<&'_ V1, &'_ V2, &'_ VStaging> {
impl<V1: Clone, V2: Clone, V3: Clone> Versioned<&'_ V1, &'_ V2, &'_ V3> {
/// Convert to a fully-owned version of the message.
pub fn clone_inner(&self) -> Versioned<V1, V2, VStaging> {
pub fn clone_inner(&self) -> Versioned<V1, V2, V3> {
match *self {
Versioned::V1(inner) => Versioned::V1(inner.clone()),
Versioned::V2(inner) => Versioned::V2(inner.clone()),
Versioned::VStaging(inner) => Versioned::VStaging(inner.clone()),
Versioned::V3(inner) => Versioned::V3(inner.clone()),
}
}
}
/// All supported versions of the validation protocol message.
pub type VersionedValidationProtocol =
Versioned<v1::ValidationProtocol, v2::ValidationProtocol, vstaging::ValidationProtocol>;
Versioned<v1::ValidationProtocol, v2::ValidationProtocol, v3::ValidationProtocol>;
impl From<v1::ValidationProtocol> for VersionedValidationProtocol {
fn from(v1: v1::ValidationProtocol) -> Self {
@@ -289,9 +289,9 @@ impl From<v2::ValidationProtocol> for VersionedValidationProtocol {
}
}
impl From<vstaging::ValidationProtocol> for VersionedValidationProtocol {
fn from(vstaging: vstaging::ValidationProtocol) -> Self {
VersionedValidationProtocol::VStaging(vstaging)
impl From<v3::ValidationProtocol> for VersionedValidationProtocol {
fn from(v3: v3::ValidationProtocol) -> Self {
VersionedValidationProtocol::V3(v3)
}
}
@@ -317,7 +317,7 @@ macro_rules! impl_versioned_full_protocol_from {
match versioned_from {
Versioned::V1(x) => Versioned::V1(x.into()),
Versioned::V2(x) => Versioned::V2(x.into()),
Versioned::VStaging(x) => Versioned::VStaging(x.into()),
Versioned::V3(x) => Versioned::V3(x.into()),
}
}
}
@@ -331,7 +331,7 @@ macro_rules! impl_versioned_try_from {
$out:ty,
$v1_pat:pat => $v1_out:expr,
$v2_pat:pat => $v2_out:expr,
$vstaging_pat:pat => $vstaging_out:expr
$v3_pat:pat => $v3_out:expr
) => {
impl TryFrom<$from> for $out {
type Error = crate::WrongVariant;
@@ -341,7 +341,7 @@ macro_rules! impl_versioned_try_from {
match x {
Versioned::V1($v1_pat) => Ok(Versioned::V1($v1_out)),
Versioned::V2($v2_pat) => Ok(Versioned::V2($v2_out)),
Versioned::VStaging($vstaging_pat) => Ok(Versioned::VStaging($vstaging_out)),
Versioned::V3($v3_pat) => Ok(Versioned::V3($v3_out)),
_ => Err(crate::WrongVariant),
}
}
@@ -355,8 +355,7 @@ macro_rules! impl_versioned_try_from {
match x {
Versioned::V1($v1_pat) => Ok(Versioned::V1($v1_out.clone())),
Versioned::V2($v2_pat) => Ok(Versioned::V2($v2_out.clone())),
Versioned::VStaging($vstaging_pat) =>
Ok(Versioned::VStaging($vstaging_out.clone())),
Versioned::V3($v3_pat) => Ok(Versioned::V3($v3_out.clone())),
_ => Err(crate::WrongVariant),
}
}
@@ -368,7 +367,7 @@ macro_rules! impl_versioned_try_from {
pub type BitfieldDistributionMessage = Versioned<
v1::BitfieldDistributionMessage,
v2::BitfieldDistributionMessage,
vstaging::BitfieldDistributionMessage,
v3::BitfieldDistributionMessage,
>;
impl_versioned_full_protocol_from!(
BitfieldDistributionMessage,
@@ -380,14 +379,14 @@ impl_versioned_try_from!(
BitfieldDistributionMessage,
v1::ValidationProtocol::BitfieldDistribution(x) => x,
v2::ValidationProtocol::BitfieldDistribution(x) => x,
vstaging::ValidationProtocol::BitfieldDistribution(x) => x
v3::ValidationProtocol::BitfieldDistribution(x) => x
);
/// Version-annotated messages used by the statement distribution subsystem.
pub type StatementDistributionMessage = Versioned<
v1::StatementDistributionMessage,
v2::StatementDistributionMessage,
vstaging::StatementDistributionMessage,
v3::StatementDistributionMessage,
>;
impl_versioned_full_protocol_from!(
StatementDistributionMessage,
@@ -399,14 +398,14 @@ impl_versioned_try_from!(
StatementDistributionMessage,
v1::ValidationProtocol::StatementDistribution(x) => x,
v2::ValidationProtocol::StatementDistribution(x) => x,
vstaging::ValidationProtocol::StatementDistribution(x) => x
v3::ValidationProtocol::StatementDistribution(x) => x
);
/// Version-annotated messages used by the approval distribution subsystem.
pub type ApprovalDistributionMessage = Versioned<
v1::ApprovalDistributionMessage,
v2::ApprovalDistributionMessage,
vstaging::ApprovalDistributionMessage,
v3::ApprovalDistributionMessage,
>;
impl_versioned_full_protocol_from!(
ApprovalDistributionMessage,
@@ -418,7 +417,7 @@ impl_versioned_try_from!(
ApprovalDistributionMessage,
v1::ValidationProtocol::ApprovalDistribution(x) => x,
v2::ValidationProtocol::ApprovalDistribution(x) => x,
vstaging::ValidationProtocol::ApprovalDistribution(x) => x
v3::ValidationProtocol::ApprovalDistribution(x) => x
);
@@ -426,7 +425,7 @@ impl_versioned_try_from!(
pub type GossipSupportNetworkMessage = Versioned<
v1::GossipSupportNetworkMessage,
v2::GossipSupportNetworkMessage,
vstaging::GossipSupportNetworkMessage,
v3::GossipSupportNetworkMessage,
>;
// This is a void enum placeholder, so never gets sent over the wire.
@@ -871,19 +870,17 @@ pub mod v2 {
}
}
/// vstaging network protocol types, intended to become v3.
/// Initial purpose is for chaning ApprovalDistributionMessage to
/// include more than one assignment in the message.
pub mod vstaging {
/// v3 network protocol types.
/// Purpose is for chaning ApprovalDistributionMessage to
/// include more than one assignment and approval in a message.
pub mod v3 {
use parity_scale_codec::{Decode, Encode};
use polkadot_node_primitives::approval::{
v1::IndirectSignedApprovalVote,
v2::{CandidateBitfield, IndirectAssignmentCertV2},
use polkadot_node_primitives::approval::v2::{
CandidateBitfield, IndirectAssignmentCertV2, IndirectSignedApprovalVoteV2,
};
/// This parts of the protocol did not change from v2, so just alias them in vstaging,
/// no reason why they can't be change untill vstaging becomes v3 and is released.
/// This parts of the protocol did not change from v2, so just alias them in v3.
pub use super::v2::{
declare_signature_payload, BackedCandidateAcknowledgement, BackedCandidateManifest,
BitfieldDistributionMessage, GossipSupportNetworkMessage, StatementDistributionMessage,
@@ -903,7 +900,7 @@ pub mod vstaging {
Assignments(Vec<(IndirectAssignmentCertV2, CandidateBitfield)>),
/// Approvals for candidates in some recent, unfinalized block.
#[codec(index = 1)]
Approvals(Vec<IndirectSignedApprovalVote>),
Approvals(Vec<IndirectSignedApprovalVoteV2>),
}
/// All network messages on the validation peer-set.
+38 -17
View File
@@ -73,7 +73,11 @@ impl PeerSet {
// Networking layer relies on `get_main_name()` being the main name of the protocol
// for peersets and connection management.
let protocol = peerset_protocol_names.get_main_name(self);
let fallback_names = PeerSetProtocolNames::get_fallback_names(self);
let fallback_names = PeerSetProtocolNames::get_fallback_names(
self,
&peerset_protocol_names.genesis_hash,
peerset_protocol_names.fork_id.as_deref(),
);
let max_notification_size = self.get_max_notification_size(is_authority);
match self {
@@ -127,15 +131,8 @@ impl PeerSet {
/// Networking layer relies on `get_main_version()` being the version
/// of the main protocol name reported by [`PeerSetProtocolNames::get_main_name()`].
pub fn get_main_version(self) -> ProtocolVersion {
#[cfg(not(feature = "network-protocol-staging"))]
match self {
PeerSet::Validation => ValidationVersion::V2.into(),
PeerSet::Collation => CollationVersion::V2.into(),
}
#[cfg(feature = "network-protocol-staging")]
match self {
PeerSet::Validation => ValidationVersion::VStaging.into(),
PeerSet::Validation => ValidationVersion::V3.into(),
PeerSet::Collation => CollationVersion::V2.into(),
}
}
@@ -163,7 +160,7 @@ impl PeerSet {
Some("validation/1")
} else if version == ValidationVersion::V2.into() {
Some("validation/2")
} else if version == ValidationVersion::VStaging.into() {
} else if version == ValidationVersion::V3.into() {
Some("validation/3")
} else {
None
@@ -236,9 +233,10 @@ pub enum ValidationVersion {
V1 = 1,
/// The second version.
V2 = 2,
/// The staging version to gather changes
/// that before the release become v3.
VStaging = 3,
/// The third version where changes to ApprovalDistributionMessage had been made.
/// The changes are translatable to V2 format untill assignments v2 and approvals
/// coalescing is enabled through a runtime upgrade.
V3 = 3,
}
/// Supported collation protocol versions. Only versions defined here must be used in the codebase.
@@ -299,6 +297,8 @@ impl From<CollationVersion> for ProtocolVersion {
pub struct PeerSetProtocolNames {
protocols: HashMap<ProtocolName, (PeerSet, ProtocolVersion)>,
names: HashMap<(PeerSet, ProtocolVersion), ProtocolName>,
genesis_hash: Hash,
fork_id: Option<String>,
}
impl PeerSetProtocolNames {
@@ -333,7 +333,7 @@ impl PeerSetProtocolNames {
}
Self::register_legacy_protocol(&mut protocols, protocol);
}
Self { protocols, names }
Self { protocols, names, genesis_hash, fork_id: fork_id.map(|fork_id| fork_id.into()) }
}
/// Helper function to register main protocol.
@@ -437,9 +437,30 @@ impl PeerSetProtocolNames {
}
/// Get the protocol fallback names. Currently only holds the legacy name
/// for `LEGACY_PROTOCOL_VERSION` = 1.
fn get_fallback_names(protocol: PeerSet) -> Vec<ProtocolName> {
std::iter::once(Self::get_legacy_name(protocol)).collect()
/// for `LEGACY_PROTOCOL_VERSION` = 1 and v2 for validation.
fn get_fallback_names(
protocol: PeerSet,
genesis_hash: &Hash,
fork_id: Option<&str>,
) -> Vec<ProtocolName> {
let mut fallbacks = vec![Self::get_legacy_name(protocol)];
match protocol {
PeerSet::Validation => {
// Fallbacks are tried one by one, till one matches so push v2 at the top, so
// that it is used ahead of the legacy one(v1).
fallbacks.insert(
0,
Self::generate_name(
genesis_hash,
fork_id,
protocol,
ValidationVersion::V2.into(),
),
)
},
PeerSet::Collation => {},
};
fallbacks
}
}
@@ -22,8 +22,8 @@ use polkadot_node_network_protocol::{
grid_topology::{GridNeighbors, RequiredRouting, SessionBoundGridTopologyStorage},
peer_set::{IsAuthority, PeerSet, ValidationVersion},
v1::{self as protocol_v1, StatementMetadata},
v2 as protocol_v2, vstaging as protocol_vstaging, IfDisconnected, PeerId,
UnifiedReputationChange as Rep, Versioned, View,
v2 as protocol_v2, v3 as protocol_v3, IfDisconnected, PeerId, UnifiedReputationChange as Rep,
Versioned, View,
};
use polkadot_node_primitives::{
SignedFullStatement, Statement, StatementWithPVD, UncheckedSignedFullStatement,
@@ -1075,7 +1075,7 @@ async fn circulate_statement<'a, Context>(
})
.partition::<Vec<_>, _>(|(_, _, version)| match version {
ValidationVersion::V1 => true,
ValidationVersion::V2 | ValidationVersion::VStaging => false,
ValidationVersion::V2 | ValidationVersion::V3 => false,
}); // partition is handy here but not if we add more protocol versions
let payload = v1_statement_message(relay_parent, stored.statement.clone(), metrics);
@@ -1108,8 +1108,7 @@ async fn circulate_statement<'a, Context>(
.collect();
let v2_peers_to_send = filter_by_peer_version(&peers_to_send, ValidationVersion::V2.into());
let vstaging_to_send =
filter_by_peer_version(&peers_to_send, ValidationVersion::VStaging.into());
let v3_to_send = filter_by_peer_version(&peers_to_send, ValidationVersion::V3.into());
if !v2_peers_to_send.is_empty() {
gum::trace!(
@@ -1126,17 +1125,17 @@ async fn circulate_statement<'a, Context>(
.await;
}
if !vstaging_to_send.is_empty() {
if !v3_to_send.is_empty() {
gum::trace!(
target: LOG_TARGET,
?vstaging_to_send,
?v3_to_send,
?relay_parent,
statement = ?stored.statement,
"Sending statement to vstaging peers",
"Sending statement to v3 peers",
);
ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage(
vstaging_to_send,
compatible_v1_message(ValidationVersion::VStaging, payload.clone()).into(),
v3_to_send,
compatible_v1_message(ValidationVersion::V3, payload.clone()).into(),
))
.await;
}
@@ -1472,10 +1471,8 @@ async fn handle_incoming_message<'a, Context>(
let message = match message {
Versioned::V1(m) => m,
Versioned::V2(protocol_v2::StatementDistributionMessage::V1Compatibility(m)) |
Versioned::VStaging(protocol_vstaging::StatementDistributionMessage::V1Compatibility(
m,
)) => m,
Versioned::V2(_) | Versioned::VStaging(_) => {
Versioned::V3(protocol_v3::StatementDistributionMessage::V1Compatibility(m)) => m,
Versioned::V2(_) | Versioned::V3(_) => {
// The higher-level subsystem code is supposed to filter out
// all non v1 messages.
gum::debug!(
@@ -2201,8 +2198,7 @@ fn compatible_v1_message(
ValidationVersion::V1 => Versioned::V1(message),
ValidationVersion::V2 =>
Versioned::V2(protocol_v2::StatementDistributionMessage::V1Compatibility(message)),
ValidationVersion::VStaging => Versioned::VStaging(
protocol_vstaging::StatementDistributionMessage::V1Compatibility(message),
),
ValidationVersion::V3 =>
Versioned::V3(protocol_v3::StatementDistributionMessage::V1Compatibility(message)),
}
}
@@ -27,7 +27,7 @@ use std::time::Duration;
use polkadot_node_network_protocol::{
request_response::{v1 as request_v1, v2::AttestedCandidateRequest, IncomingRequestReceiver},
v2 as protocol_v2, vstaging as protocol_vstaging, Versioned,
v2 as protocol_v2, v3 as protocol_v3, Versioned,
};
use polkadot_node_primitives::StatementWithPVD;
use polkadot_node_subsystem::{
@@ -400,11 +400,11 @@ impl<R: rand::Rng> StatementDistributionSubsystem<R> {
Versioned::V2(
protocol_v2::StatementDistributionMessage::V1Compatibility(_),
) |
Versioned::VStaging(
protocol_vstaging::StatementDistributionMessage::V1Compatibility(_),
Versioned::V3(
protocol_v3::StatementDistributionMessage::V1Compatibility(_),
) => VersionTarget::Legacy,
Versioned::V1(_) => VersionTarget::Legacy,
Versioned::V2(_) | Versioned::VStaging(_) => VersionTarget::Current,
Versioned::V2(_) | Versioned::V3(_) => VersionTarget::Current,
},
_ => VersionTarget::Both,
};
@@ -29,8 +29,7 @@ use polkadot_node_network_protocol::{
MAX_PARALLEL_ATTESTED_CANDIDATE_REQUESTS,
},
v2::{self as protocol_v2, StatementFilter},
vstaging as protocol_vstaging, IfDisconnected, PeerId, UnifiedReputationChange as Rep,
Versioned, View,
v3 as protocol_v3, IfDisconnected, PeerId, UnifiedReputationChange as Rep, Versioned, View,
};
use polkadot_node_primitives::{
SignedFullStatementWithPVD, StatementWithPVD as FullStatementWithPVD,
@@ -366,7 +365,7 @@ pub(crate) async fn handle_network_update<Context>(
gum::trace!(target: LOG_TARGET, ?peer_id, ?role, ?protocol_version, "Peer connected");
let versioned_protocol = if protocol_version != ValidationVersion::V2.into() &&
protocol_version != ValidationVersion::VStaging.into()
protocol_version != ValidationVersion::V3.into()
{
return
} else {
@@ -432,28 +431,28 @@ pub(crate) async fn handle_network_update<Context>(
net_protocol::StatementDistributionMessage::V2(
protocol_v2::StatementDistributionMessage::V1Compatibility(_),
) |
net_protocol::StatementDistributionMessage::VStaging(
protocol_vstaging::StatementDistributionMessage::V1Compatibility(_),
net_protocol::StatementDistributionMessage::V3(
protocol_v3::StatementDistributionMessage::V1Compatibility(_),
) => return,
net_protocol::StatementDistributionMessage::V2(
protocol_v2::StatementDistributionMessage::Statement(relay_parent, statement),
) |
net_protocol::StatementDistributionMessage::VStaging(
protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, statement),
net_protocol::StatementDistributionMessage::V3(
protocol_v3::StatementDistributionMessage::Statement(relay_parent, statement),
) =>
handle_incoming_statement(ctx, state, peer_id, relay_parent, statement, reputation)
.await,
net_protocol::StatementDistributionMessage::V2(
protocol_v2::StatementDistributionMessage::BackedCandidateManifest(inner),
) |
net_protocol::StatementDistributionMessage::VStaging(
protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest(inner),
net_protocol::StatementDistributionMessage::V3(
protocol_v3::StatementDistributionMessage::BackedCandidateManifest(inner),
) => handle_incoming_manifest(ctx, state, peer_id, inner, reputation).await,
net_protocol::StatementDistributionMessage::V2(
protocol_v2::StatementDistributionMessage::BackedCandidateKnown(inner),
) |
net_protocol::StatementDistributionMessage::VStaging(
protocol_vstaging::StatementDistributionMessage::BackedCandidateKnown(inner),
net_protocol::StatementDistributionMessage::V3(
protocol_v3::StatementDistributionMessage::BackedCandidateKnown(inner),
) => handle_incoming_acknowledgement(ctx, state, peer_id, inner, reputation).await,
},
NetworkBridgeEvent::PeerViewChange(peer_id, view) =>
@@ -806,13 +805,13 @@ fn pending_statement_network_message(
protocol_v2::StatementDistributionMessage::Statement(relay_parent, signed)
})
.map(|msg| (vec![peer.0], Versioned::V2(msg).into())),
ValidationVersion::VStaging => statement_store
ValidationVersion::V3 => statement_store
.validator_statement(originator, compact)
.map(|s| s.as_unchecked().clone())
.map(|signed| {
protocol_vstaging::StatementDistributionMessage::Statement(relay_parent, signed)
protocol_v3::StatementDistributionMessage::Statement(relay_parent, signed)
})
.map(|msg| (vec![peer.0], Versioned::VStaging(msg).into())),
.map(|msg| (vec![peer.0], Versioned::V3(msg).into())),
ValidationVersion::V1 => {
gum::error!(
target: LOG_TARGET,
@@ -945,10 +944,10 @@ async fn send_pending_grid_messages<Context>(
)
.into(),
)),
ValidationVersion::VStaging => messages.push((
ValidationVersion::V3 => messages.push((
vec![peer_id.0],
Versioned::VStaging(
protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest(
Versioned::V3(
protocol_v3::StatementDistributionMessage::BackedCandidateManifest(
manifest,
),
)
@@ -960,7 +959,7 @@ async fn send_pending_grid_messages<Context>(
"Bug ValidationVersion::V1 should not be used in statement-distribution v2,
legacy should have handled this"
);
}
},
};
},
grid::ManifestKind::Acknowledgement => {
@@ -1308,8 +1307,8 @@ async fn circulate_statement<Context>(
let statement_to_v2_peers =
filter_by_peer_version(&statement_to_peers, ValidationVersion::V2.into());
let statement_to_vstaging_peers =
filter_by_peer_version(&statement_to_peers, ValidationVersion::VStaging.into());
let statement_to_v3_peers =
filter_by_peer_version(&statement_to_peers, ValidationVersion::V3.into());
// ship off the network messages to the network bridge.
if !statement_to_v2_peers.is_empty() {
@@ -1331,17 +1330,17 @@ async fn circulate_statement<Context>(
.await;
}
if !statement_to_vstaging_peers.is_empty() {
if !statement_to_v3_peers.is_empty() {
gum::debug!(
target: LOG_TARGET,
?compact_statement,
n_peers = ?statement_to_peers.len(),
"Sending statement to vstaging peers",
"Sending statement to v3 peers",
);
ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage(
statement_to_vstaging_peers,
Versioned::VStaging(protocol_vstaging::StatementDistributionMessage::Statement(
statement_to_v3_peers,
Versioned::V3(protocol_v3::StatementDistributionMessage::Statement(
relay_parent,
statement.as_unchecked().clone(),
))
@@ -1887,8 +1886,7 @@ async fn provide_candidate_to_grid<Context>(
}
let manifest_peers_v2 = filter_by_peer_version(&manifest_peers, ValidationVersion::V2.into());
let manifest_peers_vstaging =
filter_by_peer_version(&manifest_peers, ValidationVersion::VStaging.into());
let manifest_peers_v3 = filter_by_peer_version(&manifest_peers, ValidationVersion::V3.into());
if !manifest_peers_v2.is_empty() {
gum::debug!(
target: LOG_TARGET,
@@ -1908,27 +1906,27 @@ async fn provide_candidate_to_grid<Context>(
.await;
}
if !manifest_peers_vstaging.is_empty() {
if !manifest_peers_v3.is_empty() {
gum::debug!(
target: LOG_TARGET,
?candidate_hash,
local_validator = ?per_session.local_validator,
n_peers = manifest_peers_vstaging.len(),
"Sending manifest to vstaging peers"
n_peers = manifest_peers_v3.len(),
"Sending manifest to v3 peers"
);
ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage(
manifest_peers_vstaging,
Versioned::VStaging(
protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest(manifest),
)
manifest_peers_v3,
Versioned::V3(protocol_v3::StatementDistributionMessage::BackedCandidateManifest(
manifest,
))
.into(),
))
.await;
}
let ack_peers_v2 = filter_by_peer_version(&ack_peers, ValidationVersion::V2.into());
let ack_peers_vstaging = filter_by_peer_version(&ack_peers, ValidationVersion::VStaging.into());
let ack_peers_v3 = filter_by_peer_version(&ack_peers, ValidationVersion::V3.into());
if !ack_peers_v2.is_empty() {
gum::debug!(
target: LOG_TARGET,
@@ -1948,22 +1946,20 @@ async fn provide_candidate_to_grid<Context>(
.await;
}
if !ack_peers_vstaging.is_empty() {
if !ack_peers_v3.is_empty() {
gum::debug!(
target: LOG_TARGET,
?candidate_hash,
local_validator = ?per_session.local_validator,
n_peers = ack_peers_vstaging.len(),
"Sending acknowledgement to vstaging peers"
n_peers = ack_peers_v3.len(),
"Sending acknowledgement to v3 peers"
);
ctx.send_message(NetworkBridgeTxMessage::SendValidationMessage(
ack_peers_vstaging,
Versioned::VStaging(
protocol_vstaging::StatementDistributionMessage::BackedCandidateKnown(
acknowledgement,
),
)
ack_peers_v3,
Versioned::V3(protocol_v3::StatementDistributionMessage::BackedCandidateKnown(
acknowledgement,
))
.into(),
))
.await;
@@ -2293,8 +2289,8 @@ fn post_acknowledgement_statement_messages(
)
.into(),
)),
ValidationVersion::VStaging => messages.push(Versioned::VStaging(
protocol_vstaging::StatementDistributionMessage::Statement(
ValidationVersion::V3 => messages.push(Versioned::V3(
protocol_v3::StatementDistributionMessage::Statement(
relay_parent,
statement.as_unchecked().clone(),
)
@@ -2441,9 +2437,9 @@ fn acknowledgement_and_statement_messages(
let mut messages = match peer.1 {
ValidationVersion::V2 => vec![(vec![peer.0], msg_v2.into())],
ValidationVersion::VStaging => vec![(
ValidationVersion::V3 => vec![(
vec![peer.0],
Versioned::VStaging(protocol_v2::StatementDistributionMessage::BackedCandidateKnown(
Versioned::V3(protocol_v2::StatementDistributionMessage::BackedCandidateKnown(
acknowledgement,
))
.into(),
@@ -2830,7 +2830,7 @@ fn inactive_local_participates_in_grid() {
send_peer_message(
&mut overseer,
peer_a.clone(),
protocol_vstaging::StatementDistributionMessage::BackedCandidateManifest(manifest),
protocol_v3::StatementDistributionMessage::BackedCandidateManifest(manifest),
)
.await;