mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 18:11:10 +00:00
add fallback request for req-response protocols (#2771)
Previously, it was only possible to retry the same request on a different protocol name that had the exact same binary payloads. Introduce a way of trying a different request on a different protocol if the first one fails with Unsupported protocol. This helps with adding new req-response versions in polkadot while preserving compatibility with unupgraded nodes. The way req-response protocols were bumped previously was that they were bundled with some other notifications protocol upgrade, like for async backing (but that is more complicated, especially if the feature does not require any changes to a notifications protocol). Will be needed for implementing https://github.com/polkadot-fellows/RFCs/pull/47 TODO: - [x] add tests - [x] add guidance docs in polkadot about req-response protocol versioning
This commit is contained in:
@@ -109,7 +109,12 @@ fn prepare_test_inner(
|
||||
chunks: state.chunks.clone(),
|
||||
};
|
||||
|
||||
let network = NetworkEmulator::new(&config, &dependencies, &test_authorities);
|
||||
let req_protocol_names = ReqProtocolNames::new(GENESIS_HASH, None);
|
||||
let (collation_req_receiver, req_cfg) =
|
||||
IncomingRequest::get_config_receiver(&req_protocol_names);
|
||||
|
||||
let network =
|
||||
NetworkEmulator::new(&config, &dependencies, &test_authorities, req_protocol_names);
|
||||
|
||||
let network_bridge_tx = network_bridge::MockNetworkBridgeTx::new(
|
||||
config.clone(),
|
||||
@@ -122,9 +127,6 @@ fn prepare_test_inner(
|
||||
_ => panic!("Unexpected objective"),
|
||||
};
|
||||
|
||||
let (collation_req_receiver, req_cfg) =
|
||||
IncomingRequest::get_config_receiver(&ReqProtocolNames::new(GENESIS_HASH, None));
|
||||
|
||||
let subsystem = if use_fast_path {
|
||||
AvailabilityRecoverySubsystem::with_fast_path(
|
||||
collation_req_receiver,
|
||||
|
||||
@@ -33,7 +33,9 @@ use polkadot_node_subsystem::{
|
||||
};
|
||||
|
||||
use polkadot_node_network_protocol::request_response::{
|
||||
self as req_res, v1::ChunkResponse, Requests,
|
||||
self as req_res,
|
||||
v1::{AvailableDataFetchingRequest, ChunkFetchingRequest, ChunkResponse},
|
||||
IsRequest, Requests,
|
||||
};
|
||||
use polkadot_primitives::AuthorityDiscoveryId;
|
||||
|
||||
@@ -144,7 +146,10 @@ impl MockNetworkBridgeTx {
|
||||
size = 0;
|
||||
Err(RequestFailure::Network(OutboundFailure::ConnectionClosed))
|
||||
} else {
|
||||
Ok(req_res::v1::ChunkFetchingResponse::from(Some(chunk)).encode())
|
||||
Ok((
|
||||
req_res::v1::ChunkFetchingResponse::from(Some(chunk)).encode(),
|
||||
self.network.req_protocol_names().get_name(ChunkFetchingRequest::PROTOCOL),
|
||||
))
|
||||
};
|
||||
|
||||
let authority_discovery_id_clone = authority_discovery_id.clone();
|
||||
@@ -212,8 +217,13 @@ impl MockNetworkBridgeTx {
|
||||
let response = if random_error(self.config.error) {
|
||||
Err(RequestFailure::Network(OutboundFailure::ConnectionClosed))
|
||||
} else {
|
||||
Ok(req_res::v1::AvailableDataFetchingResponse::from(Some(available_data))
|
||||
.encode())
|
||||
Ok((
|
||||
req_res::v1::AvailableDataFetchingResponse::from(Some(available_data))
|
||||
.encode(),
|
||||
self.network
|
||||
.req_protocol_names()
|
||||
.get_name(AvailableDataFetchingRequest::PROTOCOL),
|
||||
))
|
||||
};
|
||||
|
||||
let future = async move {
|
||||
|
||||
@@ -19,6 +19,7 @@ use super::{
|
||||
*,
|
||||
};
|
||||
use colored::Colorize;
|
||||
use polkadot_node_network_protocol::request_response::ReqProtocolNames;
|
||||
use polkadot_primitives::AuthorityDiscoveryId;
|
||||
use prometheus_endpoint::U64;
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
@@ -311,6 +312,8 @@ pub struct NetworkEmulator {
|
||||
stats: Vec<Arc<PeerEmulatorStats>>,
|
||||
/// Each emulated peer is a validator.
|
||||
validator_authority_ids: HashMap<AuthorityDiscoveryId, usize>,
|
||||
/// Request protocol names
|
||||
req_protocol_names: ReqProtocolNames,
|
||||
}
|
||||
|
||||
impl NetworkEmulator {
|
||||
@@ -318,6 +321,7 @@ impl NetworkEmulator {
|
||||
config: &TestConfiguration,
|
||||
dependencies: &TestEnvironmentDependencies,
|
||||
authorities: &TestAuthorities,
|
||||
req_protocol_names: ReqProtocolNames,
|
||||
) -> Self {
|
||||
let n_peers = config.n_validators;
|
||||
gum::info!(target: LOG_TARGET, "{}",format!("Initializing emulation for a {} peer network.", n_peers).bright_blue());
|
||||
@@ -355,7 +359,12 @@ impl NetworkEmulator {
|
||||
|
||||
gum::info!(target: LOG_TARGET, "{}",format!("Network created, connected validator count {}", connected_count).bright_black());
|
||||
|
||||
Self { peers, stats, validator_authority_ids: validator_authority_id_mapping }
|
||||
Self {
|
||||
peers,
|
||||
stats,
|
||||
validator_authority_ids: validator_authority_id_mapping,
|
||||
req_protocol_names,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_peer_connected(&self, peer: &AuthorityDiscoveryId) -> bool {
|
||||
@@ -428,6 +437,11 @@ impl NetworkEmulator {
|
||||
// Our node always is peer 0.
|
||||
self.peer_stats(0).inc_received(bytes);
|
||||
}
|
||||
|
||||
// Get the request protocol names
|
||||
pub fn req_protocol_names(&self) -> &ReqProtocolNames {
|
||||
&self.req_protocol_names
|
||||
}
|
||||
}
|
||||
|
||||
use polkadot_node_subsystem_util::metrics::prometheus::{
|
||||
|
||||
Reference in New Issue
Block a user