diff --git a/bin/full-node/src/run.rs b/bin/full-node/src/run.rs index ab7ecc2094..8a25644fd0 100644 --- a/bin/full-node/src/run.rs +++ b/bin/full-node/src/run.rs @@ -223,6 +223,7 @@ pub async fn run(cli_options: cli::CliOptionsRun) { num_events_receivers: 2 + if relay_chain_database.is_some() { 1 } else { 0 }, chains: iter::once(network_service::ChainConfig { protocol_id: chain_spec.protocol_id().to_owned(), + fork_id: chain_spec.fork_id().map(|s| s.to_owned()), database: database.clone(), has_grandpa_protocol: matches!( genesis_chain_information.finality, @@ -260,6 +261,7 @@ pub async fn run(cli_options: cli::CliOptionsRun) { if let Some(relay_chains_specs) = &relay_chain_spec { Some(network_service::ChainConfig { protocol_id: relay_chains_specs.protocol_id().to_owned(), + fork_id: relay_chains_specs.fork_id().map(|s| s.to_owned()), database: relay_chain_database.clone().unwrap(), has_grandpa_protocol: matches!( relay_genesis_chain_information.as_ref().unwrap().finality, diff --git a/bin/full-node/src/run/network_service.rs b/bin/full-node/src/run/network_service.rs index 1dedbb8f37..e091782e76 100644 --- a/bin/full-node/src/run/network_service.rs +++ b/bin/full-node/src/run/network_service.rs @@ -97,6 +97,11 @@ pub struct ChainConfig { /// chain, so as to not introduce conflicts in the networking messages. pub protocol_id: String, + /// Optional fork identifier, used to differentiate between chains with the same genesis hash. + /// + /// This can be a counter (e.g. "1", "2", "3") or some unique identifier (e.g. "classic"). + pub fork_id: Option, + /// If true, the chain uses the GrandPa networking protocol. pub has_grandpa_protocol: bool, } @@ -160,6 +165,7 @@ impl NetworkService { in_slots: 25, out_slots: 25, protocol_id: chain.protocol_id.clone(), + fork_id: chain.fork_id.clone(), best_hash: chain.best_block.1, best_number: chain.best_block.0, genesis_hash: chain.genesis_block_hash, diff --git a/bin/light-base/src/lib.rs b/bin/light-base/src/lib.rs index 875165b1f1..3f2fe325e4 100644 --- a/bin/light-base/src/lib.rs +++ b/bin/light-base/src/lib.rs @@ -261,6 +261,11 @@ struct ChainKey { /// Network protocol id, found in the chain specification. protocol_id: String, + + /// Optional fork identifier, used to differentiate between chains with the same genesis hash. + /// + /// This can be a counter (e.g. "1", "2", "3") or some unique identifier (e.g. "classic"). + fork_id: Option, } struct RunningChain { @@ -488,6 +493,7 @@ impl Client { ) }), protocol_id: chain_spec.protocol_id().to_owned(), + fork_id: chain_spec.fork_id().map(|s| s.to_owned()), }; // If the chain we are adding is a parachain, grab the services of the relay chain. @@ -982,6 +988,7 @@ async fn start_services( chain_information.as_ref().finalized_block_header.hash(), ), protocol_id: chain_spec.protocol_id().to_string(), + fork_id: chain_spec.fork_id().map(|s| s.to_string()), }], }) .await; diff --git a/bin/light-base/src/network_service.rs b/bin/light-base/src/network_service.rs index 0fd57d8206..128b30f054 100644 --- a/bin/light-base/src/network_service.rs +++ b/bin/light-base/src/network_service.rs @@ -98,6 +98,11 @@ pub struct ConfigChain { /// chain, so as to not introduce conflicts in the networking messages. pub protocol_id: String, + /// Optional fork identifier, used to differentiate between chains with the same genesis hash. + /// + /// This can be a counter (e.g. "1", "2", "3") or some unique identifier (e.g. "classic"). + pub fork_id: Option, + /// If true, the chain uses the GrandPa networking protocol. pub has_grandpa_protocol: bool, } @@ -153,6 +158,7 @@ impl NetworkService { None }, protocol_id: chain.protocol_id.clone(), + fork_id: chain.fork_id.clone(), best_hash: chain.best_block.1, best_number: chain.best_block.0, genesis_hash: chain.genesis_block_hash, diff --git a/src/network/service.rs b/src/network/service.rs index 63f1c39f35..a531002b9a 100644 --- a/src/network/service.rs +++ b/src/network/service.rs @@ -24,12 +24,7 @@ use crate::libp2p::{ use crate::network::{kademlia, protocol}; use crate::util::{self, SipHasherBuild}; -use alloc::{ - borrow::Cow, - format, - string::{String, ToString as _}, - vec::Vec, -}; +use alloc::{borrow::Cow, format, string::String, vec::Vec}; use core::{ fmt, iter, mem, num::NonZeroUsize, @@ -119,6 +114,12 @@ pub struct ChainConfig { /// > "chain spec"). pub protocol_id: String, + /// Optional fork identifier, used to differentiate between chains with the same genesis hash. + /// + /// > **Note**: This value is typically found in the specification of the chain (the + /// > "chain spec"). + pub fork_id: Option, + /// If `Some`, the chain uses the GrandPa networking protocol. pub grandpa_protocol_config: Option, @@ -277,12 +278,13 @@ where max_notification_size: 16 * 1024 * 1024, })) .chain({ - // The `has_grandpa_protocol` flag controls whether the chain uses GrandPa. - // Note, however, that GrandPa is technically left enabled (but unused) on all - // chains, in order to make the rest of the code of this module more - // comprehensible. iter::once(peers::NotificationProtocolConfig { - protocol_name: "/paritytech/grandpa/1".to_string(), + protocol_name: match &chain.fork_id { + Some(id) => { + format!("/{}/{}/grandpa/1", hex::encode(&chain.genesis_hash), id) + } + None => format!("/{}/grandpa/1", hex::encode(&chain.genesis_hash)), + }, fallback_protocol_names: Vec::new(), max_handshake_size: 4, max_notification_size: 1024 * 1024,