Integrate litep2p into Polkadot SDK (#2944)

[litep2p](https://github.com/altonen/litep2p) is a libp2p-compatible P2P
networking library. It supports all of the features of `rust-libp2p`
that are currently being utilized by Polkadot SDK.

Compared to `rust-libp2p`, `litep2p` has a quite different architecture
which is why the new `litep2p` network backend is only able to use a
little of the existing code in `sc-network`. The design has been mainly
influenced by how we'd wish to structure our networking-related code in
Polkadot SDK: independent higher-levels protocols directly communicating
with the network over links that support bidirectional backpressure. A
good example would be `NotificationHandle`/`RequestResponseHandle`
abstractions which allow, e.g., `SyncingEngine` to directly communicate
with peers to announce/request blocks.

I've tried running `polkadot --network-backend litep2p` with a few
different peer configurations and there is a noticeable reduction in
networking CPU usage. For high load (`--out-peers 200`), networking CPU
usage goes down from ~110% to ~30% (80 pp) and for normal load
(`--out-peers 40`), the usage goes down from ~55% to ~18% (37 pp).

These should not be taken as final numbers because:

a) there are still some low-hanging optimization fruits, such as
enabling [receive window
auto-tuning](https://github.com/libp2p/rust-yamux/pull/176), integrating
`Peerset` more closely with `litep2p` or improving memory usage of the
WebSocket transport
b) fixing bugs/instabilities that incorrectly cause `litep2p` to do less
work will increase the networking CPU usage
c) verification in a more diverse set of tests/conditions is needed

Nevertheless, these numbers should give an early estimate for CPU usage
of the new networking backend.

This PR consists of three separate changes:
* introduce a generic `PeerId` (wrapper around `Multihash`) so that we
don't have use `NetworkService::PeerId` in every part of the code that
uses a `PeerId`
* introduce `NetworkBackend` trait, implement it for the libp2p network
stack and make Polkadot SDK generic over `NetworkBackend`
  * implement `NetworkBackend` for litep2p

