Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,10 @@ impl RuntimeApiSubsystemClient for BlockChainRpcClient {
async fn validation_code_bomb_limit(&self, at: Hash) -> Result<u32, sp_api::ApiError> {
Ok(self.rpc_client.parachain_host_validation_code_bomb_limit(at).await?)
}

async fn para_ids(&self, at: Hash) -> Result<Vec<ParaId>, sp_api::ApiError> {
Ok(self.rpc_client.parachain_host_para_ids(at).await?)
}
}

#[async_trait::async_trait]
Expand Down
8 changes: 8 additions & 0 deletions cumulus/client/relay-chain-rpc-interface/src/rpc_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,14 @@ impl RelayChainRpcClient {
))?;
Ok(rx)
}

pub async fn parachain_host_para_ids(
&self,
at: RelayHash,
) -> Result<Vec<ParaId>, RelayChainError> {
self.call_remote_runtime_function("ParachainHost_para_ids", at, None::<()>)
.await
}
}

/// Send `header` through all channels contained in `senders`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use emulated_integration_tests_common::{

// Rococo declaration
decl_test_relay_chains! {
#[api_version(13)]
#[api_version(14)]
pub struct Rococo {
genesis = genesis::genesis(),
on_init = (),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use emulated_integration_tests_common::{

// Westend declaration
decl_test_relay_chains! {
#[api_version(13)]
#[api_version(14)]
pub struct Westend {
genesis = genesis::genesis(),
on_init = (),
Expand Down
11 changes: 11 additions & 0 deletions polkadot/node/core/runtime-api/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ pub(crate) struct RequestResultCache {
backing_constraints: LruMap<(Hash, ParaId), Option<Constraints>>,
scheduling_lookahead: LruMap<SessionIndex, u32>,
validation_code_bomb_limits: LruMap<SessionIndex, u32>,
para_ids: LruMap<SessionIndex, Vec<ParaId>>,
}

impl Default for RequestResultCache {
Expand Down Expand Up @@ -118,6 +119,7 @@ impl Default for RequestResultCache {
backing_constraints: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
scheduling_lookahead: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
validation_code_bomb_limits: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
para_ids: LruMap::new(ByLength::new(DEFAULT_CACHE_CAP)),
}
}
}
Expand Down Expand Up @@ -602,6 +604,14 @@ impl RequestResultCache {
pub(crate) fn validation_code_bomb_limit(&mut self, session: SessionIndex) -> Option<u32> {
self.validation_code_bomb_limits.get(&session).copied()
}

pub(crate) fn para_ids(&mut self, session_index: SessionIndex) -> Option<&Vec<ParaId>> {
self.para_ids.get(&session_index).map(|v| &*v)
}

pub(crate) fn cache_para_ids(&mut self, session_index: SessionIndex, value: Vec<ParaId>) {
self.para_ids.insert(session_index, value);
}
}

pub(crate) enum RequestResult {
Expand Down Expand Up @@ -655,4 +665,5 @@ pub(crate) enum RequestResult {
BackingConstraints(Hash, ParaId, Option<Constraints>),
SchedulingLookahead(SessionIndex, u32),
ValidationCodeBombLimit(SessionIndex, u32),
ParaIds(SessionIndex, Vec<ParaId>),
}
19 changes: 19 additions & 0 deletions polkadot/node/core/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ where
.cache_scheduling_lookahead(session_index, scheduling_lookahead),
ValidationCodeBombLimit(session_index, limit) =>
self.requests_cache.cache_validation_code_bomb_limit(session_index, limit),
ParaIds(session_index, para_ids) => {
self.requests_cache.cache_para_ids(session_index, para_ids);
},
}
}

Expand Down Expand Up @@ -368,6 +371,15 @@ where
Some(Request::ValidationCodeBombLimit(index, sender))
}
},
Request::ParaIds(index, sender) => {
if let Some(value) = self.requests_cache.para_ids(index) {
self.metrics.on_cached_request();
let _ = sender.send(Ok(value.clone()));
None
} else {
Some(Request::ParaIds(index, sender))
}
},
}
}

