mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-20 02:21:03 +00:00
Network bridge refactoring impl (#1537)
* update networking types * port over overseer-protocol message types * Add the collation protocol to network bridge * message sending * stub for ConnectToValidators * add some helper traits and methods to protocol types * add collator protocol message * leaves-updating * peer connection and disconnection * add utilities for dispatching multiple events * implement message handling * add an observedrole enum with equality and no sentry nodes * derive partial-eq on network bridge event * add PartialEq impls for network message types * add Into implementation for observedrole * port over existing network bridge tests * add some more tests * port bitfield distribution * port over bitfield distribution tests * add codec indices * port PoV distribution * port over PoV distribution tests * port over statement distribution * port over statement distribution tests * update overseer and service-new * address review comments * port availability distribution * port over availability distribution tests
This commit is contained in:
committed by
GitHub
parent
8e60a5197f
commit
a6b1d91d6e
@@ -24,21 +24,20 @@ use polkadot_subsystem::{
|
||||
ActiveLeavesUpdate, OverseerSignal, SubsystemContext, Subsystem, SubsystemResult, FromOverseer, SpawnedSubsystem,
|
||||
};
|
||||
use polkadot_subsystem::messages::{
|
||||
PoVDistributionMessage, NetworkBridgeEvent, ReputationChange as Rep, PeerId,
|
||||
RuntimeApiMessage, RuntimeApiRequest, AllMessages, NetworkBridgeMessage,
|
||||
PoVDistributionMessage, RuntimeApiMessage, RuntimeApiRequest, AllMessages, NetworkBridgeMessage,
|
||||
};
|
||||
use polkadot_node_network_protocol::{
|
||||
v1 as protocol_v1, ReputationChange as Rep, NetworkBridgeEvent, PeerId, View,
|
||||
};
|
||||
use node_primitives::{View, ProtocolId};
|
||||
|
||||
use futures::prelude::*;
|
||||
use futures::channel::oneshot;
|
||||
use parity_scale_codec::{Encode, Decode};
|
||||
|
||||
use std::collections::{hash_map::{Entry, HashMap}, HashSet};
|
||||
use std::sync::Arc;
|
||||
|
||||
const COST_APPARENT_FLOOD: Rep = Rep::new(-500, "Peer appears to be flooding us with PoV requests");
|
||||
const COST_UNEXPECTED_POV: Rep = Rep::new(-500, "Peer sent us an unexpected PoV");
|
||||
const COST_MALFORMED_MESSAGE: Rep = Rep::new(-500, "Peer sent us a malformed message");
|
||||
const COST_AWAITED_NOT_IN_VIEW: Rep
|
||||
= Rep::new(-100, "Peer claims to be awaiting something outside of its view");
|
||||
|
||||
@@ -46,20 +45,6 @@ const BENEFIT_FRESH_POV: Rep = Rep::new(25, "Peer supplied us with an awaited Po
|
||||
const BENEFIT_LATE_POV: Rep = Rep::new(10, "Peer supplied us with an awaited PoV, \
|
||||
but was not the first to do so");
|
||||
|
||||
const PROTOCOL_V1: ProtocolId = *b"pvd1";
|
||||
|
||||
#[derive(Encode, Decode)]
|
||||
enum WireMessage {
|
||||
/// Notification that we are awaiting the given PoVs (by hash) against a
|
||||
/// specific relay-parent hash.
|
||||
#[codec(index = "0")]
|
||||
Awaiting(Hash, Vec<Hash>),
|
||||
/// Notification of an awaited PoV, in a given relay-parent context.
|
||||
/// (relay_parent, pov_hash, pov)
|
||||
#[codec(index = "1")]
|
||||
SendPoV(Hash, Hash, PoV),
|
||||
}
|
||||
|
||||
/// The PoV Distribution Subsystem.
|
||||
pub struct PoVDistribution;
|
||||
|
||||
@@ -98,6 +83,22 @@ struct PeerState {
|
||||
awaited: HashMap<Hash, HashSet<Hash>>,
|
||||
}
|
||||
|
||||
fn awaiting_message(relay_parent: Hash, awaiting: Vec<Hash>)
|
||||
-> protocol_v1::ValidationProtocol
|
||||
{
|
||||
protocol_v1::ValidationProtocol::PoVDistribution(
|
||||
protocol_v1::PoVDistributionMessage::Awaiting(relay_parent, awaiting)
|
||||
)
|
||||
}
|
||||
|
||||
fn send_pov_message(relay_parent: Hash, pov_hash: Hash, pov: PoV)
|
||||
-> protocol_v1::ValidationProtocol
|
||||
{
|
||||
protocol_v1::ValidationProtocol::PoVDistribution(
|
||||
protocol_v1::PoVDistributionMessage::SendPoV(relay_parent, pov_hash, pov)
|
||||
)
|
||||
}
|
||||
|
||||
/// Handles the signal. If successful, returns `true` if the subsystem should conclude,
|
||||
/// `false` otherwise.
|
||||
async fn handle_signal(
|
||||
@@ -169,11 +170,10 @@ async fn notify_all_we_are_awaiting(
|
||||
|
||||
if peers_to_send.is_empty() { return Ok(()) }
|
||||
|
||||
let payload = WireMessage::Awaiting(relay_parent, vec![pov_hash]).encode();
|
||||
let payload = awaiting_message(relay_parent, vec![pov_hash]);
|
||||
|
||||
ctx.send_message(AllMessages::NetworkBridge(NetworkBridgeMessage::SendMessage(
|
||||
ctx.send_message(AllMessages::NetworkBridge(NetworkBridgeMessage::SendValidationMessage(
|
||||
peers_to_send,
|
||||
PROTOCOL_V1,
|
||||
payload,
|
||||
))).await
|
||||
}
|
||||
@@ -194,11 +194,10 @@ async fn notify_one_we_are_awaiting_many(
|
||||
|
||||
if awaiting_hashes.is_empty() { return Ok(()) }
|
||||
|
||||
let payload = WireMessage::Awaiting(relay_parent, awaiting_hashes).encode();
|
||||
let payload = awaiting_message(relay_parent, awaiting_hashes);
|
||||
|
||||
ctx.send_message(AllMessages::NetworkBridge(NetworkBridgeMessage::SendMessage(
|
||||
ctx.send_message(AllMessages::NetworkBridge(NetworkBridgeMessage::SendValidationMessage(
|
||||
vec![peer.clone()],
|
||||
PROTOCOL_V1,
|
||||
payload,
|
||||
))).await
|
||||
}
|
||||
@@ -226,11 +225,10 @@ async fn distribute_to_awaiting(
|
||||
|
||||
if peers_to_send.is_empty() { return Ok(()) }
|
||||
|
||||
let payload = WireMessage::SendPoV(relay_parent, pov_hash, pov.clone()).encode();
|
||||
let payload = send_pov_message(relay_parent, pov_hash, pov.clone());
|
||||
|
||||
ctx.send_message(AllMessages::NetworkBridge(NetworkBridgeMessage::SendMessage(
|
||||
ctx.send_message(AllMessages::NetworkBridge(NetworkBridgeMessage::SendValidationMessage(
|
||||
peers_to_send,
|
||||
PROTOCOL_V1,
|
||||
payload,
|
||||
))).await
|
||||
}
|
||||
@@ -361,11 +359,10 @@ async fn handle_awaiting(
|
||||
// For all requested PoV hashes, if we have it, we complete the request immediately.
|
||||
// Otherwise, we note that the peer is awaiting the PoV.
|
||||
if let Some(pov) = relay_parent_state.known.get(&pov_hash) {
|
||||
ctx.send_message(AllMessages::NetworkBridge(NetworkBridgeMessage::SendMessage(
|
||||
vec![peer.clone()],
|
||||
PROTOCOL_V1,
|
||||
WireMessage::SendPoV(relay_parent, pov_hash, (&**pov).clone()).encode(),
|
||||
))).await?;
|
||||
let payload = send_pov_message(relay_parent, pov_hash, (&**pov).clone());
|
||||
ctx.send_message(AllMessages::NetworkBridge(
|
||||
NetworkBridgeMessage::SendValidationMessage(vec![peer.clone()], payload)
|
||||
)).await?;
|
||||
} else {
|
||||
peer_awaiting.insert(pov_hash);
|
||||
}
|
||||
@@ -449,7 +446,7 @@ async fn handle_incoming_pov(
|
||||
async fn handle_network_update(
|
||||
state: &mut State,
|
||||
ctx: &mut impl SubsystemContext<Message = PoVDistributionMessage>,
|
||||
update: NetworkBridgeEvent,
|
||||
update: NetworkBridgeEvent<protocol_v1::PoVDistributionMessage>,
|
||||
) -> SubsystemResult<()> {
|
||||
match update {
|
||||
NetworkBridgeEvent::PeerConnected(peer, _observed_role) => {
|
||||
@@ -483,17 +480,18 @@ async fn handle_network_update(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
NetworkBridgeEvent::PeerMessage(peer, bytes) => {
|
||||
match WireMessage::decode(&mut &bytes[..]) {
|
||||
Ok(msg) => match msg {
|
||||
WireMessage::Awaiting(relay_parent, pov_hashes) => handle_awaiting(
|
||||
NetworkBridgeEvent::PeerMessage(peer, message) => {
|
||||
match message {
|
||||
protocol_v1::PoVDistributionMessage::Awaiting(relay_parent, pov_hashes)
|
||||
=> handle_awaiting(
|
||||
state,
|
||||
ctx,
|
||||
peer,
|
||||
relay_parent,
|
||||
pov_hashes,
|
||||
).await,
|
||||
WireMessage::SendPoV(relay_parent, pov_hash, pov) => handle_incoming_pov(
|
||||
protocol_v1::PoVDistributionMessage::SendPoV(relay_parent, pov_hash, pov)
|
||||
=> handle_incoming_pov(
|
||||
state,
|
||||
ctx,
|
||||
peer,
|
||||
@@ -501,11 +499,6 @@ async fn handle_network_update(
|
||||
pov_hash,
|
||||
pov,
|
||||
).await,
|
||||
},
|
||||
Err(_) => {
|
||||
report_peer(ctx, peer, COST_MALFORMED_MESSAGE).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
NetworkBridgeEvent::OurViewChange(view) => {
|
||||
@@ -515,19 +508,9 @@ async fn handle_network_update(
|
||||
}
|
||||
}
|
||||
|
||||
fn network_update_message(update: NetworkBridgeEvent) -> AllMessages {
|
||||
AllMessages::PoVDistribution(PoVDistributionMessage::NetworkBridgeUpdate(update))
|
||||
}
|
||||
|
||||
async fn run(
|
||||
mut ctx: impl SubsystemContext<Message = PoVDistributionMessage>,
|
||||
) -> SubsystemResult<()> {
|
||||
// startup: register the network protocol with the bridge.
|
||||
ctx.send_message(AllMessages::NetworkBridge(NetworkBridgeMessage::RegisterEventProducer(
|
||||
PROTOCOL_V1,
|
||||
network_update_message,
|
||||
))).await?;
|
||||
|
||||
let mut state = State {
|
||||
relay_parent_state: HashMap::new(),
|
||||
peer_state: HashMap::new(),
|
||||
@@ -556,7 +539,7 @@ async fn run(
|
||||
descriptor,
|
||||
pov,
|
||||
).await?,
|
||||
PoVDistributionMessage::NetworkBridgeUpdate(event) =>
|
||||
PoVDistributionMessage::NetworkBridgeUpdateV1(event) =>
|
||||
handle_network_update(
|
||||
&mut state,
|
||||
&mut ctx,
|
||||
@@ -661,13 +644,12 @@ mod tests {
|
||||
assert_matches!(
|
||||
handle.recv().await,
|
||||
AllMessages::NetworkBridge(
|
||||
NetworkBridgeMessage::SendMessage(peers, protocol, message)
|
||||
NetworkBridgeMessage::SendValidationMessage(peers, message)
|
||||
) => {
|
||||
assert_eq!(peers, vec![peer_a.clone()]);
|
||||
assert_eq!(protocol, PROTOCOL_V1);
|
||||
assert_eq!(
|
||||
message,
|
||||
WireMessage::SendPoV(hash_a, pov_hash, pov.clone()).encode(),
|
||||
send_pov_message(hash_a, pov_hash, pov.clone()),
|
||||
);
|
||||
}
|
||||
)
|
||||
@@ -737,13 +719,12 @@ mod tests {
|
||||
assert_matches!(
|
||||
handle.recv().await,
|
||||
AllMessages::NetworkBridge(
|
||||
NetworkBridgeMessage::SendMessage(peers, protocol, message)
|
||||
NetworkBridgeMessage::SendValidationMessage(peers, message)
|
||||
) => {
|
||||
assert_eq!(peers, vec![peer_a.clone()]);
|
||||
assert_eq!(protocol, PROTOCOL_V1);
|
||||
assert_eq!(
|
||||
message,
|
||||
WireMessage::Awaiting(hash_a, vec![pov_hash]).encode(),
|
||||
awaiting_message(hash_a, vec![pov_hash]),
|
||||
);
|
||||
}
|
||||
)
|
||||
@@ -809,13 +790,12 @@ mod tests {
|
||||
assert_matches!(
|
||||
handle.recv().await,
|
||||
AllMessages::NetworkBridge(
|
||||
NetworkBridgeMessage::SendMessage(peers, protocol, message)
|
||||
NetworkBridgeMessage::SendValidationMessage(peers, message)
|
||||
) => {
|
||||
assert_eq!(peers, vec![peer_a.clone()]);
|
||||
assert_eq!(protocol, PROTOCOL_V1);
|
||||
assert_eq!(
|
||||
message,
|
||||
WireMessage::Awaiting(hash_a, vec![pov_a_hash]).encode(),
|
||||
awaiting_message(hash_a, vec![pov_a_hash]),
|
||||
);
|
||||
}
|
||||
)
|
||||
@@ -878,8 +858,8 @@ mod tests {
|
||||
&mut ctx,
|
||||
NetworkBridgeEvent::PeerMessage(
|
||||
peer_a.clone(),
|
||||
WireMessage::SendPoV(hash_a, pov_hash, pov.clone()).encode(),
|
||||
),
|
||||
send_pov_message(hash_a, pov_hash, pov.clone()),
|
||||
).focus().unwrap(),
|
||||
).await.unwrap();
|
||||
|
||||
handle_network_update(
|
||||
@@ -887,8 +867,8 @@ mod tests {
|
||||
&mut ctx,
|
||||
NetworkBridgeEvent::PeerMessage(
|
||||
peer_b.clone(),
|
||||
WireMessage::SendPoV(hash_a, pov_hash, pov.clone()).encode(),
|
||||
),
|
||||
send_pov_message(hash_a, pov_hash, pov.clone()),
|
||||
).focus().unwrap(),
|
||||
).await.unwrap();
|
||||
|
||||
assert_eq!(&*pov_recv.await.unwrap(), &pov);
|
||||
@@ -966,8 +946,8 @@ mod tests {
|
||||
&mut ctx,
|
||||
NetworkBridgeEvent::PeerMessage(
|
||||
peer_a.clone(),
|
||||
WireMessage::SendPoV(hash_a, pov_hash, bad_pov.clone()).encode(),
|
||||
),
|
||||
send_pov_message(hash_a, pov_hash, bad_pov.clone()),
|
||||
).focus().unwrap(),
|
||||
).await.unwrap();
|
||||
|
||||
// didn't complete our sender.
|
||||
@@ -1029,8 +1009,8 @@ mod tests {
|
||||
&mut ctx,
|
||||
NetworkBridgeEvent::PeerMessage(
|
||||
peer_a.clone(),
|
||||
WireMessage::SendPoV(hash_a, pov_hash, pov.clone()).encode(),
|
||||
),
|
||||
send_pov_message(hash_a, pov_hash, pov.clone()),
|
||||
).focus().unwrap(),
|
||||
).await.unwrap();
|
||||
|
||||
assert_matches!(
|
||||
@@ -1090,8 +1070,8 @@ mod tests {
|
||||
&mut ctx,
|
||||
NetworkBridgeEvent::PeerMessage(
|
||||
peer_a.clone(),
|
||||
WireMessage::SendPoV(hash_b, pov_hash, pov.clone()).encode(),
|
||||
),
|
||||
send_pov_message(hash_b, pov_hash, pov.clone()),
|
||||
).focus().unwrap(),
|
||||
).await.unwrap();
|
||||
|
||||
assert_matches!(
|
||||
@@ -1152,8 +1132,8 @@ mod tests {
|
||||
&mut ctx,
|
||||
NetworkBridgeEvent::PeerMessage(
|
||||
peer_a.clone(),
|
||||
WireMessage::Awaiting(hash_a, vec![pov_hash]).encode(),
|
||||
),
|
||||
awaiting_message(hash_a, vec![pov_hash]),
|
||||
).focus().unwrap(),
|
||||
).await.unwrap();
|
||||
}
|
||||
|
||||
@@ -1166,8 +1146,8 @@ mod tests {
|
||||
&mut ctx,
|
||||
NetworkBridgeEvent::PeerMessage(
|
||||
peer_a.clone(),
|
||||
WireMessage::Awaiting(hash_a, vec![last_pov_hash]).encode(),
|
||||
),
|
||||
awaiting_message(hash_a, vec![last_pov_hash]),
|
||||
).focus().unwrap(),
|
||||
).await.unwrap();
|
||||
|
||||
// No more bookkeeping for you!
|
||||
@@ -1235,8 +1215,8 @@ mod tests {
|
||||
&mut ctx,
|
||||
NetworkBridgeEvent::PeerMessage(
|
||||
peer_a.clone(),
|
||||
WireMessage::Awaiting(hash_b, vec![pov_hash]).encode(),
|
||||
),
|
||||
awaiting_message(hash_b, vec![pov_hash]),
|
||||
).focus().unwrap(),
|
||||
).await.unwrap();
|
||||
|
||||
assert!(state.peer_state[&peer_a].awaited.get(&hash_b).is_none());
|
||||
@@ -1297,8 +1277,8 @@ mod tests {
|
||||
&mut ctx,
|
||||
NetworkBridgeEvent::PeerMessage(
|
||||
peer_a.clone(),
|
||||
WireMessage::Awaiting(hash_b, vec![pov_hash]).encode(),
|
||||
),
|
||||
awaiting_message(hash_b, vec![pov_hash]),
|
||||
).focus().unwrap(),
|
||||
).await.unwrap();
|
||||
|
||||
// Illegal `awaited` is ignored.
|
||||
@@ -1371,8 +1351,8 @@ mod tests {
|
||||
&mut ctx,
|
||||
NetworkBridgeEvent::PeerMessage(
|
||||
peer_a.clone(),
|
||||
WireMessage::SendPoV(hash_a, pov_hash, pov.clone()).encode(),
|
||||
),
|
||||
send_pov_message(hash_a, pov_hash, pov.clone()),
|
||||
).focus().unwrap(),
|
||||
).await.unwrap();
|
||||
|
||||
assert_eq!(&*pov_recv.await.unwrap(), &pov);
|
||||
@@ -1390,13 +1370,12 @@ mod tests {
|
||||
assert_matches!(
|
||||
handle.recv().await,
|
||||
AllMessages::NetworkBridge(
|
||||
NetworkBridgeMessage::SendMessage(peers, protocol, message)
|
||||
NetworkBridgeMessage::SendValidationMessage(peers, message)
|
||||
) => {
|
||||
assert_eq!(peers, vec![peer_b.clone()]);
|
||||
assert_eq!(protocol, PROTOCOL_V1);
|
||||
assert_eq!(
|
||||
message,
|
||||
WireMessage::SendPoV(hash_a, pov_hash, pov.clone()).encode(),
|
||||
send_pov_message(hash_a, pov_hash, pov.clone()),
|
||||
);
|
||||
}
|
||||
);
|
||||
@@ -1454,8 +1433,8 @@ mod tests {
|
||||
&mut ctx,
|
||||
NetworkBridgeEvent::PeerMessage(
|
||||
peer_a.clone(),
|
||||
WireMessage::SendPoV(hash_a, pov_hash, pov.clone()).encode(),
|
||||
),
|
||||
send_pov_message(hash_a, pov_hash, pov.clone()),
|
||||
).focus().unwrap(),
|
||||
).await.unwrap();
|
||||
|
||||
assert_eq!(&*pov_recv.await.unwrap(), &pov);
|
||||
|
||||
Reference in New Issue
Block a user