mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-18 23:25:40 +00:00
Remove request multiplexer (#3624)
* WIP: Get rid of request multiplexer. * WIP * Receiver for handling of incoming requests. * Get rid of useless `Fault` abstraction. The things the type system let us do are not worth getting abstracted in its own type. Instead error handling is going to be merely a pattern. * Make most things compile again. * Port availability distribution away from request multiplexer. * Formatting. * Port dispute distribution over. * Fixup statement distribution. * Handle request directly in collator protocol. + Only allow fatal errors at top level. * Use direct request channel for availability recovery. * Finally get rid of request multiplexer Fixes #2842 and paves the way for more back pressure possibilities. * Fix overseer and statement distribution tests. * Fix collator protocol and network bridge tests. * Fix tests in availability recovery. * Fix availability distribution tests. * Fix dispute distribution tests. * Add missing dependency * Typos. * Review remarks. * More remarks.
This commit is contained in:
@@ -21,19 +21,20 @@ use std::{
|
||||
};
|
||||
|
||||
use futures::{
|
||||
channel::{mpsc, oneshot},
|
||||
channel::oneshot,
|
||||
future::{poll_fn, BoxFuture},
|
||||
pin_mut,
|
||||
stream::{FusedStream, FuturesUnordered, StreamExt},
|
||||
FutureExt, Stream,
|
||||
Future, FutureExt, Stream,
|
||||
};
|
||||
use lru::LruCache;
|
||||
|
||||
use polkadot_node_network_protocol::{
|
||||
authority_discovery::AuthorityDiscovery,
|
||||
request_response::{
|
||||
request::{OutgoingResponse, OutgoingResponseSender},
|
||||
incoming::{OutgoingResponse, OutgoingResponseSender},
|
||||
v1::{DisputeRequest, DisputeResponse},
|
||||
IncomingRequest,
|
||||
IncomingRequest, IncomingRequestReceiver,
|
||||
},
|
||||
PeerId, UnifiedReputationChange as Rep,
|
||||
};
|
||||
@@ -50,7 +51,7 @@ use crate::{
|
||||
};
|
||||
|
||||
mod error;
|
||||
use self::error::{log_error, Fatal, FatalResult, NonFatal, NonFatalResult, Result};
|
||||
use self::error::{log_error, NonFatal, NonFatalResult, Result};
|
||||
|
||||
const COST_INVALID_REQUEST: Rep = Rep::CostMajor("Received message could not be decoded.");
|
||||
const COST_INVALID_SIGNATURE: Rep = Rep::Malicious("Signatures were invalid.");
|
||||
@@ -72,7 +73,7 @@ pub struct DisputesReceiver<Sender, AD> {
|
||||
sender: Sender,
|
||||
|
||||
/// Channel to retrieve incoming requests from.
|
||||
receiver: mpsc::Receiver<sc_network::config::IncomingRequest>,
|
||||
receiver: IncomingRequestReceiver<DisputeRequest>,
|
||||
|
||||
/// Authority discovery service:
|
||||
authority_discovery: AD,
|
||||
@@ -103,26 +104,27 @@ enum MuxedMessage {
|
||||
ConfirmedImport(NonFatalResult<(PeerId, ImportStatementsResult)>),
|
||||
|
||||
/// A new request has arrived and should be handled.
|
||||
NewRequest(sc_network::config::IncomingRequest),
|
||||
NewRequest(IncomingRequest<DisputeRequest>),
|
||||
}
|
||||
|
||||
impl MuxedMessage {
|
||||
async fn receive(
|
||||
pending_imports: &mut PendingImports,
|
||||
pending_requests: &mut mpsc::Receiver<sc_network::config::IncomingRequest>,
|
||||
) -> FatalResult<MuxedMessage> {
|
||||
pending_requests: &mut IncomingRequestReceiver<DisputeRequest>,
|
||||
) -> Result<MuxedMessage> {
|
||||
poll_fn(|ctx| {
|
||||
if let Poll::Ready(v) = pending_requests.poll_next_unpin(ctx) {
|
||||
let r = match v {
|
||||
None => Err(Fatal::RequestChannelFinished),
|
||||
Some(msg) => Ok(MuxedMessage::NewRequest(msg)),
|
||||
};
|
||||
return Poll::Ready(r)
|
||||
let next_req = pending_requests.recv(|| vec![COST_INVALID_REQUEST]);
|
||||
pin_mut!(next_req);
|
||||
if let Poll::Ready(r) = next_req.poll(ctx) {
|
||||
return match r {
|
||||
Err(e) => Poll::Ready(Err(e.into())),
|
||||
Ok(v) => Poll::Ready(Ok(Self::NewRequest(v))),
|
||||
}
|
||||
}
|
||||
// In case of Ready(None) return `Pending` below - we want to wait for the next request
|
||||
// in that case.
|
||||
if let Poll::Ready(Some(v)) = pending_imports.poll_next_unpin(ctx) {
|
||||
return Poll::Ready(Ok(MuxedMessage::ConfirmedImport(v)))
|
||||
return Poll::Ready(Ok(Self::ConfirmedImport(v)))
|
||||
}
|
||||
Poll::Pending
|
||||
})
|
||||
@@ -137,7 +139,7 @@ where
|
||||
/// Create a new receiver which can be `run`.
|
||||
pub fn new(
|
||||
sender: Sender,
|
||||
receiver: mpsc::Receiver<sc_network::config::IncomingRequest>,
|
||||
receiver: IncomingRequestReceiver<DisputeRequest>,
|
||||
authority_discovery: AD,
|
||||
metrics: Metrics,
|
||||
) -> Self {
|
||||
@@ -165,17 +167,14 @@ where
|
||||
loop {
|
||||
match log_error(self.run_inner().await) {
|
||||
Ok(()) => {},
|
||||
Err(Fatal::RequestChannelFinished) => {
|
||||
Err(fatal) => {
|
||||
tracing::debug!(
|
||||
target: LOG_TARGET,
|
||||
"Incoming request stream exhausted - shutting down?"
|
||||
error = ?fatal,
|
||||
"Shutting down"
|
||||
);
|
||||
return
|
||||
},
|
||||
Err(err) => {
|
||||
tracing::warn!(target: LOG_TARGET, ?err, "Dispute receiver died.");
|
||||
return
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -184,7 +183,7 @@ where
|
||||
async fn run_inner(&mut self) -> Result<()> {
|
||||
let msg = MuxedMessage::receive(&mut self.pending_imports, &mut self.receiver).await?;
|
||||
|
||||
let raw = match msg {
|
||||
let incoming = match msg {
|
||||
// We need to clean up futures, to make sure responses are sent:
|
||||
MuxedMessage::ConfirmedImport(m_bad) => {
|
||||
self.ban_bad_peer(m_bad)?;
|
||||
@@ -195,14 +194,14 @@ where
|
||||
|
||||
self.metrics.on_received_request();
|
||||
|
||||
let peer = raw.peer;
|
||||
let peer = incoming.peer;
|
||||
|
||||
// Only accept messages from validators:
|
||||
if self.authority_discovery.get_authority_id_by_peer_id(raw.peer).await.is_none() {
|
||||
raw.pending_response
|
||||
.send(sc_network::config::OutgoingResponse {
|
||||
if self.authority_discovery.get_authority_id_by_peer_id(peer).await.is_none() {
|
||||
incoming
|
||||
.send_outgoing_response(OutgoingResponse {
|
||||
result: Err(()),
|
||||
reputation_changes: vec![COST_NOT_A_VALIDATOR.into_base_rep()],
|
||||
reputation_changes: vec![COST_NOT_A_VALIDATOR],
|
||||
sent_feedback: None,
|
||||
})
|
||||
.map_err(|_| NonFatal::SendResponse(peer))?;
|
||||
@@ -210,10 +209,6 @@ where
|
||||
return Err(NonFatal::NotAValidator(peer).into())
|
||||
}
|
||||
|
||||
let incoming =
|
||||
IncomingRequest::<DisputeRequest>::try_from_raw(raw, vec![COST_INVALID_REQUEST])
|
||||
.map_err(NonFatal::FromRawRequest)?;
|
||||
|
||||
// Immediately drop requests from peers that already have requests in flight or have
|
||||
// been banned recently (flood protection):
|
||||
if self.pending_imports.peer_is_pending(&peer) || self.banned_peers.contains(&peer) {
|
||||
|
||||
Reference in New Issue
Block a user