Expand Down Expand Up @@ -702,5 +714,12 @@ where
sender,
result = (index)
),
Request::ParaIds(index, sender) => query!(
ParaIds,
para_ids(),
ver = Request::PARAIDS_RUNTIME_REQUIREMENT,
sender,
result = (index)
),
}
}
4 changes: 4 additions & 0 deletions polkadot/node/core/runtime-api/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,10 @@ impl RuntimeApiSubsystemClient for MockSubsystemClient {
async fn validation_code_bomb_limit(&self, _: Hash) -> Result<u32, ApiError> {
todo!("Not required for tests")
}

async fn para_ids(&self, _: Hash) -> Result<Vec<ParaId>, ApiError> {
todo!("Not required for tests")
}
}

#[test]
Expand Down
6 changes: 6 additions & 0 deletions polkadot/node/subsystem-types/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,9 @@ pub enum RuntimeApiRequest {
/// Get the maximum uncompressed code size.
/// `V12`
ValidationCodeBombLimit(SessionIndex, RuntimeApiSender<u32>),
/// Get the paraids at the relay parent.
/// `V14`
ParaIds(SessionIndex, RuntimeApiSender<Vec<ParaId>>),
Copy link
Copy Markdown
Contributor Author

@Sajjon Sajjon Jul 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nevermind

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

}

impl RuntimeApiRequest {
Expand Down Expand Up @@ -830,6 +833,9 @@ impl RuntimeApiRequest {

/// `SchedulingLookahead`
pub const SCHEDULING_LOOKAHEAD_RUNTIME_REQUIREMENT: u32 = 13;

/// `ParaIds`
pub const PARAIDS_RUNTIME_REQUIREMENT: u32 = 14;
}

/// A message to the Runtime API subsystem.
Expand Down
8 changes: 8 additions & 0 deletions polkadot/node/subsystem-types/src/runtime_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,10 @@ pub trait RuntimeApiSubsystemClient {
// === v12 ===
/// Fetch the maximum uncompressed code size.
async fn validation_code_bomb_limit(&self, at: Hash) -> Result<u32, ApiError>;

// == v14 ==
/// Fetch the list of all parachain IDs registered in the relay chain.
async fn para_ids(&self, at: Hash) -> Result<Vec<Id>, ApiError>;
}

/// Default implementation of [`RuntimeApiSubsystemClient`] using the client.
Expand Down Expand Up @@ -650,6 +654,10 @@ where
async fn validation_code_bomb_limit(&self, at: Hash) -> Result<u32, ApiError> {
self.client.runtime_api().validation_code_bomb_limit(at)
}

async fn para_ids(&self, at: Hash) -> Result<Vec<Id>, ApiError> {
self.client.runtime_api().para_ids(at)
}
}

impl<Client, Block> HeaderBackend<Block> for DefaultSubsystemClient<Client>
Expand Down
1 change: 1 addition & 0 deletions polkadot/node/subsystem-util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ specialize_requests! {
fn request_backing_constraints(para_id: ParaId) -> Option<Constraints>; BackingConstraints;
fn request_min_backing_votes(session_index: SessionIndex) -> u32; MinimumBackingVotes;
fn request_node_features(session_index: SessionIndex) -> NodeFeatures; NodeFeatures;
fn request_para_ids(session_index: SessionIndex) -> Vec<ParaId>; ParaIds;

}

Expand Down
4 changes: 4 additions & 0 deletions polkadot/primitives/src/runtime_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,10 @@ sp_api::decl_runtime_apis! {
#[api_version(13)]
fn scheduling_lookahead() -> u32;

/***** Added in v14 *****/
/// Retrieve paraids at relay parent
#[api_version(14)]
fn para_ids() -> Vec<ppp::Id>;

}
}
8 changes: 7 additions & 1 deletion polkadot/runtime/parachains/src/runtime_api_impl/vstaging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

//! Put implementations of functions from staging APIs here.

use crate::{configuration, initializer};
use crate::{configuration, initializer, paras};
use alloc::vec::Vec;

use frame_system::pallet_prelude::*;
use polkadot_primitives::{vstaging::async_backing::Constraints, Id as ParaId};

Expand Down Expand Up @@ -56,3 +58,7 @@ pub fn validation_code_bomb_limit<T: initializer::Config>() -> u32 {
configuration::ActiveConfig::<T>::get().max_code_size *
configuration::MAX_VALIDATION_CODE_COMPRESSION_RATIO
}

pub fn para_ids<T: initializer::Config>() -> Vec<ParaId> {
paras::Heads::<T>::iter_keys().collect()
}
6 changes: 5 additions & 1 deletion polkadot/runtime/rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2014,7 +2014,7 @@ sp_api::impl_runtime_apis! {
}
}