The new library should be considered experimental which is why
`rust-libp2p` will remain as the default option for the time being. This
PR currently depends on the master branch of `litep2p` but I'll cut a
new release for the library once all review comments have been
addresses.

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Co-authored-by: Dmitry Markin <dmitry@markin.tech>
Co-authored-by: Alexandru Vasile <60601340+lexnv@users.noreply.github.com>
Co-authored-by: Alexandru Vasile <alexandru.vasile@parity.io>
This commit is contained in:
Aaro Altonen
2024-04-08 19:44:13 +03:00
committed by GitHub
parent 9543d31474
commit 80616f6d03
181 changed files with 11055 additions and 1862 deletions
+213 -129
View File
@@ -21,7 +21,7 @@ use crate::{
fake_runtime_api::{
asset_hub_polkadot_aura::RuntimeApi as AssetHubPolkadotRuntimeApi, aura::RuntimeApi,
},
service::{new_partial, Block},
service::{new_partial, Block, Hash},
};
use cumulus_client_service::storage_proof_size::HostFunctions as ReclaimHostFunctions;
use cumulus_primitives_core::ParaId;
@@ -498,7 +498,6 @@ macro_rules! construct_async_run {
/// Parse command line arguments into service configuration.
pub fn run() -> Result<()> {
use Runtime::*;
let cli = Cli::from_args();
match &cli.subcommand {
@@ -670,151 +669,236 @@ pub fn run() -> Result<()> {
info!("Parachain Account: {}", parachain_account);
info!("Is collating: {}", if config.role.is_authority() { "yes" } else { "no" });
match config.chain_spec.runtime()? {
AssetHubPolkadot => crate::service::start_asset_hub_node::<
AssetHubPolkadotRuntimeApi,
AssetHubPolkadotAuraId,
>(config, polkadot_config, collator_options, id, hwbench)
.await
.map(|r| r.0)
.map_err(Into::into),
AssetHubKusama =>
crate::service::start_asset_hub_node::<
RuntimeApi,
AuraId,
>(config, polkadot_config, collator_options, id, hwbench)
.await
.map(|r| r.0)
.map_err(Into::into),
AssetHubRococo | AssetHubWestend =>
crate::service::start_asset_hub_lookahead_node::<
RuntimeApi,
AuraId,
>(config, polkadot_config, collator_options, id, hwbench)
.await
.map(|r| r.0)
.map_err(Into::into),
CollectivesPolkadot =>
crate::service::start_generic_aura_node(config, polkadot_config, collator_options, id, hwbench)
.await
.map(|r| r.0)
.map_err(Into::into),
CollectivesWestend =>
crate::service::start_generic_aura_lookahead_node(config, polkadot_config, collator_options, id, hwbench)
.await
.map(|r| r.0)
.map_err(Into::into),
Seedling | Shell =>
crate::service::start_shell_node(
match polkadot_config.network.network_backend {
sc_network::config::NetworkBackendType::Libp2p =>
start_node::<sc_network::NetworkWorker<_, _>>(
config,
polkadot_config,
collator_options,
id,
hwbench,
)
.await
.map(|r| r.0)
.map_err(Into::into),
ContractsRococo => crate::service::start_contracts_rococo_node(
config,
polkadot_config,
collator_options,
id,
hwbench,
)
.await
.map(|r| r.0)
.map_err(Into::into),
BridgeHub(bridge_hub_runtime_type) => match bridge_hub_runtime_type {
chain_spec::bridge_hubs::BridgeHubRuntimeType::Polkadot |
chain_spec::bridge_hubs::BridgeHubRuntimeType::PolkadotLocal =>
crate::service::start_generic_aura_node(config, polkadot_config, collator_options, id, hwbench)
.await
.map(|r| r.0),
chain_spec::bridge_hubs::BridgeHubRuntimeType::Kusama |
chain_spec::bridge_hubs::BridgeHubRuntimeType::KusamaLocal =>
crate::service::start_generic_aura_node(config, polkadot_config, collator_options, id, hwbench)
.await
.map(|r| r.0),
chain_spec::bridge_hubs::BridgeHubRuntimeType::Westend |
chain_spec::bridge_hubs::BridgeHubRuntimeType::WestendLocal |
chain_spec::bridge_hubs::BridgeHubRuntimeType::WestendDevelopment =>
crate::service::start_generic_aura_lookahead_node(config, polkadot_config, collator_options, id, hwbench)
.await
.map(|r| r.0),
chain_spec::bridge_hubs::BridgeHubRuntimeType::Rococo |
chain_spec::bridge_hubs::BridgeHubRuntimeType::RococoLocal |
chain_spec::bridge_hubs::BridgeHubRuntimeType::RococoDevelopment =>
crate::service::start_generic_aura_lookahead_node(config, polkadot_config, collator_options, id, hwbench)
.await
.map(|r| r.0),
}
.map_err(Into::into),
Coretime(coretime_runtime_type) => match coretime_runtime_type {
chain_spec::coretime::CoretimeRuntimeType::Kusama |
chain_spec::coretime::CoretimeRuntimeType::KusamaLocal |
chain_spec::coretime::CoretimeRuntimeType::Polkadot |
chain_spec::coretime::CoretimeRuntimeType::PolkadotLocal |
chain_spec::coretime::CoretimeRuntimeType::Rococo |
chain_spec::coretime::CoretimeRuntimeType::RococoLocal |
chain_spec::coretime::CoretimeRuntimeType::RococoDevelopment |
chain_spec::coretime::CoretimeRuntimeType::Westend |
chain_spec::coretime::CoretimeRuntimeType::WestendLocal |
chain_spec::coretime::CoretimeRuntimeType::WestendDevelopment =>
crate::service::start_generic_aura_lookahead_node(config, polkadot_config, collator_options, id, hwbench)
.await
.map(|r| r.0),
}
.map_err(Into::into),
Penpal(_) | Default =>
crate::service::start_rococo_parachain_node(
.await,
sc_network::config::NetworkBackendType::Litep2p =>
start_node::<sc_network::Litep2pNetworkBackend>(
config,
polkadot_config,
collator_options,
id,
hwbench,
)
.await
.map(|r| r.0)
.map_err(Into::into),
Glutton | GluttonWestend =>
crate::service::start_basic_lookahead_node(config, polkadot_config, collator_options, id, hwbench)
.await
.map(|r| r.0)
.map_err(Into::into),
People(people_runtime_type) => match people_runtime_type {
chain_spec::people::PeopleRuntimeType::Kusama |
chain_spec::people::PeopleRuntimeType::KusamaLocal |
chain_spec::people::PeopleRuntimeType::Polkadot |
chain_spec::people::PeopleRuntimeType::PolkadotLocal |
chain_spec::people::PeopleRuntimeType::Rococo |
chain_spec::people::PeopleRuntimeType::RococoLocal |
chain_spec::people::PeopleRuntimeType::RococoDevelopment |
chain_spec::people::PeopleRuntimeType::Westend |
chain_spec::people::PeopleRuntimeType::WestendLocal |
chain_spec::people::PeopleRuntimeType::WestendDevelopment =>
crate::service::start_generic_aura_lookahead_node(config, polkadot_config, collator_options, id, hwbench)
.await
.map(|r| r.0),
}
.map_err(Into::into),
.await,
}
})
},
}
}
async fn start_node<Network: sc_network::NetworkBackend<Block, Hash>>(
config: sc_service::Configuration,
polkadot_config: sc_service::Configuration,
collator_options: cumulus_client_cli::CollatorOptions,
id: ParaId,
hwbench: Option<sc_sysinfo::HwBench>,
) -> Result<sc_service::TaskManager> {
match config.chain_spec.runtime()? {
Runtime::AssetHubPolkadot => crate::service::start_asset_hub_node::<
AssetHubPolkadotRuntimeApi,
AssetHubPolkadotAuraId,
Network,
>(config, polkadot_config, collator_options, id, hwbench)
.await
.map(|r| r.0)
.map_err(Into::into),
Runtime::AssetHubKusama => crate::service::start_asset_hub_node::<
RuntimeApi,
AuraId,
Network,
>(config, polkadot_config, collator_options, id, hwbench)
.await
.map(|r| r.0)
.map_err(Into::into),
Runtime::AssetHubRococo | Runtime::AssetHubWestend =>
crate::service::start_asset_hub_lookahead_node::<RuntimeApi, AuraId, Network>(
config,
polkadot_config,
collator_options,
id,
hwbench,
)
.await
.map(|r| r.0)
.map_err(Into::into),
Runtime::CollectivesPolkadot => crate::service::start_generic_aura_node::<Network>(
config,
polkadot_config,
collator_options,
id,
hwbench,
)
.await
.map(|r| r.0)
.map_err(Into::into),
Runtime::CollectivesWestend =>
crate::service::start_generic_aura_lookahead_node::<Network>(
config,
polkadot_config,
collator_options,
id,
hwbench,
)
.await
.map(|r| r.0)
.map_err(Into::into),
Runtime::Seedling | Runtime::Shell => crate::service::start_shell_node::<Network>(
config,
polkadot_config,
collator_options,
id,
hwbench,
)
.await
.map(|r| r.0)
.map_err(Into::into),
Runtime::ContractsRococo => crate::service::start_contracts_rococo_node::<Network>(
config,
polkadot_config,
collator_options,
id,
hwbench,
)
.await
.map(|r| r.0)
.map_err(Into::into),
Runtime::BridgeHub(bridge_hub_runtime_type) => match bridge_hub_runtime_type {
chain_spec::bridge_hubs::BridgeHubRuntimeType::Polkadot |
chain_spec::bridge_hubs::BridgeHubRuntimeType::PolkadotLocal =>
crate::service::start_generic_aura_node::<Network>(
config,
polkadot_config,
collator_options,
id,
hwbench,
)
.await
.map(|r| r.0),
chain_spec::bridge_hubs::BridgeHubRuntimeType::Kusama |
chain_spec::bridge_hubs::BridgeHubRuntimeType::KusamaLocal =>
crate::service::start_generic_aura_node::<Network>(
config,
polkadot_config,
collator_options,
id,
hwbench,
)
.await
.map(|r| r.0),
chain_spec::bridge_hubs::BridgeHubRuntimeType::Westend |
chain_spec::bridge_hubs::BridgeHubRuntimeType::WestendLocal |
chain_spec::bridge_hubs::BridgeHubRuntimeType::WestendDevelopment =>
crate::service::start_generic_aura_lookahead_node::<Network>(
config,
polkadot_config,
collator_options,
id,
hwbench,
)
.await
.map(|r| r.0),
chain_spec::bridge_hubs::BridgeHubRuntimeType::Rococo |
chain_spec::bridge_hubs::BridgeHubRuntimeType::RococoLocal |
chain_spec::bridge_hubs::BridgeHubRuntimeType::RococoDevelopment =>
crate::service::start_generic_aura_lookahead_node::<Network>(
config,
polkadot_config,
collator_options,
id,
hwbench,
)
.await
.map(|r| r.0),
}
.map_err(Into::into),
Runtime::Coretime(coretime_runtime_type) => match coretime_runtime_type {
chain_spec::coretime::CoretimeRuntimeType::Kusama |
chain_spec::coretime::CoretimeRuntimeType::KusamaLocal |
chain_spec::coretime::CoretimeRuntimeType::Polkadot |
chain_spec::coretime::CoretimeRuntimeType::PolkadotLocal |
chain_spec::coretime::CoretimeRuntimeType::Rococo |
chain_spec::coretime::CoretimeRuntimeType::RococoLocal |
chain_spec::coretime::CoretimeRuntimeType::RococoDevelopment |
chain_spec::coretime::CoretimeRuntimeType::Westend |
chain_spec::coretime::CoretimeRuntimeType::WestendLocal |
chain_spec::coretime::CoretimeRuntimeType::WestendDevelopment =>
crate::service::start_generic_aura_lookahead_node::<Network>(
config,
polkadot_config,
collator_options,
id,
hwbench,
)
.await
.map(|r| r.0),
}
.map_err(Into::into),
Runtime::Penpal(_) | Runtime::Default =>
crate::service::start_rococo_parachain_node::<Network>(
config,
polkadot_config,
collator_options,
id,
hwbench,
)
.await
.map(|r| r.0)
.map_err(Into::into),
Runtime::Glutton | Runtime::GluttonWestend =>
crate::service::start_basic_lookahead_node::<Network>(
config,
polkadot_config,
collator_options,
id,
hwbench,
)
.await
.map(|r| r.0)
.map_err(Into::into),
Runtime::People(people_runtime_type) => match people_runtime_type {
chain_spec::people::PeopleRuntimeType::Kusama |
chain_spec::people::PeopleRuntimeType::KusamaLocal |
chain_spec::people::PeopleRuntimeType::Polkadot |
chain_spec::people::PeopleRuntimeType::PolkadotLocal |
chain_spec::people::PeopleRuntimeType::Rococo |
chain_spec::people::PeopleRuntimeType::RococoLocal |
chain_spec::people::PeopleRuntimeType::RococoDevelopment |
chain_spec::people::PeopleRuntimeType::Westend |
chain_spec::people::PeopleRuntimeType::WestendLocal |
chain_spec::people::PeopleRuntimeType::WestendDevelopment =>
crate::service::start_generic_aura_lookahead_node::<Network>(
config,
polkadot_config,
collator_options,
id,
hwbench,
)
.await
.map(|r| r.0),
}
.map_err(Into::into),
}
}
impl DefaultConfigurationValues for RelayChainCli {
fn p2p_listen_port() -> u16 {
30334
+26 -19
View File
@@ -51,7 +51,7 @@ use sc_consensus::{
BlockImportParams, ImportQueue,
};
use sc_executor::{HeapAllocStrategy, WasmExecutor, DEFAULT_HEAP_ALLOC_STRATEGY};
use sc_network::{config::FullNetworkConfiguration, NetworkBlock};
use sc_network::{config::FullNetworkConfiguration, service::traits::NetworkBackend, NetworkBlock};
use sc_network_sync::SyncingService;
use sc_service::{Configuration, PartialComponents, TFullBackend, TFullClient, TaskManager};
use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle};
@@ -191,7 +191,7 @@ where
///
/// This is the actual implementation that is abstract over the executor and the runtime api.
#[sc_tracing::logging::prefix_logs_with("Parachain")]
async fn start_node_impl<RuntimeApi, RB, BIQ, SC>(
async fn start_node_impl<RuntimeApi, RB, BIQ, SC, Net>(
parachain_config: Configuration,
polkadot_config: Configuration,
collator_options: CollatorOptions,
@@ -244,6 +244,7 @@ where
Arc<dyn Fn(Hash, Option<Vec<u8>>) + Send + Sync>,
Arc<ParachainBackend>,
) -> Result<(), sc_service::Error>,
Net: NetworkBackend<Block, Hash>,
{
let parachain_config = prepare_node_config(parachain_config);
@@ -269,7 +270,7 @@ where
let prometheus_registry = parachain_config.prometheus_registry().cloned();
let transaction_pool = params.transaction_pool.clone();
let import_queue_service = params.import_queue.service();
let net_config = FullNetworkConfiguration::new(&parachain_config.network);
let net_config = FullNetworkConfiguration::<_, _, Net>::new(&parachain_config.network);
let (network, system_rpc_tx, tx_handler_controller, start_network, sync_service) =
build_network(BuildNetworkParams {
@@ -423,14 +424,14 @@ pub fn build_aura_import_queue(
}
/// Start a rococo parachain node.
pub async fn start_rococo_parachain_node(
pub async fn start_rococo_parachain_node<Net: NetworkBackend<Block, Hash>>(
parachain_config: Configuration,
polkadot_config: Configuration,
collator_options: CollatorOptions,
para_id: ParaId,
hwbench: Option<sc_sysinfo::HwBench>,
) -> sc_service::error::Result<(TaskManager, Arc<ParachainClient<FakeRuntimeApi>>)> {
start_node_impl::<FakeRuntimeApi, _, _, _>(
start_node_impl::<FakeRuntimeApi, _, _, _, Net>(
parachain_config,
polkadot_config,
collator_options,
@@ -492,14 +493,14 @@ fn build_contracts_rpc_extensions(
}
/// Start a polkadot-shell parachain node.
pub async fn start_shell_node(
pub async fn start_shell_node<Net: NetworkBackend<Block, Hash>>(
parachain_config: Configuration,
polkadot_config: Configuration,
collator_options: CollatorOptions,
para_id: ParaId,
hwbench: Option<sc_sysinfo::HwBench>,
) -> sc_service::error::Result<(TaskManager, Arc<ParachainClient<FakeRuntimeApi>>)> {
start_node_impl::<FakeRuntimeApi, _, _, _>(
start_node_impl::<FakeRuntimeApi, _, _, _, Net>(
parachain_config,
polkadot_config,
collator_options,
@@ -687,14 +688,14 @@ where
}
/// Start an aura powered parachain node. Some system chains use this.
pub async fn start_generic_aura_node(
pub async fn start_generic_aura_node<Net: NetworkBackend<Block, Hash>>(
parachain_config: Configuration,
polkadot_config: Configuration,
collator_options: CollatorOptions,
para_id: ParaId,
hwbench: Option<sc_sysinfo::HwBench>,
) -> sc_service::error::Result<(TaskManager, Arc<ParachainClient<FakeRuntimeApi>>)> {
start_node_impl::<FakeRuntimeApi, _, _, _>(
start_node_impl::<FakeRuntimeApi, _, _, _, Net>(
parachain_config,
polkadot_config,
collator_options,
@@ -768,14 +769,14 @@ pub async fn start_generic_aura_node(
/// Uses the lookahead collator to support async backing.
///
/// Start an aura powered parachain node. Some system chains use this.
pub async fn start_generic_aura_lookahead_node(
pub async fn start_generic_aura_lookahead_node<Net: NetworkBackend<Block, Hash>>(
parachain_config: Configuration,
polkadot_config: Configuration,
collator_options: CollatorOptions,
para_id: ParaId,
hwbench: Option<sc_sysinfo::HwBench>,
) -> sc_service::error::Result<(TaskManager, Arc<ParachainClient<FakeRuntimeApi>>)> {
start_node_impl::<FakeRuntimeApi, _, _, _>(
start_node_impl::<FakeRuntimeApi, _, _, _, Net>(
parachain_config,
polkadot_config,
collator_options,
@@ -792,7 +793,7 @@ pub async fn start_generic_aura_lookahead_node(
/// Start a shell node which should later transition into an Aura powered parachain node. Asset Hub
/// uses this because at genesis, Asset Hub was on the `shell` runtime which didn't have Aura and
/// needs to sync and upgrade before it can run `AuraApi` functions.
pub async fn start_asset_hub_node<RuntimeApi, AuraId: AppCrypto + Send + Codec + Sync>(
pub async fn start_asset_hub_node<RuntimeApi, AuraId: AppCrypto + Send + Codec + Sync, Net>(
parachain_config: Configuration,
polkadot_config: Configuration,
collator_options: CollatorOptions,
@@ -813,8 +814,9 @@ where
+ frame_rpc_system::AccountNonceApi<Block, AccountId, Nonce>,
<<AuraId as AppCrypto>::Pair as Pair>::Signature:
TryFrom<Vec<u8>> + std::hash::Hash + sp_runtime::traits::Member + Codec,
Net: NetworkBackend<Block, Hash>,
{
start_node_impl::<RuntimeApi, _, _, _>(
start_node_impl::<RuntimeApi, _, _, _, Net>(
parachain_config,
polkadot_config,
collator_options,
@@ -940,7 +942,11 @@ where
///
/// Uses the lookahead collator to support async backing.
#[sc_tracing::logging::prefix_logs_with("Parachain")]
pub async fn start_asset_hub_lookahead_node<RuntimeApi, AuraId: AppCrypto + Send + Codec + Sync>(
pub async fn start_asset_hub_lookahead_node<
RuntimeApi,
AuraId: AppCrypto + Send + Codec + Sync,
Net,
>(
parachain_config: Configuration,
polkadot_config: Configuration,
collator_options: CollatorOptions,
@@ -962,8 +968,9 @@ where
+ cumulus_primitives_aura::AuraUnincludedSegmentApi<Block>,
<<AuraId as AppCrypto>::Pair as Pair>::Signature:
TryFrom<Vec<u8>> + std::hash::Hash + sp_runtime::traits::Member + Codec,
Net: NetworkBackend<Block, Hash>,
{
start_node_impl::<RuntimeApi, _, _, _>(
start_node_impl::<RuntimeApi, _, _, _, Net>(
parachain_config,
polkadot_config,
collator_options,
@@ -1213,14 +1220,14 @@ fn start_lookahead_aura_consensus(
/// Start an aura powered parachain node which uses the lookahead collator to support async backing.
/// This node is basic in the sense that its runtime api doesn't include common contents such as
/// transaction payment. Used for aura glutton.
pub async fn start_basic_lookahead_node(
pub async fn start_basic_lookahead_node<Net: NetworkBackend<Block, Hash>>(
parachain_config: Configuration,
polkadot_config: Configuration,
collator_options: CollatorOptions,
para_id: ParaId,
hwbench: Option<sc_sysinfo::HwBench>,
) -> sc_service::error::Result<(TaskManager, Arc<ParachainClient<FakeRuntimeApi>>)> {
start_node_impl::<FakeRuntimeApi, _, _, _>(
start_node_impl::<FakeRuntimeApi, _, _, _, Net>(
parachain_config,
polkadot_config,
collator_options,
@@ -1235,14 +1242,14 @@ pub async fn start_basic_lookahead_node(
}
/// Start a parachain node for Rococo Contracts.
pub async fn start_contracts_rococo_node(
pub async fn start_contracts_rococo_node<Net: NetworkBackend<Block, Hash>>(
parachain_config: Configuration,
polkadot_config: Configuration,
collator_options: CollatorOptions,
para_id: ParaId,
hwbench: Option<sc_sysinfo::HwBench>,
) -> sc_service::error::Result<(TaskManager, Arc<ParachainClient<FakeRuntimeApi>>)> {
start_node_impl::<FakeRuntimeApi, _, _, _>(
start_node_impl::<FakeRuntimeApi, _, _, _, Net>(
parachain_config,
polkadot_config,
collator_options,