Skip to content

Commit 4f8176d

Browse files
authored
feat: /paras/{number}/inclusion (#1776)
* ParaInclusion controller * Controller exports * Add ParaInclusion services * chains config * cleanup service and types * Optimize, and add depth query param * docs * remove bad import * Update chains-config and adjust docs * Remove consoles * consolidate promises * Add notes on batch size * Combine searches for more performance * Fix inline comment
1 parent 35876cf commit 4f8176d

File tree

15 files changed

+428
-3
lines changed

15 files changed

+428
-3
lines changed

docs-v2/dist/bundle.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs-v2/openapi-v1.yaml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4412,6 +4412,52 @@ paths:
44124412
application/json:
44134413
schema:
44144414
$ref: '#/components/schemas/ParasHeaders'
4415+
/paras/{number}/inclusion:
4416+
get:
4417+
tags:
4418+
- paras
4419+
summary: Get relay chain inclusion information for a specific parachain block.
4420+
description: |
4421+
Returns the relay chain block number where a parachain block was included,
4422+
along with the relay parent number used during production. This endpoint helps
4423+
track the lifecycle of parachain blocks from production to inclusion.
4424+
4425+
**Note**: This endpoint requires a multi-chain connection (both parachain and relay chain APIs).
4426+
parameters:
4427+
- name: number
4428+
in: path
4429+
description: Parachain block number to find inclusion information for.
4430+
required: true
4431+
schema:
4432+
type: string
4433+
format: unsignedInteger
4434+
- name: depth
4435+
in: query
4436+
description: Maximum number of relay chain blocks to search for inclusion (must be divisible by 5, max 100).
4437+
required: false
4438+
schema:
4439+
type: integer
4440+
minimum: 5
4441+
maximum: 100
4442+
multipleOf: 5
4443+
default: 10
4444+
responses:
4445+
"200":
4446+
description: successful operation
4447+
content:
4448+
application/json:
4449+
schema:
4450+
$ref: '#/components/schemas/ParachainInclusion'
4451+
"400":
4452+
description: Invalid depth parameter
4453+
content:
4454+
application/json:
4455+
schema:
4456+
type: object
4457+
properties:
4458+
error:
4459+
type: string
4460+
example: "Depth parameter must be divisible by 5 for optimal performance."
44154461
/experimental/blocks/head/traces:
44164462
get:
44174463
tags:
@@ -6794,6 +6840,36 @@ components:
67946840
items:
67956841
$ref: '#/components/schemas/DigestItem'
67966842
description: Array of `DigestItem`s associated with the block.
6843+
ParachainInclusion:
6844+
type: object
6845+
properties:
6846+
parachainBlock:
6847+
type: integer
6848+
description: The parachain block number that was searched for.
6849+
parachainBlockHash:
6850+
type: string
6851+
format: hex
6852+
description: The hash of the parachain block.
6853+
parachainId:
6854+
type: integer
6855+
description: The parachain ID.
6856+
relayParentNumber:
6857+
type: integer
6858+
description: The relay chain block number used as parent during parachain block production.
6859+
inclusionNumber:
6860+
type: integer
6861+
nullable: true
6862+
description: The relay chain block number where the parachain block was included (null if not found).
6863+
found:
6864+
type: boolean
6865+
description: Whether the inclusion was found within the search depth.
6866+
required:
6867+
- parachainBlock
6868+
- parachainBlockHash
6869+
- parachainId
6870+
- relayParentNumber
6871+
- inclusionNumber
6872+
- found
67976873
ParasLeasesCurrent:
67986874
type: object
67996875
properties:

docs/dist/app.bundle.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/src/openapi-v1.yaml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4412,6 +4412,52 @@ paths:
44124412
application/json:
44134413
schema:
44144414
$ref: '#/components/schemas/ParasHeaders'
4415+
/paras/{number}/inclusion:
4416+
get:
4417+
tags:
4418+
- paras
4419+
summary: Get relay chain inclusion information for a specific parachain block.
4420+
description: |
4421+
Returns the relay chain block number where a parachain block was included,
4422+
along with the relay parent number used during production. This endpoint helps
4423+
track the lifecycle of parachain blocks from production to inclusion.
4424+
4425+
**Note**: This endpoint requires a multi-chain connection (both parachain and relay chain APIs).
4426+
parameters:
4427+
- name: number
4428+
in: path
4429+
description: Parachain block number to find inclusion information for.
4430+
required: true
4431+
schema:
4432+
type: string
4433+
format: unsignedInteger
4434+
- name: depth
4435+
in: query
4436+
description: Maximum number of relay chain blocks to search for inclusion (must be divisible by 5, max 100).
4437+
required: false
4438+
schema:
4439+
type: integer
4440+
minimum: 5
4441+
maximum: 100
4442+
multipleOf: 5
4443+
default: 10
4444+
responses:
4445+
"200":
4446+
description: successful operation
4447+
content:
4448+
application/json:
4449+
schema:
4450+
$ref: '#/components/schemas/ParachainInclusion'
4451+
"400":
4452+
description: Invalid depth parameter
4453+
content:
4454+
application/json:
4455+
schema:
4456+
type: object
4457+
properties:
4458+
error:
4459+
type: string
4460+
example: "Depth parameter must be divisible by 5 for optimal performance."
44154461
/experimental/blocks/head/traces:
44164462
get:
44174463
tags:
@@ -6794,6 +6840,36 @@ components:
67946840
items:
67956841
$ref: '#/components/schemas/DigestItem'
67966842
description: Array of `DigestItem`s associated with the block.
6843+
ParachainInclusion:
6844+
type: object
6845+
properties:
6846+
parachainBlock:
6847+
type: integer
6848+
description: The parachain block number that was searched for.
6849+
parachainBlockHash:
6850+
type: string
6851+
format: hex
6852+
description: The hash of the parachain block.
6853+
parachainId:
6854+
type: integer
6855+
description: The parachain ID.
6856+
relayParentNumber:
6857+
type: integer
6858+
description: The relay chain block number used as parent during parachain block production.
6859+
inclusionNumber:
6860+
type: integer
6861+
nullable: true
6862+
description: The relay chain block number where the parachain block was included (null if not found).
6863+
found:
6864+
type: boolean
6865+
description: Whether the inclusion was found within the search depth.
6866+
required:
6867+
- parachainBlock
6868+
- parachainBlockHash
6869+
- parachainId
6870+
- relayParentNumber
6871+
- inclusionNumber
6872+
- found
67976873
ParasLeasesCurrent:
67986874
type: object
67996875
properties:

src/chains-config/assetHubKusamaControllers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export const assetHubKusamaControllers: ControllerConfig = {
3939
'PalletsErrors',
4040
'PalletsEvents',
4141
'PalletsForeignAssets',
42+
'ParasInclusion',
4243
'RcAccountsBalanceInfo',
4344
'RcAccountsProxyInfo',
4445
'RcAccountsStakingInfo',

src/chains-config/assetHubNextWestendControllers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export const assetHubNextWestendControllers: ControllerConfig = {
5050
'PalletsStakingValidators',
5151
'PalletsStorage',
5252
'PalletsPoolAssets',
53+
'ParasInclusion',
5354
'RcAccountsBalanceInfo',
5455
'RcAccountsProxyInfo',
5556
'RcAccountsStakingInfo',

src/chains-config/assetHubPolkadotControllers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export const assetHubPolkadotControllers: ControllerConfig = {
4141
'PalletsEvents',
4242
'PalletsErrors',
4343
'PalletsForeignAssets',
44+
'ParasInclusion',
4445
'RcAccountsBalanceInfo',
4546
'RcAccountsProxyInfo',
4647
'RcAccountsStakingInfo',

src/chains-config/assetHubWestendControllers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export const assetHubWestendControllers: ControllerConfig = {
5050
'RcPalletsStakingProgress',
5151
'PalletsStorage',
5252
'PalletsPoolAssets',
53+
'ParasInclusion',
5354
'RcAccountsBalanceInfo',
5455
'RcAccountsProxyInfo',
5556
'RcAccountsStakingInfo',

src/controllers/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import {
4646
PalletsStakingValidators,
4747
PalletsStorage,
4848
} from './pallets';
49-
import { Paras } from './paras';
49+
import { Paras, ParasInclusion } from './paras';
5050
import {
5151
RcAccountsBalanceInfo,
5252
RcAccountsProxyInfo,
@@ -136,6 +136,7 @@ export const controllers = {
136136
TransactionMaterial,
137137
TransactionSubmit,
138138
Paras,
139+
ParasInclusion,
139140
CoretimeGeneric,
140141
CoretimeChain,
141142
};
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright 2017-2025 Parity Technologies (UK) Ltd.
2+
// This file is part of Substrate API Sidecar.
3+
//
4+
// Substrate API Sidecar is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
import { u32 } from '@polkadot/types-codec';
18+
import { RequestHandler } from 'express';
19+
20+
import { ParasInclusionService } from '../../services';
21+
import { INumberParam } from '../../types/requests';
22+
import AbstractController from '../AbstractController';
23+
24+
export default class ParasInclusionController extends AbstractController<ParasInclusionService> {
25+
static controllerName = 'ParasInclusion';
26+
static requiredPallets = [['parachainInfo']];
27+
28+
constructor(api: string) {
29+
super(api, '', new ParasInclusionService(api));
30+
this.initRoutes();
31+
}
32+
33+
protected initRoutes(): void {
34+
this.safeMountAsyncGetHandlers([['/paras/:number/inclusion', this.getParachainInclusion]]);
35+
}
36+
37+
/**
38+
* Get inclusion information for a specific parachain block.
39+
*
40+
* @param number - The parachain block number
41+
* @param at - Optional relay chain block hash to search from
42+
* @param depth - Optional search depth (must be divisible by 5, defaults to 10)
43+
*/
44+
private getParachainInclusion: RequestHandler<INumberParam> = async (
45+
{ params: { number }, query: { depth } },
46+
res,
47+
): Promise<void> => {
48+
const [hash, paraId] = await Promise.all([
49+
this.getHashFromAt(number),
50+
this.api.query.parachainInfo.parachainId<u32>(),
51+
]);
52+
53+
// Validate and parse depth parameter
54+
let searchDepth = 10; // default
55+
if (depth) {
56+
const parsedDepth = parseInt(depth as string, 10);
57+
if (isNaN(parsedDepth) || parsedDepth <= 0) {
58+
ParasInclusionController.sanitizedSend(res, { error: 'Invalid depth parameter. Must be a positive integer.' });
59+
return;
60+
}
61+
if (parsedDepth % 5 !== 0) {
62+
ParasInclusionController.sanitizedSend(res, {
63+
error: 'Depth parameter must be divisible by 5 for optimal performance.',
64+
});
65+
return;
66+
}
67+
if (parsedDepth > 100) {
68+
ParasInclusionController.sanitizedSend(res, {
69+
error: 'Depth parameter cannot exceed 100 to prevent excessive network requests.',
70+
});
71+
return;
72+
}
73+
searchDepth = parsedDepth;
74+
}
75+
76+
ParasInclusionController.sanitizedSend(
77+
res,
78+
await this.service.getParachainInclusion(hash, paraId, number, searchDepth),
79+
);
80+
};
81+
}

0 commit comments

Comments
 (0)