Skip to content

Commit

Permalink
feat: add /pallets/staking/validators endpoint (#1045)
Browse files Browse the repository at this point in the history
* Added the `validators` endpoint
- Controller, service, response type
- Returns all validators addresses and their corresponding status (active / waiting)

* Validators Info per block
- Added the `at` query param
- Modified the Service accordingly

* yarn lint

* Changes `array` to `Set` (James Super Tip)
- Changed the data structure used to save the validators in the active set from an `array` to a `Set` (based on James suggestion)
- Changed also the used functions accordingly.
- Merged in one loop the check of which validator is in the active set and the population of the returned array.

* Lint & Update docs
- yarn lint
- Added validators endpoint to the docs
- Corrected other parts of the docs mentioned by the swagger as errors.

* Added in latest e2e tests the validators endpoint

* Changes from Tarik s comments

* Adjustments in the docstring

* Update src/services/pallets/PalletsStakingValidatorsService.ts

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

* yarn lint:fix

Co-authored-by: Tarik Gul <47201679+TarikGul@users.noreply.github.com>
  • Loading branch information
Imod7 and TarikGul committed Jan 24, 2023
1 parent 22f8fd4 commit 70e0a36
Show file tree
Hide file tree
Showing 13 changed files with 213 additions and 2 deletions.
2 changes: 1 addition & 1 deletion docs/dist/app.bundle.js

Large diffs are not rendered by default.

51 changes: 50 additions & 1 deletion docs/src/openapi-v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,11 @@ paths:
description: Abi params used as args specified in the metadata to be passed into a query.
The format to use this query param is ?args[]=1&args[]=2&args[]=3.
required: false
schema:
type: array
items:
type: string
description: An array of Abi params.
responses:
"200":
description: succesful operation
Expand Down Expand Up @@ -1016,6 +1021,37 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/Error'
/pallets/staking/validators:
get:
tags:
- staking
- pallets
summary: Get all validators (active/waiting) of a specific chain.
description: Returns a list of all validators addresses and their
corresponding status which can be either active or waiting.
operationId: getStakingValidators
parameters:
- name: at
in: query
description: Block at which to retrieve the list of validators.
required: false
schema:
type: string
description: Block identifier, as the block height or block hash.
format: unsignedInteger or $hex
responses:
"200":
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/StakingValidators'
"400":
description: invalid blockId supplied for at query param
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/pallets/{palletId}/errors:
get:
tags:
Expand Down Expand Up @@ -2192,7 +2228,7 @@ components:
description: Will result in an Ok or Err object depending on the result of the query.
storageDeposit:
type: object
ContractMetata:
ContractMetadata:
type: object
description: Metadata used to instantiate a ContractPromise. This metadata can be generated
by compiling the contract you are querying.
Expand Down Expand Up @@ -2566,6 +2602,8 @@ components:
type: string
description: Metadata of an error item from a FRAME pallet.
PalletsNominationPool:
type: object
properties:
bondedPool:
$ref: '#/components/schemas/BondedPool'
rewardPool:
Expand Down Expand Up @@ -3112,6 +3150,17 @@ components:
items:
type: string
format: ss58
StakingValidators:
type: object
properties:
at:
$ref: '#/components/schemas/BlockIdentifiers'
address:
type: string
description: Address of validator.
status:
type: string
description: Status of individual validator (active/waiting).
StorageEntryTypeV13:
type: object
properties:
Expand Down
7 changes: 7 additions & 0 deletions e2e-tests/latest/endpoints/polkadot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ export const polkadot: IConfig = {
'unclaimedOnly=false',
],
},
'/pallets/staking/validators': {
path: '/pallets/staking/validators',
queryParams: [
'at={blockId}',
'metadata=true',
]
},
'/accounts/{accountId}/validate': {
path: '/accounts/DXgXPAT5zWtPHo6FhVvrDdiaDPgCNGxhJAeVBYLtiwW9hAc/validate',
queryParams: [],
Expand Down
1 change: 1 addition & 0 deletions src/chains-config/kusamaControllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const kusamaControllers: ControllerConfig = {
'PalletsErrors',
'PalletsNominationPools',
'PalletsStakingProgress',
'PalletsStakingValidators',
'PalletsStorage',
'Paras',
'RuntimeCode',
Expand Down
1 change: 1 addition & 0 deletions src/chains-config/polkadotControllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const polkadotControllers: ControllerConfig = {
'PalletsErrors',
'PalletsNominationPools',
'PalletsStakingProgress',
'PalletsStakingValidators',
'PalletsStorage',
'Paras',
'RuntimeCode',
Expand Down
1 change: 1 addition & 0 deletions src/chains-config/westendControllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const westendControllers: ControllerConfig = {
'PalletsErrors',
'PalletsNominationPools',
'PalletsStakingProgress',
'PalletsStakingValidators',
'PalletsStorage',
'Paras',
'RuntimeCode',
Expand Down
2 changes: 2 additions & 0 deletions src/controllers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
PalletsErrors,
PalletsNominationPools,
PalletsStakingProgress,
PalletsStakingValidators,
PalletsStorage,
} from './pallets';
import { Paras } from './paras';
Expand Down Expand Up @@ -61,6 +62,7 @@ export const controllers = {
PalletsErrors,
PalletsNominationPools,
PalletsStakingProgress,
PalletsStakingValidators,
PalletsStorage,
NodeNetwork,
NodeTransactionPool,
Expand Down
54 changes: 54 additions & 0 deletions src/controllers/pallets/PalletsStakingValidatorsController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2017-2022 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
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// 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 { RequestHandler } from 'express';

import { PalletsStakingValidatorsService } from '../../services';
import AbstractController from '../AbstractController';

export default class PalletsStakingValidatorsController extends AbstractController<PalletsStakingValidatorsService> {
constructor(api: ApiPromise) {
super(
api,
'/pallets/staking/validators',
new PalletsStakingValidatorsService(api)
);
this.initRoutes();
}

protected initRoutes(): void {
this.safeMountAsyncGetHandlers([['', this.getPalletStakingValidators]]);
}

/**
* Get the progress of the staking pallet system.
*
* @param _req Express Request
* @param res Express Response
*/
private getPalletStakingValidators: RequestHandler = async (
{ query: { at } },
res
): Promise<void> => {
const hash = await this.getHashFromAt(at);

PalletsStakingValidatorsController.sanitizedSend(
res,
await this.service.derivePalletStakingValidators(hash)
);
};
}
1 change: 1 addition & 0 deletions src/controllers/pallets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ export { default as PalletsAssets } from './PalletsAssetsController';
export { default as PalletsErrors } from './PalletsErrorsController';
export { default as PalletsNominationPools } from './PalletsNominationPoolsController';
export { default as PalletsStakingProgress } from './PalletsStakingProgressController';
export { default as PalletsStakingValidators } from './PalletsStakingValidatorsController';
export { default as PalletsStorage } from './PalletsStorageController';
61 changes: 61 additions & 0 deletions src/services/pallets/PalletsStakingValidatorsService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2017-2022 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
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// 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 { BlockHash } from '@polkadot/types/interfaces';
import { IPalletStakingValidator, IValidator } from 'src/types/responses';

import { AbstractService } from '../AbstractService';

export class PalletsStakingValidatorsService extends AbstractService {
/**
* Fetch all validators addresses and their status at a given block.
* The status of the validator can be either:
* - `active` (validator is part of the active set) or
* - `waiting` (validator did not get into the active set this era)
*
* @param hash `BlockHash` to make call at
*/
async derivePalletStakingValidators(
hash: BlockHash
): Promise<IPalletStakingValidator> {
const { api } = this;
const historicApi = await api.at(hash);

const validatorSession = await historicApi.query.session.validators();
const validatorsActiveSet = new Set<string>();
for (const address of validatorSession) {
validatorsActiveSet.add(address.toString());
}

// Populating the returned array with the Validator address and its
// status. If the address is found in the `validatorsActiveSet` then
// status is `active` otherwise is set to `waiting`
const validators: IValidator[] = [];
const validatorsEntries =
await historicApi.query.staking.validators.entries();
validatorsEntries.map(([key]) => {
const address = key.args.map((k) => k.toHuman())[0];
const status: string = validatorsActiveSet.has(address)
? 'active'
: 'waiting';
validators.push({ address, status });
});

return {
validators,
};
}
}
1 change: 1 addition & 0 deletions src/services/pallets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ export * from '././PalletsErrorsService';
export * from './PalletsAssetsService';
export * from './PalletsNominationPoolsService';
export * from './PalletsStakingProgressService';
export * from './PalletsStakingValidatorsService';
export * from './PalletsStorageService';
32 changes: 32 additions & 0 deletions src/types/responses/PalletStakingValidators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2017-2022 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
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

export interface IValidator {
/**
* Address of the validator.
*/
address: string;
/**
* The status of the validator which can be either `active` or `waiting`.
* `Active` means that the validator is part of the active set and
* `waiting` means that the validator did not get into the active set this era.
*/
status: string;
}

export interface IPalletStakingValidator {
validators: IValidator[];
}
1 change: 1 addition & 0 deletions src/types/responses/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export * from './PalletErrors';
export * from './PalletErrorsItem';
export * from './PalletNominationPools';
export * from './PalletStakingProgress';
export * from './PalletStakingValidators';
export * from './PalletStorage';
export * from './PalletStorageItem';
export * from './Paras';
Expand Down

0 comments on commit 70e0a36

Please sign in to comment.