refactor overseer into proc-macro based pattern (#2962)

This commit is contained in:
Bernhard Schuster
2021-07-08 21:09:26 +02:00
committed by GitHub
parent 2510bfc5d7
commit 3c9104daff
119 changed files with 5675 additions and 3864 deletions
@@ -24,9 +24,10 @@ use polkadot_primitives::v1::{
Id as ParaId,
};
use polkadot_subsystem::{
overseer,
FromOverseer, OverseerSignal, PerLeafSpan, SubsystemContext, jaeger,
messages::{
AllMessages, CollatorProtocolMessage, NetworkBridgeEvent, NetworkBridgeMessage,
CollatorProtocolMessage, NetworkBridgeEvent, NetworkBridgeMessage,
},
};
use polkadot_node_network_protocol::{
@@ -301,15 +302,19 @@ impl State {
/// or the relay-parent isn't in the active-leaves set, we ignore the message
/// as it must be invalid in that case - although this indicates a logic error
/// elsewhere in the node.
async fn distribute_collation(
ctx: &mut impl SubsystemContext,
async fn distribute_collation<Context>(
ctx: &mut Context,
runtime: &mut RuntimeInfo,
state: &mut State,
id: ParaId,
receipt: CandidateReceipt,
pov: PoV,
result_sender: Option<oneshot::Sender<SignedFullStatement>>,
) -> Result<()> {
) -> Result<()>
where
Context: SubsystemContext<Message = CollatorProtocolMessage>,
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
{
let relay_parent = receipt.descriptor.relay_parent;
// This collation is not in the active-leaves set.
@@ -400,11 +405,15 @@ async fn distribute_collation(
/// Get the Id of the Core that is assigned to the para being collated on if any
/// and the total number of cores.
async fn determine_core(
ctx: &mut impl SubsystemContext,
async fn determine_core<Context>(
ctx: &mut Context,
para_id: ParaId,
relay_parent: Hash,
) -> Result<Option<(CoreIndex, usize)>> {
) -> Result<Option<(CoreIndex, usize)>>
where
Context: SubsystemContext<Message = CollatorProtocolMessage>,
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
{
let cores = get_availability_cores(ctx, relay_parent).await?;
for (idx, core) in cores.iter().enumerate() {
@@ -430,13 +439,17 @@ struct GroupValidators {
/// Figure out current and next group of validators assigned to the para being collated on.
///
/// Returns [`ValidatorId`]'s of current and next group as determined based on the `relay_parent`.
async fn determine_our_validators(
ctx: &mut impl SubsystemContext,
async fn determine_our_validators<Context>(
ctx: &mut Context,
runtime: &mut RuntimeInfo,
core_index: CoreIndex,
cores: usize,
relay_parent: Hash,
) -> Result<(GroupValidators, GroupValidators)> {
) -> Result<(GroupValidators, GroupValidators)>
where
Context: SubsystemContext<Message = CollatorProtocolMessage>,
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
{
let session_index = runtime.get_session_index(ctx, relay_parent).await?;
let info = &runtime.get_session_info_by_index(ctx, relay_parent, session_index)
.await?
@@ -469,11 +482,15 @@ async fn determine_our_validators(
}
/// Issue a `Declare` collation message to the given `peer`.
async fn declare(
ctx: &mut impl SubsystemContext<Message = CollatorProtocolMessage>,
async fn declare<Context>(
ctx: &mut Context,
state: &mut State,
peer: PeerId,
) {
)
where
Context: SubsystemContext<Message = CollatorProtocolMessage>,
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
{
let declare_signature_payload = protocol_v1::declare_signature_payload(&state.local_peer_id);
if let Some(para_id) = state.collating_on {
@@ -483,39 +500,47 @@ async fn declare(
state.collator_pair.sign(&declare_signature_payload),
);
ctx.send_message(AllMessages::NetworkBridge(
ctx.send_message(
NetworkBridgeMessage::SendCollationMessage(
vec![peer],
protocol_v1::CollationProtocol::CollatorProtocol(wire_message),
)
)).await;
).await;
}
}
/// Issue a connection request to a set of validators and
/// revoke the previous connection request.
async fn connect_to_validators(
ctx: &mut impl SubsystemContext,
async fn connect_to_validators<Context>(
ctx: &mut Context,
validator_ids: Vec<AuthorityDiscoveryId>,
) {
)
where
Context: SubsystemContext<Message = CollatorProtocolMessage>,
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
{
// ignore address resolution failure
// will reissue a new request on new collation
let (failed, _) = oneshot::channel();
ctx.send_message(AllMessages::NetworkBridge(NetworkBridgeMessage::ConnectToValidators {
ctx.send_message(NetworkBridgeMessage::ConnectToValidators {
validator_ids, peer_set: PeerSet::Collation, failed,
})).await;
}).await;
}
/// Advertise collation to the given `peer`.
///
/// This will only advertise a collation if there exists one for the given `relay_parent` and the given `peer` is
/// set as validator for our para at the given `relay_parent`.
async fn advertise_collation(
ctx: &mut impl SubsystemContext,
async fn advertise_collation<Context>(
ctx: &mut Context,
state: &mut State,
relay_parent: Hash,
peer: PeerId,
) {
)
where
Context: SubsystemContext<Message = CollatorProtocolMessage>,
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
{
let should_advertise = state.our_validators_groups
.get(&relay_parent)
.map(|g| g.should_advertise_to(&state.peer_ids, &peer))
@@ -555,12 +580,12 @@ async fn advertise_collation(
relay_parent,
);
ctx.send_message(AllMessages::NetworkBridge(
ctx.send_message(
NetworkBridgeMessage::SendCollationMessage(
vec![peer.clone()],
protocol_v1::CollationProtocol::CollatorProtocol(wire_message),
)
)).await;
).await;
if let Some(validators) = state.our_validators_groups.get_mut(&relay_parent) {
validators.advertised_to_peer(&state.peer_ids, &peer);
@@ -570,12 +595,16 @@ async fn advertise_collation(
}
/// The main incoming message dispatching switch.
async fn process_msg(
ctx: &mut impl SubsystemContext<Message = CollatorProtocolMessage>,
async fn process_msg<Context>(
ctx: &mut Context,
runtime: &mut RuntimeInfo,
state: &mut State,
msg: CollatorProtocolMessage,
) -> Result<()> {
) -> Result<()>
where
Context: SubsystemContext<Message = CollatorProtocolMessage>,
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
{
use CollatorProtocolMessage::*;
let _timer = state.metrics.time_process_msg();
@@ -718,13 +747,17 @@ async fn send_collation(
}
/// A networking messages switch.
async fn handle_incoming_peer_message(
ctx: &mut impl SubsystemContext,
async fn handle_incoming_peer_message<Context>(
ctx: &mut Context,
runtime: &mut RuntimeInfo,
state: &mut State,
origin: PeerId,
msg: protocol_v1::CollatorProtocolMessage,
) -> Result<()> {
) -> Result<()>
where
Context: SubsystemContext<Message = CollatorProtocolMessage>,
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
{
use protocol_v1::CollatorProtocolMessage::*;
match msg {
@@ -737,7 +770,7 @@ async fn handle_incoming_peer_message(
// If we are declared to, this is another collator, and we should disconnect.
ctx.send_message(
NetworkBridgeMessage::DisconnectPeer(origin, PeerSet::Collation).into()
NetworkBridgeMessage::DisconnectPeer(origin, PeerSet::Collation)
).await;
}
AdvertiseCollation(_) => {
@@ -748,12 +781,12 @@ async fn handle_incoming_peer_message(
);
ctx.send_message(
NetworkBridgeMessage::ReportPeer(origin.clone(), COST_UNEXPECTED_MESSAGE).into()
NetworkBridgeMessage::ReportPeer(origin.clone(), COST_UNEXPECTED_MESSAGE)
).await;
// If we are advertised to, this is another collator, and we should disconnect.
ctx.send_message(
NetworkBridgeMessage::DisconnectPeer(origin, PeerSet::Collation).into()
NetworkBridgeMessage::DisconnectPeer(origin, PeerSet::Collation)
).await;
}
CollationSeconded(relay_parent, statement) => {
@@ -789,12 +822,16 @@ async fn handle_incoming_peer_message(
}
/// Our view has changed.
async fn handle_peer_view_change(
ctx: &mut impl SubsystemContext<Message = CollatorProtocolMessage>,
async fn handle_peer_view_change<Context>(
ctx: &mut Context,
state: &mut State,
peer_id: PeerId,
view: View,
) {
)
where
Context: SubsystemContext<Message = CollatorProtocolMessage>,
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
{
let current = state.peer_views.entry(peer_id.clone()).or_default();
let added: Vec<Hash> = view.difference(&*current).cloned().collect();
@@ -807,12 +844,16 @@ async fn handle_peer_view_change(
}
/// Bridge messages switch.
async fn handle_network_msg(
ctx: &mut impl SubsystemContext<Message = CollatorProtocolMessage>,
async fn handle_network_msg<Context>(
ctx: &mut Context,
runtime: &mut RuntimeInfo,
state: &mut State,
bridge_message: NetworkBridgeEvent<protocol_v1::CollatorProtocolMessage>,
) -> Result<()> {
) -> Result<()>
where
Context: SubsystemContext<Message = CollatorProtocolMessage>,
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
{
use NetworkBridgeEvent::*;
match bridge_message {
@@ -917,13 +958,16 @@ async fn handle_our_view_change(
}
/// The collator protocol collator side main loop.
pub(crate) async fn run(
mut ctx: impl SubsystemContext<Message = CollatorProtocolMessage>,
pub(crate) async fn run<Context>(
mut ctx: Context,
local_peer_id: PeerId,
collator_pair: CollatorPair,
metrics: Metrics,
) -> Result<()> {
use FromOverseer::*;
) -> Result<()>
where
Context: SubsystemContext<Message = CollatorProtocolMessage>,
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>
{
use OverseerSignal::*;
let mut state = State::new(local_peer_id, collator_pair, metrics);
@@ -932,15 +976,15 @@ pub(crate) async fn run(
loop {
select! {
msg = ctx.recv().fuse() => match msg.map_err(Fatal::SubsystemReceive)? {
Communication { msg } => {
FromOverseer::Communication { msg } => {
log_error(
process_msg(&mut ctx, &mut runtime, &mut state, msg).await,
"Failed to process message"
)?;
},
Signal(ActiveLeaves(_update)) => {}
Signal(BlockFinalized(..)) => {}
Signal(Conclude) => return Ok(()),
FromOverseer::Signal(ActiveLeaves(_update)) => {}
FromOverseer::Signal(BlockFinalized(..)) => {}
FromOverseer::Signal(Conclude) => return Ok(()),
},
relay_parent = state.active_collation_fetches.select_next_some() => {
let next = if let Some(waiting) = state.waiting_collation_fetches.get_mut(&relay_parent) {
@@ -39,7 +39,7 @@ use polkadot_primitives::v1::{
use polkadot_node_primitives::BlockData;
use polkadot_subsystem::{
jaeger,
messages::{RuntimeApiMessage, RuntimeApiRequest},
messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest},
ActiveLeavesUpdate, ActivatedLeaf, LeafStatus,
};
use polkadot_subsystem_testhelpers as test_helpers;
@@ -18,7 +18,7 @@
//! Error handling related code and Error/Result definitions.
use polkadot_node_primitives::UncheckedSignedFullStatement;
use polkadot_subsystem::SubsystemError;
use polkadot_subsystem::errors::SubsystemError;
use thiserror::Error;
use polkadot_node_subsystem_util::{Fault, runtime, unwrap_non_fatal};
@@ -28,9 +28,16 @@ use sp_keystore::SyncCryptoStorePtr;
use polkadot_node_network_protocol::{PeerId, UnifiedReputationChange as Rep};
use polkadot_primitives::v1::CollatorPair;
use polkadot_subsystem::{
messages::{AllMessages, CollatorProtocolMessage, NetworkBridgeMessage},
SpawnedSubsystem, Subsystem, SubsystemContext, SubsystemError,
SpawnedSubsystem,
SubsystemContext,
SubsystemSender,
overseer,
messages::{
CollatorProtocolMessage, NetworkBridgeMessage,
},
errors::SubsystemError,
};
mod error;
@@ -92,7 +99,8 @@ impl CollatorProtocolSubsystem {
async fn run<Context>(self, ctx: Context) -> Result<()>
where
Context: SubsystemContext<Message = CollatorProtocolMessage>,
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
Context: SubsystemContext<Message=CollatorProtocolMessage>,
{
match self.protocol_side {
ProtocolSide::Validator { keystore, eviction_policy, metrics } => validator_side::run(
@@ -111,9 +119,11 @@ impl CollatorProtocolSubsystem {
}
}
impl<Context> Subsystem<Context> for CollatorProtocolSubsystem
impl<Context> overseer::Subsystem<Context, SubsystemError> for CollatorProtocolSubsystem
where
Context: SubsystemContext<Message = CollatorProtocolMessage> + Sync + Send,
Context: SubsystemContext<Message = CollatorProtocolMessage>,
Context: overseer::SubsystemContext<Message = CollatorProtocolMessage>,
<Context as SubsystemContext>::Sender: SubsystemSender,
{
fn start(self, ctx: Context) -> SpawnedSubsystem {
let future = self
@@ -140,7 +150,7 @@ where
"reputation change for peer",
);
ctx.send_message(AllMessages::NetworkBridge(
ctx.send_message(
NetworkBridgeMessage::ReportPeer(peer, rep),
)).await;
).await;
}
@@ -40,9 +40,10 @@ use polkadot_node_primitives::{SignedFullStatement, PoV};
use polkadot_node_subsystem_util::metrics::{self, prometheus};
use polkadot_primitives::v1::{CandidateReceipt, CollatorId, Hash, Id as ParaId};
use polkadot_subsystem::{
overseer,
jaeger,
messages::{
AllMessages, CollatorProtocolMessage, IfDisconnected,
CollatorProtocolMessage, IfDisconnected,
NetworkBridgeEvent, NetworkBridgeMessage, CandidateBackingMessage,
},
FromOverseer, OverseerSignal, PerLeafSpan, SubsystemContext, SubsystemSender,
@@ -583,19 +584,27 @@ fn collator_peer_id(
)
}
async fn disconnect_peer(ctx: &mut impl SubsystemContext, peer_id: PeerId) {
async fn disconnect_peer<Context>(ctx: &mut Context, peer_id: PeerId)
where
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
Context: SubsystemContext<Message=CollatorProtocolMessage>,
{
ctx.send_message(
NetworkBridgeMessage::DisconnectPeer(peer_id, PeerSet::Collation).into()
NetworkBridgeMessage::DisconnectPeer(peer_id, PeerSet::Collation)
).await
}
/// Another subsystem has requested to fetch collations on a particular leaf for some para.
async fn fetch_collation(
ctx: &mut impl SubsystemContext<Message = CollatorProtocolMessage>,
async fn fetch_collation<Context>(
ctx: &mut Context,
state: &mut State,
pc: PendingCollation,
id: CollatorId,
) {
)
where
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
Context: SubsystemContext<Message=CollatorProtocolMessage>,
{
let (tx, rx) = oneshot::channel();
let PendingCollation { relay_parent, para_id, peer_id, .. } = pc;
@@ -627,7 +636,8 @@ async fn note_good_collation<Context>(
id: CollatorId,
)
where
Context: SubsystemContext<Message = CollatorProtocolMessage>
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
Context: SubsystemContext<Message=CollatorProtocolMessage>,
{
if let Some(peer_id) = collator_peer_id(peer_data, &id) {
modify_reputation(ctx, peer_id, BENEFIT_NOTIFY_GOOD).await;
@@ -635,19 +645,23 @@ where
}
/// Notify a collator that its collation got seconded.
async fn notify_collation_seconded(
ctx: &mut impl SubsystemContext<Message = CollatorProtocolMessage>,
async fn notify_collation_seconded<Context>(
ctx: &mut Context,
peer_id: PeerId,
relay_parent: Hash,
statement: SignedFullStatement,
) {
)
where
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
Context: SubsystemContext<Message=CollatorProtocolMessage>,
{
let wire_message = protocol_v1::CollatorProtocolMessage::CollationSeconded(relay_parent, statement.into());
ctx.send_message(AllMessages::NetworkBridge(
ctx.send_message(
NetworkBridgeMessage::SendCollationMessage(
vec![peer_id],
protocol_v1::CollationProtocol::CollatorProtocol(wire_message),
)
)).await;
).await;
modify_reputation(ctx, peer_id, BENEFIT_NOTIFY_GOOD).await;
}
@@ -684,7 +698,8 @@ async fn request_collation<Context>(
result: oneshot::Sender<(CandidateReceipt, PoV)>,
)
where
Context: SubsystemContext<Message = CollatorProtocolMessage>
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
Context: SubsystemContext<Message=CollatorProtocolMessage>,
{
if !state.view.contains(&relay_parent) {
tracing::debug!(
@@ -737,8 +752,8 @@ where
"Requesting collation",
);
ctx.send_message(AllMessages::NetworkBridge(
NetworkBridgeMessage::SendRequests(vec![requests], IfDisconnected::ImmediateError))
ctx.send_message(
NetworkBridgeMessage::SendRequests(vec![requests], IfDisconnected::ImmediateError)
).await;
}
@@ -750,7 +765,8 @@ async fn process_incoming_peer_message<Context>(
msg: protocol_v1::CollatorProtocolMessage,
)
where
Context: SubsystemContext<Message = CollatorProtocolMessage>
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
Context: SubsystemContext<Message=CollatorProtocolMessage>,
{
use protocol_v1::CollatorProtocolMessage::*;
use sp_runtime::traits::AppVerify;
@@ -897,12 +913,16 @@ async fn remove_relay_parent(
}
/// Our view has changed.
async fn handle_our_view_change(
ctx: &mut impl SubsystemContext,
async fn handle_our_view_change<Context>(
ctx: &mut Context,
state: &mut State,
keystore: &SyncCryptoStorePtr,
view: OurView,
) -> Result<()> {
) -> Result<()>
where
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
Context: SubsystemContext<Message=CollatorProtocolMessage>,
{
let old_view = std::mem::replace(&mut state.view, view);
let added: HashMap<Hash, Arc<jaeger::Span>> = state.view
@@ -955,7 +975,8 @@ async fn handle_network_msg<Context>(
bridge_message: NetworkBridgeEvent<protocol_v1::CollatorProtocolMessage>,
) -> Result<()>
where
Context: SubsystemContext<Message = CollatorProtocolMessage>
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
Context: SubsystemContext<Message=CollatorProtocolMessage>,
{
use NetworkBridgeEvent::*;
@@ -993,7 +1014,8 @@ async fn process_msg<Context>(
state: &mut State,
)
where
Context: SubsystemContext<Message = CollatorProtocolMessage>
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
Context: SubsystemContext<Message=CollatorProtocolMessage>,
{
use CollatorProtocolMessage::*;
@@ -1101,9 +1123,10 @@ pub(crate) async fn run<Context>(
eviction_policy: crate::CollatorEvictionPolicy,
metrics: Metrics,
) -> Result<()>
where Context: SubsystemContext<Message = CollatorProtocolMessage>
where
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
Context: SubsystemContext<Message=CollatorProtocolMessage>,
{
use FromOverseer::*;
use OverseerSignal::*;
let mut state = State {
@@ -1122,7 +1145,7 @@ pub(crate) async fn run<Context>(
select! {
res = ctx.recv().fuse() => {
match res {
Ok(Communication { msg }) => {
Ok(FromOverseer::Communication { msg }) => {
tracing::trace!(target: LOG_TARGET, msg = ?msg, "received a message");
process_msg(
&mut ctx,
@@ -1131,7 +1154,7 @@ pub(crate) async fn run<Context>(
&mut state,
).await;
}
Ok(Signal(Conclude)) => break,
Ok(FromOverseer::Signal(Conclude)) => break,
_ => {},
}
}
@@ -1159,11 +1182,15 @@ pub(crate) async fn run<Context>(
}
/// Handle a fetched collation result.
async fn handle_collation_fetched_result(
ctx: &mut impl SubsystemContext<Message = CollatorProtocolMessage>,
async fn handle_collation_fetched_result<Context>(
ctx: &mut Context,
state: &mut State,
(mut collation_event, res): PendingCollationFetch,
) {
)
where
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
Context: SubsystemContext<Message=CollatorProtocolMessage>,
{
// If no prior collation for this relay parent has been seconded, then
// memoize the collation_event for that relay_parent, such that we may
// notify the collator of their successful second backing
@@ -1204,7 +1231,7 @@ async fn handle_collation_fetched_result(
relay_parent.clone(),
candidate_receipt,
pov,
).into()
)
).await;
entry.insert(collation_event);
@@ -1221,11 +1248,15 @@ async fn handle_collation_fetched_result(
// This issues `NetworkBridge` notifications to disconnect from all inactive peers at the
// earliest possible point. This does not yet clean up any metadata, as that will be done upon
// receipt of the `PeerDisconnected` event.
async fn disconnect_inactive_peers(
ctx: &mut impl SubsystemContext,
async fn disconnect_inactive_peers<Context>(
ctx: &mut Context,
eviction_policy: &crate::CollatorEvictionPolicy,
peers: &HashMap<PeerId, PeerData>,
) {
)
where
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
Context: SubsystemContext<Message=CollatorProtocolMessage>,
{
for (peer, peer_data) in peers {
if peer_data.is_inactive(&eviction_policy) {
disconnect_peer(ctx, peer.clone()).await;
@@ -1248,7 +1279,8 @@ async fn poll_collation_response<Context>(
)
-> bool
where
Context: SubsystemContext
Context: overseer::SubsystemContext<Message=CollatorProtocolMessage>,
Context: SubsystemContext,
{
if never!(per_req.from_collator.is_terminated()) {
tracing::error!(
@@ -31,7 +31,7 @@ use polkadot_primitives::v1::{
use polkadot_node_primitives::BlockData;
use polkadot_node_subsystem_util::TimeoutExt;
use polkadot_subsystem_testhelpers as test_helpers;
use polkadot_subsystem::messages::{RuntimeApiMessage, RuntimeApiRequest};
use polkadot_subsystem::messages::{AllMessages, RuntimeApiMessage, RuntimeApiRequest};
use polkadot_node_network_protocol::{
our_view, ObservedRole, request_response::{Requests, ResponseSender},
};