From 4def0da0dcae8350f4b48f33f3d568700f74deb6 Mon Sep 17 00:00:00 2001 From: Dmitry Markin <dmitry@markin.tech> Date: Fri, 12 Aug 2022 15:07:13 +0300 Subject: [PATCH] Change request-response protocol names to include genesis hash & fork id (#5870) --- polkadot/Cargo.lock | 1 + .../src/tests/mod.rs | 11 ++- .../availability-recovery/src/tests.rs | 13 ++- polkadot/node/network/bridge/src/network.rs | 6 +- polkadot/node/network/bridge/src/rx/tests.rs | 4 +- polkadot/node/network/bridge/src/tx/mod.rs | 42 +++++++-- polkadot/node/network/bridge/src/tx/tests.rs | 11 ++- .../network/bridge/src/validator_discovery.rs | 6 +- .../src/collator_side/tests.rs | 12 ++- .../dispute-distribution/src/tests/mod.rs | 6 +- polkadot/node/network/protocol/Cargo.toml | 1 + .../src/request_response/incoming/mod.rs | 8 +- .../protocol/src/request_response/mod.rs | 94 ++++++++++++++----- .../statement-distribution/src/tests.rs | 22 +++-- polkadot/node/service/src/lib.rs | 30 +++--- polkadot/node/service/src/overseer.rs | 9 +- .../src/node/disputes/dispute-distribution.md | 4 +- 17 files changed, 207 insertions(+), 73 deletions(-) diff --git a/polkadot/Cargo.lock b/polkadot/Cargo.lock index d2d0d1e5389..fcaa07ff59c 100644 --- a/polkadot/Cargo.lock +++ b/polkadot/Cargo.lock @@ -6671,6 +6671,7 @@ dependencies = [ "derive_more", "fatality", "futures", + "hex", "parity-scale-codec", "polkadot-node-jaeger", "polkadot-node-primitives", diff --git a/polkadot/node/network/availability-distribution/src/tests/mod.rs b/polkadot/node/network/availability-distribution/src/tests/mod.rs index fd5d0dafaf1..ebbc436a00d 100644 --- a/polkadot/node/network/availability-distribution/src/tests/mod.rs +++ b/polkadot/node/network/availability-distribution/src/tests/mod.rs @@ -18,8 +18,8 @@ use std::collections::HashSet; use futures::{executor, future, Future}; -use polkadot_node_network_protocol::request_response::IncomingRequest; -use polkadot_primitives::v2::CoreState; +use polkadot_node_network_protocol::request_response::{IncomingRequest, ReqProtocolNames}; +use polkadot_primitives::v2::{CoreState, Hash}; use sp_keystore::SyncCryptoStorePtr; use polkadot_node_subsystem_test_helpers as test_helpers; @@ -41,9 +41,12 @@ fn test_harness<T: Future<Output = ()>>( let pool = sp_core::testing::TaskExecutor::new(); let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool.clone()); + let genesis_hash = Hash::repeat_byte(0xff); + let req_protocol_names = ReqProtocolNames::new(&genesis_hash, None); - let (pov_req_receiver, pov_req_cfg) = IncomingRequest::get_config_receiver(); - let (chunk_req_receiver, chunk_req_cfg) = IncomingRequest::get_config_receiver(); + let (pov_req_receiver, pov_req_cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); + let (chunk_req_receiver, chunk_req_cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); let subsystem = AvailabilityDistributionSubsystem::new( keystore, IncomingRequestReceivers { pov_req_receiver, chunk_req_receiver }, diff --git a/polkadot/node/network/availability-recovery/src/tests.rs b/polkadot/node/network/availability-recovery/src/tests.rs index 3c16157f488..2cfed743bc5 100644 --- a/polkadot/node/network/availability-recovery/src/tests.rs +++ b/polkadot/node/network/availability-recovery/src/tests.rs @@ -21,7 +21,7 @@ use futures::{executor, future}; use futures_timer::Delay; use parity_scale_codec::Encode; -use polkadot_node_network_protocol::request_response::IncomingRequest; +use polkadot_node_network_protocol::request_response::{IncomingRequest, ReqProtocolNames}; use super::*; @@ -36,11 +36,14 @@ use polkadot_node_subsystem::{ }; use polkadot_node_subsystem_test_helpers::{make_subsystem_context, TestSubsystemContextHandle}; use polkadot_node_subsystem_util::TimeoutExt; -use polkadot_primitives::v2::{AuthorityDiscoveryId, HeadData, PersistedValidationData}; +use polkadot_primitives::v2::{AuthorityDiscoveryId, Hash, HeadData, PersistedValidationData}; use polkadot_primitives_test_helpers::{dummy_candidate_receipt, dummy_hash}; type VirtualOverseer = TestSubsystemContextHandle<AvailabilityRecoveryMessage>; +// Deterministic genesis hash for protocol names +const GENESIS_HASH: Hash = Hash::repeat_byte(0xff); + fn test_harness_fast_path<T: Future<Output = (VirtualOverseer, RequestResponseConfig)>>( test: impl FnOnce(VirtualOverseer, RequestResponseConfig) -> T, ) { @@ -53,7 +56,8 @@ fn test_harness_fast_path<T: Future<Output = (VirtualOverseer, RequestResponseCo let (context, virtual_overseer) = make_subsystem_context(pool.clone()); - let (collation_req_receiver, req_cfg) = IncomingRequest::get_config_receiver(); + let (collation_req_receiver, req_cfg) = + IncomingRequest::get_config_receiver(&ReqProtocolNames::new(&GENESIS_HASH, None)); let subsystem = AvailabilityRecoverySubsystem::with_fast_path(collation_req_receiver, Metrics::new_dummy()); let subsystem = async { @@ -87,7 +91,8 @@ fn test_harness_chunks_only<T: Future<Output = (VirtualOverseer, RequestResponse let (context, virtual_overseer) = make_subsystem_context(pool.clone()); - let (collation_req_receiver, req_cfg) = IncomingRequest::get_config_receiver(); + let (collation_req_receiver, req_cfg) = + IncomingRequest::get_config_receiver(&ReqProtocolNames::new(&GENESIS_HASH, None)); let subsystem = AvailabilityRecoverySubsystem::with_chunks_only( collation_req_receiver, Metrics::new_dummy(), diff --git a/polkadot/node/network/bridge/src/network.rs b/polkadot/node/network/bridge/src/network.rs index cea6283202b..00a950f35c5 100644 --- a/polkadot/node/network/bridge/src/network.rs +++ b/polkadot/node/network/bridge/src/network.rs @@ -31,7 +31,7 @@ use sc_network_common::service::{ use polkadot_node_network_protocol::{ peer_set::PeerSet, - request_response::{OutgoingRequest, Recipient, Requests}, + request_response::{OutgoingRequest, Recipient, ReqProtocolNames, Requests}, PeerId, ProtocolVersion, UnifiedReputationChange as Rep, }; use polkadot_primitives::v2::{AuthorityDiscoveryId, Block, Hash}; @@ -100,6 +100,7 @@ pub trait Network: Clone + Send + 'static { &self, authority_discovery: &mut AD, req: Requests, + req_protocol_names: &ReqProtocolNames, if_disconnected: IfDisconnected, ); @@ -152,6 +153,7 @@ impl Network for Arc<NetworkService<Block, Hash>> { &self, authority_discovery: &mut AD, req: Requests, + req_protocol_names: &ReqProtocolNames, if_disconnected: IfDisconnected, ) { let (protocol, OutgoingRequest { peer, payload, pending_response }) = req.encode_request(); @@ -197,7 +199,7 @@ impl Network for Arc<NetworkService<Block, Hash>> { NetworkService::start_request( &*self, peer_id, - protocol.into_protocol_name(), + req_protocol_names.get_name(protocol), payload, pending_response, if_disconnected, diff --git a/polkadot/node/network/bridge/src/rx/tests.rs b/polkadot/node/network/bridge/src/rx/tests.rs index 4e4ce923d8c..ad1d8392d30 100644 --- a/polkadot/node/network/bridge/src/rx/tests.rs +++ b/polkadot/node/network/bridge/src/rx/tests.rs @@ -31,7 +31,8 @@ use std::{ use sc_network::{Event as NetworkEvent, IfDisconnected}; use polkadot_node_network_protocol::{ - request_response::outgoing::Requests, view, ObservedRole, Versioned, + request_response::{outgoing::Requests, ReqProtocolNames}, + view, ObservedRole, Versioned, }; use polkadot_node_subsystem::{ jaeger, @@ -117,6 +118,7 @@ impl Network for TestNetwork { &self, _: &mut AD, _: Requests, + _: &ReqProtocolNames, _: IfDisconnected, ) { } diff --git a/polkadot/node/network/bridge/src/tx/mod.rs b/polkadot/node/network/bridge/src/tx/mod.rs index d58ccf8fbb9..ac34cf315ce 100644 --- a/polkadot/node/network/bridge/src/tx/mod.rs +++ b/polkadot/node/network/bridge/src/tx/mod.rs @@ -17,7 +17,9 @@ //! The Network Bridge Subsystem - handles _outgoing_ messages, from subsystem to the network. use super::*; -use polkadot_node_network_protocol::{peer_set::PeerSet, v1 as protocol_v1, PeerId, Versioned}; +use polkadot_node_network_protocol::{ + peer_set::PeerSet, request_response::ReqProtocolNames, v1 as protocol_v1, PeerId, Versioned, +}; use polkadot_node_subsystem::{ errors::SubsystemError, messages::NetworkBridgeTxMessage, overseer, FromOrchestra, @@ -50,6 +52,7 @@ pub struct NetworkBridgeTx<N, AD> { network_service: N, authority_discovery_service: AD, metrics: Metrics, + req_protocol_names: ReqProtocolNames, } impl<N, AD> NetworkBridgeTx<N, AD> { @@ -57,8 +60,13 @@ impl<N, AD> NetworkBridgeTx<N, AD> { /// /// This assumes that the network service has had the notifications protocol for the network /// bridge already registered. See [`peers_sets_info`](peers_sets_info). - pub fn new(network_service: N, authority_discovery_service: AD, metrics: Metrics) -> Self { - Self { network_service, authority_discovery_service, metrics } + pub fn new( + network_service: N, + authority_discovery_service: AD, + metrics: Metrics, + req_protocol_names: ReqProtocolNames, + ) -> Self { + Self { network_service, authority_discovery_service, metrics, req_protocol_names } } } @@ -82,6 +90,7 @@ async fn handle_subsystem_messages<Context, N, AD>( mut network_service: N, mut authority_discovery_service: AD, metrics: Metrics, + req_protocol_names: ReqProtocolNames, ) -> Result<(), Error> where N: Network, @@ -102,6 +111,7 @@ where authority_discovery_service.clone(), msg, &metrics, + &req_protocol_names, ) .await; }, @@ -117,6 +127,7 @@ async fn handle_incoming_subsystem_communication<Context, N, AD>( mut authority_discovery_service: AD, msg: NetworkBridgeTxMessage, metrics: &Metrics, + req_protocol_names: &ReqProtocolNames, ) -> (N, AD) where N: Network, @@ -218,7 +229,12 @@ where for req in reqs { network_service - .start_request(&mut authority_discovery_service, req, if_disconnected) + .start_request( + &mut authority_discovery_service, + req, + req_protocol_names, + if_disconnected, + ) .await; } }, @@ -275,9 +291,21 @@ where N: Network, AD: validator_discovery::AuthorityDiscovery + Clone + Sync, { - let NetworkBridgeTx { network_service, authority_discovery_service, metrics } = bridge; - - handle_subsystem_messages(ctx, network_service, authority_discovery_service, metrics).await?; + let NetworkBridgeTx { + network_service, + authority_discovery_service, + metrics, + req_protocol_names, + } = bridge; + + handle_subsystem_messages( + ctx, + network_service, + authority_discovery_service, + metrics, + req_protocol_names, + ) + .await?; Ok(()) } diff --git a/polkadot/node/network/bridge/src/tx/tests.rs b/polkadot/node/network/bridge/src/tx/tests.rs index 63d9730e659..d5b6d3ca67a 100644 --- a/polkadot/node/network/bridge/src/tx/tests.rs +++ b/polkadot/node/network/bridge/src/tx/tests.rs @@ -25,12 +25,13 @@ use std::{borrow::Cow, collections::HashSet}; use sc_network::{Event as NetworkEvent, IfDisconnected}; use polkadot_node_network_protocol::{ - request_response::outgoing::Requests, ObservedRole, Versioned, + request_response::{outgoing::Requests, ReqProtocolNames}, + ObservedRole, Versioned, }; use polkadot_node_subsystem::{FromOrchestra, OverseerSignal}; use polkadot_node_subsystem_test_helpers::TestSubsystemContextHandle; use polkadot_node_subsystem_util::metered; -use polkadot_primitives::v2::AuthorityDiscoveryId; +use polkadot_primitives::v2::{AuthorityDiscoveryId, Hash}; use polkadot_primitives_test_helpers::dummy_collator_signature; use sc_network::Multiaddr; use sp_keyring::Sr25519Keyring; @@ -104,6 +105,7 @@ impl Network for TestNetwork { &self, _: &mut AD, _: Requests, + _: &ReqProtocolNames, _: IfDisconnected, ) { } @@ -182,7 +184,10 @@ fn test_harness<T: Future<Output = VirtualOverseer>>(test: impl FnOnce(TestHarne let (context, virtual_overseer) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); - let bridge_out = NetworkBridgeTx::new(network, discovery, Metrics(None)); + let genesis_hash = Hash::repeat_byte(0xff); + let protocol_names = ReqProtocolNames::new(genesis_hash, None); + + let bridge_out = NetworkBridgeTx::new(network, discovery, Metrics(None), protocol_names); let network_bridge_out_fut = run_network_out(bridge_out, context) .map_err(|e| panic!("bridge-out subsystem execution failed {:?}", e)) diff --git a/polkadot/node/network/bridge/src/validator_discovery.rs b/polkadot/node/network/bridge/src/validator_discovery.rs index eb9bb954e7a..9c90200aa06 100644 --- a/polkadot/node/network/bridge/src/validator_discovery.rs +++ b/polkadot/node/network/bridge/src/validator_discovery.rs @@ -162,7 +162,10 @@ mod tests { use async_trait::async_trait; use futures::stream::BoxStream; - use polkadot_node_network_protocol::{request_response::outgoing::Requests, PeerId}; + use polkadot_node_network_protocol::{ + request_response::{outgoing::Requests, ReqProtocolNames}, + PeerId, + }; use sc_network::{Event as NetworkEvent, IfDisconnected}; use sp_keyring::Sr25519Keyring; use std::{ @@ -236,6 +239,7 @@ mod tests { &self, _: &mut AD, _: Requests, + _: &ReqProtocolNames, _: IfDisconnected, ) { } diff --git a/polkadot/node/network/collator-protocol/src/collator_side/tests.rs b/polkadot/node/network/collator-protocol/src/collator_side/tests.rs index 4d95b7c807e..f81e738e16a 100644 --- a/polkadot/node/network/collator-protocol/src/collator_side/tests.rs +++ b/polkadot/node/network/collator-protocol/src/collator_side/tests.rs @@ -29,7 +29,11 @@ use sp_core::crypto::Pair; use sp_keyring::Sr25519Keyring; use sp_runtime::traits::AppVerify; -use polkadot_node_network_protocol::{our_view, request_response::IncomingRequest, view}; +use polkadot_node_network_protocol::{ + our_view, + request_response::{IncomingRequest, ReqProtocolNames}, + view, +}; use polkadot_node_primitives::BlockData; use polkadot_node_subsystem::{ jaeger, @@ -201,7 +205,11 @@ fn test_harness<T: Future<Output = TestHarness>>( let (context, virtual_overseer) = test_helpers::make_subsystem_context(pool.clone()); - let (collation_req_receiver, req_cfg) = IncomingRequest::get_config_receiver(); + let genesis_hash = Hash::repeat_byte(0xff); + let req_protocol_names = ReqProtocolNames::new(&genesis_hash, None); + + let (collation_req_receiver, req_cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); let subsystem = async { run(context, local_peer_id, collator_pair, collation_req_receiver, Default::default()) .await diff --git a/polkadot/node/network/dispute-distribution/src/tests/mod.rs b/polkadot/node/network/dispute-distribution/src/tests/mod.rs index 9c843f3e786..8f78b664de8 100644 --- a/polkadot/node/network/dispute-distribution/src/tests/mod.rs +++ b/polkadot/node/network/dispute-distribution/src/tests/mod.rs @@ -31,7 +31,7 @@ use parity_scale_codec::{Decode, Encode}; use sc_network::config::RequestResponseConfig; use polkadot_node_network_protocol::{ - request_response::{v1::DisputeRequest, IncomingRequest}, + request_response::{v1::DisputeRequest, IncomingRequest, ReqProtocolNames}, PeerId, }; use sp_keyring::Sr25519Keyring; @@ -723,7 +723,9 @@ where sp_tracing::try_init_simple(); let keystore = make_ferdie_keystore(); - let (req_receiver, req_cfg) = IncomingRequest::get_config_receiver(); + let genesis_hash = Hash::repeat_byte(0xff); + let req_protocol_names = ReqProtocolNames::new(&genesis_hash, None); + let (req_receiver, req_cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); let subsystem = DisputeDistributionSubsystem::new( keystore, req_receiver, diff --git a/polkadot/node/network/protocol/Cargo.toml b/polkadot/node/network/protocol/Cargo.toml index 7b26a03e3d4..8b863089cc9 100644 --- a/polkadot/node/network/protocol/Cargo.toml +++ b/polkadot/node/network/protocol/Cargo.toml @@ -7,6 +7,7 @@ description = "Primitives types for the Node-side" [dependencies] async-trait = "0.1.53" +hex = "0.4.3" polkadot-primitives = { path = "../../../primitives" } polkadot-node-primitives = { path = "../../primitives" } polkadot-node-jaeger = { path = "../../jaeger" } diff --git a/polkadot/node/network/protocol/src/request_response/incoming/mod.rs b/polkadot/node/network/protocol/src/request_response/incoming/mod.rs index 309ca32b0de..808d7064599 100644 --- a/polkadot/node/network/protocol/src/request_response/incoming/mod.rs +++ b/polkadot/node/network/protocol/src/request_response/incoming/mod.rs @@ -25,7 +25,7 @@ use parity_scale_codec::{Decode, Encode}; use sc_network::{config as netconfig, config::RequestResponseConfig, PeerId}; -use super::IsRequest; +use super::{IsRequest, ReqProtocolNames}; use crate::UnifiedReputationChange; mod error; @@ -55,8 +55,10 @@ where /// /// This Register that config with substrate networking and receive incoming requests via the /// returned `IncomingRequestReceiver`. - pub fn get_config_receiver() -> (IncomingRequestReceiver<Req>, RequestResponseConfig) { - let (raw, cfg) = Req::PROTOCOL.get_config(); + pub fn get_config_receiver( + req_protocol_names: &ReqProtocolNames, + ) -> (IncomingRequestReceiver<Req>, RequestResponseConfig) { + let (raw, cfg) = Req::PROTOCOL.get_config(req_protocol_names); (IncomingRequestReceiver { raw, phantom: PhantomData {} }, cfg) } diff --git a/polkadot/node/network/protocol/src/request_response/mod.rs b/polkadot/node/network/protocol/src/request_response/mod.rs index b434c152b89..fb955286990 100644 --- a/polkadot/node/network/protocol/src/request_response/mod.rs +++ b/polkadot/node/network/protocol/src/request_response/mod.rs @@ -32,11 +32,11 @@ //! //! Versioned (v1 module): The actual requests and responses as sent over the network. -use std::{borrow::Cow, time::Duration, u64}; +use std::{borrow::Cow, collections::HashMap, time::Duration, u64}; use futures::channel::mpsc; use polkadot_primitives::v2::{MAX_CODE_SIZE, MAX_POV_SIZE}; -use strum::EnumIter; +use strum::{EnumIter, IntoEnumIterator}; pub use sc_network::{config as network, config::RequestResponseConfig}; @@ -126,13 +126,17 @@ impl Protocol { /// /// Returns a receiver for messages received on this protocol and the requested /// `ProtocolConfig`. - pub fn get_config(self) -> (mpsc::Receiver<network::IncomingRequest>, RequestResponseConfig) { - let p_name = self.into_protocol_name(); + pub fn get_config( + self, + req_protocol_names: &ReqProtocolNames, + ) -> (mpsc::Receiver<network::IncomingRequest>, RequestResponseConfig) { + let name = req_protocol_names.get_name(self); + let fallback_names = self.get_fallback_names(); let (tx, rx) = mpsc::channel(self.get_channel_size()); let cfg = match self { Protocol::ChunkFetchingV1 => RequestResponseConfig { - name: p_name, - fallback_names: Vec::new(), + name, + fallback_names, max_request_size: 1_000, max_response_size: POV_RESPONSE_SIZE as u64 * 3, // We are connected to all validators: @@ -140,8 +144,8 @@ impl Protocol { inbound_queue: Some(tx), }, Protocol::CollationFetchingV1 => RequestResponseConfig { - name: p_name, - fallback_names: Vec::new(), + name, + fallback_names, max_request_size: 1_000, max_response_size: POV_RESPONSE_SIZE, // Taken from initial implementation in collator protocol: @@ -149,16 +153,16 @@ impl Protocol { inbound_queue: Some(tx), }, Protocol::PoVFetchingV1 => RequestResponseConfig { - name: p_name, - fallback_names: Vec::new(), + name, + fallback_names, max_request_size: 1_000, max_response_size: POV_RESPONSE_SIZE, request_timeout: POV_REQUEST_TIMEOUT_CONNECTED, inbound_queue: Some(tx), }, Protocol::AvailableDataFetchingV1 => RequestResponseConfig { - name: p_name, - fallback_names: Vec::new(), + name, + fallback_names, max_request_size: 1_000, // Available data size is dominated by the PoV size. max_response_size: POV_RESPONSE_SIZE, @@ -166,8 +170,8 @@ impl Protocol { inbound_queue: Some(tx), }, Protocol::StatementFetchingV1 => RequestResponseConfig { - name: p_name, - fallback_names: Vec::new(), + name, + fallback_names, max_request_size: 1_000, // Available data size is dominated code size. max_response_size: STATEMENT_RESPONSE_SIZE, @@ -184,8 +188,8 @@ impl Protocol { inbound_queue: Some(tx), }, Protocol::DisputeSendingV1 => RequestResponseConfig { - name: p_name, - fallback_names: Vec::new(), + name, + fallback_names, max_request_size: 1_000, /// Responses are just confirmation, in essence not even a bit. So 100 seems /// plenty. @@ -243,13 +247,13 @@ impl Protocol { } } - /// Get the protocol name of this protocol, as understood by substrate networking. - pub fn into_protocol_name(self) -> Cow<'static, str> { - self.get_protocol_name_static().into() + /// Fallback protocol names of this protocol, as understood by substrate networking. + fn get_fallback_names(self) -> Vec<Cow<'static, str>> { + std::iter::once(self.get_legacy_name().into()).collect() } - /// Get the protocol name associated with each peer set as static str. - pub const fn get_protocol_name_static(self) -> &'static str { + /// Legacy protocol name associated with each peer set. + const fn get_legacy_name(self) -> &'static str { match self { Protocol::ChunkFetchingV1 => "/polkadot/req_chunk/1", Protocol::CollationFetchingV1 => "/polkadot/req_collation/1", @@ -269,3 +273,51 @@ pub trait IsRequest { /// What protocol this `Request` implements. const PROTOCOL: Protocol; } + +/// Type for getting on the wire [`Protocol`] names using genesis hash & fork id. +pub struct ReqProtocolNames { + names: HashMap<Protocol, Cow<'static, str>>, +} + +impl ReqProtocolNames { + /// Construct [`ReqProtocolNames`] from `genesis_hash` and `fork_id`. + pub fn new<Hash: AsRef<[u8]>>(genesis_hash: Hash, fork_id: Option<&str>) -> Self { + let mut names = HashMap::new(); + for protocol in Protocol::iter() { + names.insert(protocol, Self::generate_name(protocol, &genesis_hash, fork_id)); + } + Self { names } + } + + /// Get on the wire [`Protocol`] name. + pub fn get_name(&self, protocol: Protocol) -> Cow<'static, str> { + self.names + .get(&protocol) + .expect("All `Protocol` enum variants are added above via `strum`; qed") + .clone() + } + + /// Protocol name of this protocol based on `genesis_hash` and `fork_id`. + fn generate_name<Hash: AsRef<[u8]>>( + protocol: Protocol, + genesis_hash: &Hash, + fork_id: Option<&str>, + ) -> Cow<'static, str> { + let prefix = if let Some(fork_id) = fork_id { + format!("/{}/{}", hex::encode(genesis_hash), fork_id) + } else { + format!("/{}", hex::encode(genesis_hash)) + }; + + let short_name = match protocol { + Protocol::ChunkFetchingV1 => "/req_chunk/1", + Protocol::CollationFetchingV1 => "/req_collation/1", + Protocol::PoVFetchingV1 => "/req_pov/1", + Protocol::AvailableDataFetchingV1 => "/req_available_data/1", + Protocol::StatementFetchingV1 => "/req_statement/1", + Protocol::DisputeSendingV1 => "/send_dispute/1", + }; + + format!("{}{}", prefix, short_name).into() + } +} diff --git a/polkadot/node/network/statement-distribution/src/tests.rs b/polkadot/node/network/statement-distribution/src/tests.rs index 49a6e211bbd..efc9ca896bb 100644 --- a/polkadot/node/network/statement-distribution/src/tests.rs +++ b/polkadot/node/network/statement-distribution/src/tests.rs @@ -22,7 +22,7 @@ use parity_scale_codec::{Decode, Encode}; use polkadot_node_network_protocol::{ request_response::{ v1::{StatementFetchingRequest, StatementFetchingResponse}, - IncomingRequest, Recipient, Requests, + IncomingRequest, Recipient, ReqProtocolNames, Requests, }, view, ObservedRole, }; @@ -44,6 +44,9 @@ use sp_keyring::Sr25519Keyring; use sp_keystore::{CryptoStore, SyncCryptoStore, SyncCryptoStorePtr}; use std::{iter::FromIterator as _, sync::Arc, time::Duration}; +// Some deterministic genesis hash for protocol names +const GENESIS_HASH: Hash = Hash::repeat_byte(0xff); + #[test] fn active_head_accepts_only_2_seconded_per_validator() { let validators = vec![ @@ -724,7 +727,8 @@ fn receiving_from_one_sends_to_another_and_to_candidate_backing() { let pool = sp_core::testing::TaskExecutor::new(); let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); - let (statement_req_receiver, _) = IncomingRequest::get_config_receiver(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let (statement_req_receiver, _) = IncomingRequest::get_config_receiver(&req_protocol_names); let bg = async move { let s = StatementDistributionSubsystem::new( @@ -917,7 +921,9 @@ fn receiving_large_statement_from_one_sends_to_another_and_to_candidate_backing( let pool = sp_core::testing::TaskExecutor::new(); let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); - let (statement_req_receiver, mut req_cfg) = IncomingRequest::get_config_receiver(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let (statement_req_receiver, mut req_cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); let bg = async move { let s = StatementDistributionSubsystem::new( @@ -1429,7 +1435,9 @@ fn share_prioritizes_backing_group() { let pool = sp_core::testing::TaskExecutor::new(); let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); - let (statement_req_receiver, mut req_cfg) = IncomingRequest::get_config_receiver(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let (statement_req_receiver, mut req_cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); let bg = async move { let s = StatementDistributionSubsystem::new( @@ -1724,7 +1732,8 @@ fn peer_cant_flood_with_large_statements() { let pool = sp_core::testing::TaskExecutor::new(); let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); - let (statement_req_receiver, _) = IncomingRequest::get_config_receiver(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let (statement_req_receiver, _) = IncomingRequest::get_config_receiver(&req_protocol_names); let bg = async move { let s = StatementDistributionSubsystem::new( make_ferdie_keystore(), @@ -1928,7 +1937,8 @@ fn handle_multiple_seconded_statements() { let pool = sp_core::testing::TaskExecutor::new(); let (ctx, mut handle) = polkadot_node_subsystem_test_helpers::make_subsystem_context(pool); - let (statement_req_receiver, _) = IncomingRequest::get_config_receiver(); + let req_protocol_names = ReqProtocolNames::new(&GENESIS_HASH, None); + let (statement_req_receiver, _) = IncomingRequest::get_config_receiver(&req_protocol_names); let virtual_overseer_fut = async move { let s = StatementDistributionSubsystem::new( diff --git a/polkadot/node/service/src/lib.rs b/polkadot/node/service/src/lib.rs index d12b2ccadb3..206809aeefe 100644 --- a/polkadot/node/service/src/lib.rs +++ b/polkadot/node/service/src/lib.rs @@ -46,6 +46,7 @@ use { self as chain_selection_subsystem, Config as ChainSelectionConfig, }, polkadot_node_core_dispute_coordinator::Config as DisputeCoordinatorConfig, + polkadot_node_network_protocol::request_response::ReqProtocolNames, polkadot_overseer::BlockInfo, sc_client_api::{BlockBackend, ExecutorProvider}, sp_core::traits::SpawnNamed, @@ -831,22 +832,19 @@ where let shared_voter_state = rpc_setup; let auth_disc_publish_non_global_ips = config.network.allow_non_globals_in_dht; + let genesis_hash = client.block_hash(0).ok().flatten().expect("Genesis block exists; qed"); + // Note: GrandPa is pushed before the Polkadot-specific protocols. This doesn't change // anything in terms of behaviour, but makes the logs more consistent with the other // Substrate nodes. - let grandpa_protocol_name = grandpa::protocol_standard_name( - &client.block_hash(0).ok().flatten().expect("Genesis block exists; qed"), - &config.chain_spec, - ); + let grandpa_protocol_name = grandpa::protocol_standard_name(&genesis_hash, &config.chain_spec); config .network .extra_sets .push(grandpa::grandpa_peers_set_config(grandpa_protocol_name.clone())); - let beefy_protocol_name = beefy_gadget::protocol_standard_name( - &client.block_hash(0).ok().flatten().expect("Genesis block exists; qed"), - &config.chain_spec, - ); + let beefy_protocol_name = + beefy_gadget::protocol_standard_name(&genesis_hash, &config.chain_spec); if enable_beefy { config .network @@ -860,17 +858,20 @@ where config.network.extra_sets.extend(peer_sets_info(is_authority)); } - let (pov_req_receiver, cfg) = IncomingRequest::get_config_receiver(); + let req_protocol_names = ReqProtocolNames::new(&genesis_hash, config.chain_spec.fork_id()); + + let (pov_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); config.network.request_response_protocols.push(cfg); - let (chunk_req_receiver, cfg) = IncomingRequest::get_config_receiver(); + let (chunk_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); config.network.request_response_protocols.push(cfg); - let (collation_req_receiver, cfg) = IncomingRequest::get_config_receiver(); + let (collation_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); config.network.request_response_protocols.push(cfg); - let (available_data_req_receiver, cfg) = IncomingRequest::get_config_receiver(); + let (available_data_req_receiver, cfg) = + IncomingRequest::get_config_receiver(&req_protocol_names); config.network.request_response_protocols.push(cfg); - let (statement_req_receiver, cfg) = IncomingRequest::get_config_receiver(); + let (statement_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); config.network.request_response_protocols.push(cfg); - let (dispute_req_receiver, cfg) = IncomingRequest::get_config_receiver(); + let (dispute_req_receiver, cfg) = IncomingRequest::get_config_receiver(&req_protocol_names); config.network.request_response_protocols.push(cfg); let grandpa_hard_forks = if config.chain_spec.is_kusama() { @@ -1061,6 +1062,7 @@ where dispute_coordinator_config, pvf_checker_enabled, overseer_message_channel_capacity_override, + req_protocol_names, }, ) .map_err(|e| { diff --git a/polkadot/node/service/src/overseer.rs b/polkadot/node/service/src/overseer.rs index c150dd35e72..622b815944a 100644 --- a/polkadot/node/service/src/overseer.rs +++ b/polkadot/node/service/src/overseer.rs @@ -24,7 +24,9 @@ use polkadot_node_core_av_store::Config as AvailabilityConfig; use polkadot_node_core_candidate_validation::Config as CandidateValidationConfig; use polkadot_node_core_chain_selection::Config as ChainSelectionConfig; use polkadot_node_core_dispute_coordinator::Config as DisputeCoordinatorConfig; -use polkadot_node_network_protocol::request_response::{v1 as request_v1, IncomingRequestReceiver}; +use polkadot_node_network_protocol::request_response::{ + v1 as request_v1, IncomingRequestReceiver, ReqProtocolNames, +}; #[cfg(any(feature = "malus", test))] pub use polkadot_overseer::{ dummy::{dummy_overseer_builder, DummySubsystem}, @@ -118,6 +120,8 @@ where pub pvf_checker_enabled: bool, /// Overseer channel capacity override. pub overseer_message_channel_capacity_override: Option<usize>, + /// Request-response protocol names source. + pub req_protocol_names: ReqProtocolNames, } /// Obtain a prepared `OverseerBuilder`, that is initialized @@ -146,6 +150,7 @@ pub fn prepared_overseer_builder<'a, Spawner, RuntimeClient>( dispute_coordinator_config, pvf_checker_enabled, overseer_message_channel_capacity_override, + req_protocol_names, }: OverseerGenArgs<'a, Spawner, RuntimeClient>, ) -> Result< InitializedOverseerBuilder< @@ -194,11 +199,13 @@ where let spawner = SpawnGlue(spawner); let network_bridge_metrics: NetworkBridgeMetrics = Metrics::register(registry)?; + let builder = Overseer::builder() .network_bridge_tx(NetworkBridgeTxSubsystem::new( network_service.clone(), authority_discovery_service.clone(), network_bridge_metrics.clone(), + req_protocol_names, )) .network_bridge_rx(NetworkBridgeRxSubsystem::new( network_service.clone(), diff --git a/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-distribution.md b/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-distribution.md index eb571420fb7..579a1ce8f14 100644 --- a/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-distribution.md +++ b/polkadot/roadmap/implementers-guide/src/node/disputes/dispute-distribution.md @@ -30,7 +30,7 @@ This design should result in a protocol that is: #### Disputes -Protocol: `"/polkadot/send_dispute/1"` +Protocol: `"/<genesis_hash>/<fork_id>/send_dispute/1"` Request: @@ -86,7 +86,7 @@ enum DisputeResponse { #### Vote Recovery -Protocol: `"/polkadot/req_votes/1"` +Protocol: `"/<genesis_hash>/<fork_id>/req_votes/1"` ```rust struct IHaveVotesRequest { -- GitLab