#[api_version(13)]
#[api_version(14)]
impl polkadot_primitives::runtime_api::ParachainHost<Block> for Runtime {
fn validators() -> Vec<ValidatorId> {
parachains_runtime_api_impl::validators::<Runtime>()
Expand Down Expand Up @@ -2192,6 +2192,10 @@ sp_api::impl_runtime_apis! {
fn validation_code_bomb_limit() -> u32 {
parachains_staging_runtime_api_impl::validation_code_bomb_limit::<Runtime>()
}

fn para_ids() -> Vec<ParaId> {
parachains_staging_runtime_api_impl::para_ids::<Runtime>()
}
}

#[api_version(5)]
Expand Down
6 changes: 5 additions & 1 deletion polkadot/runtime/test-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -965,7 +965,7 @@ sp_api::impl_runtime_apis! {
}
}

#[api_version(13)]
#[api_version(14)]
impl polkadot_primitives::runtime_api::ParachainHost<Block> for Runtime {
fn validators() -> Vec<ValidatorId> {
runtime_impl::validators::<Runtime>()
Expand Down Expand Up @@ -1140,6 +1140,10 @@ sp_api::impl_runtime_apis! {
fn validation_code_bomb_limit() -> u32 {
staging_runtime_impl::validation_code_bomb_limit::<Runtime>()
}

fn para_ids() -> Vec<ParaId> {
staging_runtime_impl::para_ids::<Runtime>()
}
}

impl sp_consensus_beefy::BeefyApi<Block, BeefyId> for Runtime {
Expand Down
6 changes: 5 additions & 1 deletion polkadot/runtime/westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2237,7 +2237,7 @@ sp_api::impl_runtime_apis! {
}
}

#[api_version(13)]
#[api_version(14)]
impl polkadot_primitives::runtime_api::ParachainHost<Block> for Runtime {
fn validators() -> Vec<ValidatorId> {
parachains_runtime_api_impl::validators::<Runtime>()
Expand Down Expand Up @@ -2415,6 +2415,10 @@ sp_api::impl_runtime_apis! {
fn validation_code_bomb_limit() -> u32 {
parachains_staging_runtime_api_impl::validation_code_bomb_limit::<Runtime>()
}

fn para_ids() -> Vec<ParaId> {
parachains_staging_runtime_api_impl::para_ids::<Runtime>()
}
}

#[api_version(5)]
Expand Down
32 changes: 32 additions & 0 deletions prdoc/pr_9055.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
title: Add `para_ids` Runtime API

doc:
- audience: "Node Dev"
description: |
Add a new runtime API for querying the registered paraids at a relay parent (both on-demand parachains and parachains).

This can be used for pruning the reputation database for the new collator protocol, so that we don't keep storing reputations indefinitely for parachains that have been offboarded.

crates:
- name: polkadot-node-core-runtime-api
bump: patch
- name: polkadot-primitives
bump: minor
- name: polkadot-runtime-parachains
bump: minor
- name: rococo-runtime
bump: minor
- name: westend-runtime
bump: minor
- name: polkadot-test-runtime
bump: minor
- name: pallet-staking-async-rc-runtime
bump: minor
- name: polkadot-node-subsystem-types
bump: major
- name: polkadot-node-subsystem-util
bump: minor
- name: cumulus-relay-chain-minimal-node
bump: minor
- name: cumulus-relay-chain-rpc-interface
bump: minor
6 changes: 5 additions & 1 deletion substrate/frame/staking-async/runtimes/rc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2070,7 +2070,7 @@ sp_api::impl_runtime_apis! {
}
}

#[api_version(13)]
#[api_version(14)]
impl polkadot_primitives::runtime_api::ParachainHost<Block> for Runtime {
fn validators() -> Vec<ValidatorId> {
parachains_runtime_api_impl::validators::<Runtime>()
Expand Down Expand Up @@ -2248,6 +2248,10 @@ sp_api::impl_runtime_apis! {
fn scheduling_lookahead() -> u32 {
parachains_staging_runtime_api_impl::scheduling_lookahead::<Runtime>()
}

fn para_ids() -> Vec<ParaId> {
parachains_staging_runtime_api_impl::para_ids::<Runtime>()
}
}

#[api_version(5)]
Expand Down