Skip to content

Commit

Permalink
make ranks deterministic
Browse files Browse the repository at this point in the history
  • Loading branch information
will pankiewicz authored and will pankiewicz committed Feb 14, 2024
1 parent 0bce335 commit c4c33c7
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 8 deletions.
7 changes: 6 additions & 1 deletion packages/common/src/chaindata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,12 @@ export class ChainData {
getTotalEraPoints = async (era: number) => {
await this.checkApiConnection();

const erasRewardPoints = await this.api.query.staking.erasRewardPoints(era);
const chainMetadata = await getChainMetadata();
const chainType = chainMetadata.name;
const [blockHash, err] = await this.findEraBlockHash(era, chainType);
const apiAt = await this.api.at(blockHash);

const erasRewardPoints = await apiAt.query.staking.erasRewardPoints(era);
const total = erasRewardPoints.total;
const validators = erasRewardPoints.individual;
const vals = [];
Expand Down
16 changes: 16 additions & 0 deletions packages/common/src/db/queries/Candidate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,22 @@ export const pushFaultEvent = async (
return false;
};

export const setRank = async (
stash: string,
newRank: number,
): Promise<boolean> => {
await CandidateModel.findOneAndUpdate(
{
stash,
},
{
rank: newRank,
},
).exec();

return true;
};

export const addPoint = async (stash: string): Promise<boolean> => {
logger.info(`Adding a point to ${stash}.`);

Expand Down
36 changes: 36 additions & 0 deletions packages/common/src/db/queries/EraPoints.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Create new Era Points records
import { EraPointsModel, TotalEraPointsModel } from "../models";
import { getIdentityAddresses } from "./Candidate";

export const setEraPoints = async (
era: number,
Expand Down Expand Up @@ -195,3 +196,38 @@ export const getValidatorLastEraPoints = async (
.limit(1)
.exec();
};

// Gets the number of eras a validator has era points for
export const getValidatorEraPointsCount = async (
address: string,
): Promise<number> => {
const eras = await EraPointsModel.find({
address: address,
})
.lean()
.exec();
return eras.length;
};

// Gets a list of the total count of era points for every identity that is a part of a validators super/sub identity
export const getIdentityValidatorEraPointsCount = async (
address: string,
): Promise<{ address: string; eras: number }[]> => {
const eraPointsList: { address: string; eras: number }[] = [];
const identityAddresses: string[] = await getIdentityAddresses(address);
for (const identityAddress of identityAddresses) {
const eras = await getValidatorEraPointsCount(identityAddress);
eraPointsList.push({ address: identityAddress, eras: eras });
}
return eraPointsList.sort((a, b) => b.eras - a.eras);
};

// For an identity, gets the identity with the most era points
export const getIdentityValidatorEraPointsCountMax = async (
address: string,
): Promise<number> => {
const identityEras: { address: string; eras: number }[] =
await getIdentityValidatorEraPointsCount(address);
const maxEras: number = Math.max(...identityEras.map((entry) => entry.eras));
return maxEras || 0;
};
10 changes: 10 additions & 0 deletions packages/core/src/scorekeeper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,16 @@ export default class ScoreKeeper {
async begin(): Promise<void> {
logger.info(`Starting Scorekeeper.`, scorekeeperLabel);

const candidates = await queries.allCandidates();

// Set all candidate identities
for (const [index, candidate] of candidates.entries()) {
const identity = await this.chaindata.getFormattedIdentity(
candidate.stash,
);
await queries.setCandidateIdentity(candidate.stash, identity);
}

// If `forceRound` is on - start immediately.
if (this.config.scorekeeper.forceRound) {
logger.info(
Expand Down
3 changes: 1 addition & 2 deletions packages/core/src/scorekeeper/Round.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { scorekeeperLabel } from "../scorekeeper";
import { logger, queries, Types, Util } from "@1kv/common";
import { addPoint, dockPoints } from "./Rank";
import { dockPoints } from "./Rank";
import { doNominations } from "./Nominating";

/**
Expand Down Expand Up @@ -120,7 +120,6 @@ export const endRound = async (

// They were active - increase their rank and add a rank event
const didRank = await queries.pushRankEvent(stash, startEra, activeEra);
if (didRank) await addPoint(stash, bot);
}

// For all bad validators, dock their points and create a "Fault Event"
Expand Down
2 changes: 1 addition & 1 deletion packages/gateway/src/services/Candidate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const getCandidateData = async (candidate: any): Promise<any> => {
nominatedAt: candidate.nominatedAt,
offlineSince: candidate.offlineSince,
offlineAccumulated: candidate.offlineAccumulated,
rank: candidate.rank,
rank: candidate.rank || 0,
faults: candidate.faults,
invalidityReasons: candidate.invalidityReasons,
unclaimedEras: candidate.unclaimedEras,
Expand Down
25 changes: 21 additions & 4 deletions packages/worker/src/jobs/EraPointsJob.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { logger, queries, ChainData } from "@1kv/common";
import { ChainData, logger, queries } from "@1kv/common";

export const erapointsLabel = { label: "EraPointsJob" };

Expand All @@ -10,7 +10,7 @@ export const individualEraPointsJob = async (
const erapoints = await queries.getTotalEraPoints(eraIndex);

// If Era Points for the era exist, and are what the total should be, skip
if (!!erapoints && erapoints.totalEraPoints >= 70000 && erapoints.median) {
if (!!erapoints && erapoints.totalEraPoints >= 700 && erapoints.median) {
return;
} else {
const { era, total, validators } =
Expand All @@ -24,12 +24,29 @@ export const eraPointsJob = async (chaindata: ChainData) => {

// Set Era Points
// - get the current active era
// - iterate through the previous 84 eras
// - iterate through the previous eras until the first era
// - if a record for era points for that era already exists, skip it
// - if a record doesn't exist, create it
const [activeEra, err] = await chaindata.getActiveEraIndex();
for (let i = activeEra - 1; i > activeEra - 84 && i >= 0; i--) {
for (let i = activeEra - 1; i >= 0; i--) {
await individualEraPointsJob(chaindata, i);
logger.info(
`Processed Era Points for Era: ${i} (${activeEra - i}/${activeEra})`,
erapointsLabel,
);
}

// Update ranks for candidates to be the max number of eras active of any identity within a validators sub/super identity
const candidates = await queries.allCandidates();
for (const [index, candidate] of candidates.entries()) {
const rank =
(await queries.getIdentityValidatorEraPointsCountMax(candidate.stash)) ||
0;
await queries.setRank(candidate.stash, rank);
logger.info(
`Updated Rank for ${candidate.stash} to ${rank} (${index + 1}/${candidates.length})`,
erapointsLabel,
);
}

const end = Date.now();
Expand Down

0 comments on commit c4c33c7

Please sign in to comment.