UNPKG

@substrate/api-sidecar

Version:

REST service that makes it easy to interact with blockchain nodes built using Substrate's FRAME framework.

109 lines 4.76 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PalletsStakingValidatorsService = void 0; const badStakingBlocks_1 = require("../../util/badStakingBlocks"); const AbstractService_1 = require("../AbstractService"); class PalletsStakingValidatorsService extends AbstractService_1.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) { const { api } = this; const historicApi = await api.at(hash); if (!historicApi.query.staking) { throw new Error('Staking pallet not found for queried runtime'); } const [{ number }, validatorsEntries] = await Promise.all([ api.rpc.chain.getHeader(hash), historicApi.query.staking.validators.entries(), ]); const at = { hash, height: number.unwrap().toString(10), }; if ((0, badStakingBlocks_1.isBadStakingBlock)(this.specName, number.unwrap().toNumber())) { let chainName = this.specName; switch (this.specName) { case 'westmint': chainName = 'Westend Asset Hub'; break; } throw new Error(`Post migration, there were some interruptions to staking on ${chainName}, Block ${number.unwrap().toString(10)} is in the list of known bad staking blocks in ${chainName}`); } // 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 = []; // Active validators that wont be part of the next active validator set // for the incoming era. const validatorsToBeChilled = []; const validatorsActiveSet = await this.getActiveValidators(historicApi); validatorsEntries.map(([key, prefs]) => { const address = key.args.map((k) => k.toString())[0]; let status; if (validatorsActiveSet.has(address)) { status = 'active'; validatorsActiveSet.delete(address); } else { status = 'waiting'; } validators.push({ address, status, commission: prefs.commission ? prefs.commission.unwrap().toString() : undefined, blocked: prefs.blocked ? prefs.blocked.isTrue : false, }); }); // Any validators remaining in validatorsActiveSet are active in the current session // but don't have entries in staking.validators, which means they're being chilled if (validatorsActiveSet.size > 0) { validatorsActiveSet.forEach((address) => { validators.push({ address, status: 'active' }); validatorsToBeChilled.push({ address, status: 'active' }); }); } return { at, validators, validatorsToBeChilled, }; } /** * Get the active validators given an era. * * @param historicApi */ async getActiveValidators(historicApi) { const validatorsActiveSet = new Set(); if (historicApi.query.staking.erasStakersOverview) { let activeEra; const activeEraOption = await historicApi.query.staking.activeEra(); if (activeEraOption.isNone) { const currentEraOption = await historicApi.query.staking.currentEra(); if (currentEraOption.isNone) throw new Error('No active or current era was found'); activeEra = currentEraOption.unwrap(); } else { activeEra = activeEraOption.unwrap().index; } const vals = await historicApi.query.staking.erasStakersOverview.keys(activeEra); vals.forEach(({ args }) => validatorsActiveSet.add(args[1].toString())); } else { const validatorSession = await historicApi.query.session.validators(); for (const address of validatorSession) { validatorsActiveSet.add(address.toString()); } } return validatorsActiveSet; } } exports.PalletsStakingValidatorsService = PalletsStakingValidatorsService; //# sourceMappingURL=PalletsStakingValidatorsService.js.map