|
| 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