Skip to content

Commit

Permalink
feat: add decoded XCM data in blocks endpoint (#1364)
Browse files Browse the repository at this point in the history
* feat: add decoded xcm data in blocks endpoint

* add types to fix any lint errors

* update copyright year

* fix paraId filter for horizontal msgs

* fix xcm decoding for moonbeam horizontal msg

* add yarn.lock file

* update docs

* removed moonbeam package

* adding back yarn.lock

* changed variable to const

* retrieved yarn.lock from master branch

* added a test for decoding upward msg in polkadot block

* added test for decoding horizontal msg in KAH block

* updated cacheKey with query params of decodedXcmMsgs and paraId
- updated docs in blocks controller comments

* replaced mocked data of block 18207445 with those of block 18468942
- in block 18468942 we have 2 upward msgs from two different parachains so with the same mocked data we can add 2 tests
- added a test to check the query param paraId is working as expected

* replaced mocked data of block 5831776 with those of block 3356195
- in block 3356195 we have downward and horizontal msgs so with the same mocked data we can test two different directions

* changed structure of decodedXcmMsgs response
- changed structure of the decodedMsgs response so that it always returns three arrays (filled or empty), one for each direction.
- removed an if statement as unnecessary in XCMDecoder
- updated corresponding tests with the new structure of the response

* reintroduced the if statement so that paraId query param works when connected to parachain

* added test to check if query param paraId works correctly also in horizontal msgs

* run linter

* added the decodedXcmMsgs response for blockId endpoint
- the response is a combination of Block and BlockXCM response with the use of allOf
- added schema for Liquidity Pool because the swagger was complaining
- changed the order of a hash field so that it aligns of it actually appears in the corresponding response

* added decodedXcmMsgsArg and paraId in the options arg

* added validation for paraId query param
- changed type of paraId after validation
- renamed boolean option for decodedXcmMsgs so it is shorter

* XCMDecoder changes from Tarik's Amazing review
- changes in imports
- replaced class name with the keyword 'this'
- replaced static with readonly for class properties
- replaced static with private for class methods
- changed specname to lowercase

* reused mockApi's 'perClass' in the other mocked apis
- added the 'type' keyword in more imports

* run linter & refix imports

* Update src/services/blocks/BlocksService.ts

Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com>

* fix on the perClass field

---------

Co-authored-by: marshacb <cameron.marshall12@gmail.com>
Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com>
  • Loading branch information
3 people committed Jan 23, 2024
1 parent 95987f5 commit 555817c
Show file tree
Hide file tree
Showing 48 changed files with 11,740 additions and 89 deletions.
2 changes: 1 addition & 1 deletion docs/dist/app.bundle.js

Large diffs are not rendered by default.

100 changes: 95 additions & 5 deletions docs/src/openapi-v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -643,13 +643,29 @@ paths:
required: false
schema:
type: boolean
- name: decodedXcmMsgs
in: query
description: When set to `true`, this will show the decoded XCM messages within
the extrinsics of the requested block.
required: false
schema:
type: boolean
default: false
- name: paraId
in: query
description: When it is set, this will return only the decoded XCM messages
for the specified paraId/parachain Id. To activate this functionality,
ensure that the `decodedXcmMsgs` parameter is set to true.
required: false
schema:
type: string
responses:
"200":
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Block'
$ref: '#/components/schemas/DecodedXcmMsgs'
"400":
description: invalid Block identifier supplied
content:
Expand Down Expand Up @@ -2339,6 +2355,10 @@ components:
description: An array of queried assets.
items:
$ref: '#/components/schemas/AssetsBalance'
DecodedXcmMsgs:
allOf:
- $ref: "#/components/schemas/Block"
- $ref: "#/components/schemas/BlockXCM"
LiquidityPools:
type: object
properties:
Expand All @@ -2347,10 +2367,29 @@ components:
pools:
type: array
description: Array containing existent liquidity pool's token id.
items:
$ref: '#/components/schemas/LiquidityPool'
example: "[{\"reserves\":[{\"parents\":\"1\",\"interior\":{\"here\":
null}},{\"parents\":\"0\",\"interior\":{\"x2\":[{\"palletInstance\":
\"50\"},{\"generalIndex\":\"2\"}]}}],\"lpToken\":{\"lpToken\":\"1\"}
},{\"lpToken\":{\"lpToken\":\"0\"}}]"
LiquidityPool:
type: object
properties:
reserves:
type: array
items:
type: object
properties:
parents:
type: string
format: unsignedInteger
interior:
type: object
lpToken:
type: string
format: unsignedInteger
description: Liquidity pool token ID.
NextAvailableId:
type: object
properties:
Expand Down Expand Up @@ -2638,14 +2677,14 @@ components:
Block:
type: object
properties:
hash:
type: string
description: The block's hash.
format: hex
number:
type: string
description: The block's height.
format: unsignedInteger
hash:
type: string
description: The block's hash.
format: hex
parentHash:
type: string
description: The hash of the parent block.
Expand Down Expand Up @@ -2781,6 +2820,57 @@ components:
$ref: '#/components/schemas/SanitizedEvent'
description: Object with an array of `SanitizedEvent`s that occurred during
block initialization with the `method` and `data` for each.
BlockXCM:
type: object
properties:
decodedXcmMsgs:
type: object
properties:
horizontalMessages:
type: array
items:
type: object
properties:
sentAt:
type: string
format: unsignedInteger
description: Represents the block number that the XCM message was sent at on the relay chain.
paraId:
type: string
format: unsignedInteger
description: The paraId that the specific XCM message was sent from.
data:
type: object
description: The decoded instructions and their respective fields that are included in the XCM message.
downwardMessages:
type: array
items:
type: object
properties:
sentAt:
type: string
format: unsignedInteger
description: Represents the block number that the XCM message was sent at on the relay chain.
msg:
type: string
description: Represents the XCM message.
data:
type: object
description: The decoded instructions and their respective fields that are included in the XCM message.
upwardMessages:
type: array
items:
type: object
properties:
paraId:
type: string
format: unsignedInteger
description: The paraId that the specific XCM message was sent from.
data:
type: object
description: The decoded instructions and their respective fields that are included in the XCM message.
description: Object with three arrays, one for every XCM direction. The arrays are populated or left
empty based on the direction of the current XCM message that is being decoded.
BlocksTrace:
type: object
properties:
Expand Down
24 changes: 21 additions & 3 deletions src/controllers/blocks/BlocksController.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2017-2023 Parity Technologies (UK) Ltd.
// Copyright 2017-2024 Parity Technologies (UK) Ltd.
// This file is part of Substrate API Sidecar.
//
// Substrate API Sidecar is free software: you can redistribute it and/or modify
Expand All @@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import { ApiPromise } from '@polkadot/api';
import type { ApiPromise } from '@polkadot/api';
import { isHex } from '@polkadot/util';
import { RequestHandler } from 'express';
import { BadRequest } from 'http-errors';
Expand Down Expand Up @@ -43,6 +43,12 @@ import AbstractController from '../AbstractController';
* - (Optional for `/blocks/head`) `finalized`: When set to `false`, it will fetch the head of
* the node's canon chain, which might not be finalized. When set to `true` it
* will fetch the head of the finalized chain.
* - (Optional) `noFees`: When set to `true`, it will not calculate the fee for each extrinsic.
* - (Optional for `/blocks/{blockId}`) `decodedXcmMsgs`: When set to `true`, it will show the
* decoded XCM messages within the extrinsics of the requested block.
* - (Optional for `/blocks/{blockId}) `paraId`: When it is set, it will return only the decoded
* XCM messages for the specified paraId/parachain Id. To activate this functionality, ensure
* that the `decodedXcmMsgs` parameter is set to true.
*
*
* Returns:
Expand Down Expand Up @@ -74,6 +80,8 @@ import AbstractController from '../AbstractController';
* is `true` and that the extrinsic is signed when reconciling old blocks.
* - `onFinalize`: Object with an array of `SanitizedEvent`s that occurred during block
* finalization with the `method` and `data` for each.
* - `decodedXcmMsgs`: An array of the decoded XCM messages found within the extrinsics
* of the requested block.
*
* Note: Block finalization does not correspond to consensus, i.e. whether the block is in the
* canonical chain. It denotes the finalization of block _construction._
Expand Down Expand Up @@ -147,6 +155,8 @@ export default class BlocksController extends AbstractController<BlocksService>
queryFinalizedHead,
omitFinalizedTag,
noFees: noFeesArg,
checkDecodedXcm: false,
paraId: undefined,
};

const historicApi = await this.api.at(hash);
Expand All @@ -161,7 +171,7 @@ export default class BlocksController extends AbstractController<BlocksService>
* @param res Express Response
*/
private getBlockById: RequestHandler<INumberParam> = async (
{ params: { number }, query: { eventDocs, extrinsicDocs, noFees, finalizedKey } },
{ params: { number }, query: { eventDocs, extrinsicDocs, noFees, finalizedKey, decodedXcmMsgs, paraId } },
res,
): Promise<void> => {
const checkFinalized = isHex(number);
Expand All @@ -180,13 +190,19 @@ export default class BlocksController extends AbstractController<BlocksService>
omitFinalizedTag = true;
}

const decodedXcmMsgsArg = decodedXcmMsgs === 'true';
const paraIdArg =
paraId !== undefined ? this.parseNumberOrThrow(paraId as string, 'paraId must be an integer') : undefined;

const options = {
eventDocs: eventDocsArg,
extrinsicDocs: extrinsicDocsArg,
checkFinalized,
queryFinalizedHead,
omitFinalizedTag,
noFees: noFeesArg,
checkDecodedXcm: decodedXcmMsgsArg,
paraId: paraIdArg,
};

// HistoricApi to fetch any historic information that doesnt include the current runtime
Expand Down Expand Up @@ -249,6 +265,8 @@ export default class BlocksController extends AbstractController<BlocksService>
queryFinalizedHead,
omitFinalizedTag,
noFees: noFeesArg,
checkDecodedXcm: false,
paraId: undefined,
};

const pQueue = new PromiseQueue(4);
Expand Down
10 changes: 6 additions & 4 deletions src/controllers/blocks/BlocksExtrinsicsController.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2017-2022 Parity Technologies (UK) Ltd.
// Copyright 2017-2024 Parity Technologies (UK) Ltd.
// This file is part of Substrate API Sidecar.
//
// Substrate API Sidecar is free software: you can redistribute it and/or modify
Expand All @@ -14,12 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import { ApiPromise } from '@polkadot/api';
import type { ApiPromise } from '@polkadot/api';
import { RequestHandler } from 'express';

import { BlocksService } from '../../services';
import { ControllerOptions } from '../../types/chains-config';
import { INumberParam } from '../../types/requests';
import type { ControllerOptions } from '../../types/chains-config';
import type { INumberParam } from '../../types/requests';
import AbstractController from '../AbstractController';

export default class BlocksExtrinsicsController extends AbstractController<BlocksService> {
Expand Down Expand Up @@ -58,6 +58,8 @@ export default class BlocksExtrinsicsController extends AbstractController<Block
queryFinalizedHead: false,
omitFinalizedTag: true,
noFees: noFeesArg,
checkDecodedXcm: false,
paraId: undefined,
};

const historicApi = await this.api.at(hash);
Expand Down
Loading

0 comments on commit 555817c

Please sign in to comment.