Skip to content

Commit

Permalink
always print the list of validators (#52)
Browse files Browse the repository at this point in the history
* always print the list of validators
fix small bugs when the returned value doesn't exists

* lint & prettier
  • Loading branch information
marcellorigotti authored Apr 26, 2024
1 parent 1b83568 commit 9df8e49
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 115 deletions.
115 changes: 54 additions & 61 deletions src/metrics/chainflip/gaugeWitnessChainTracking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import promClient, { Gauge } from 'prom-client';
import { Context } from '../../lib/interfaces';
import { blake2AsHex } from '@polkadot/util-crypto';
import { hex2bin, insertOrReplace } from '../../utils/utils';
import { customRpc } from '../../utils/makeRpcRequest';
import makeRpcRequest, { customRpc } from '../../utils/makeRpcRequest';

const witnessHash10 = new Map<number, Set<string>>();
const witnessHash50 = new Map<number, Set<string>>();
Expand Down Expand Up @@ -56,72 +56,65 @@ export const gaugeWitnessChainTracking = async (context: Context): Promise<void>
witnessHash10.delete(blockNumber);
for (const hash of tmpSet) {
const parsedObj = JSON.parse(hash);
api.query.witnesser
.votes(global.epochIndex, parsedObj.hash)
.then(async (votes: { toJSON: () => any }) => {
if (global.currentBlock === currentBlockNumber) {
const vote = votes.toJSON();
if (vote) {
const binary = hex2bin(vote);
let total = binary.match(/1/g)?.length || 0;
// check the previous epoch as well! could be a false positive after rotation!
if (total < global.currentAuthorities * 0.1) {
const previousEpochVote = (
await api.query.witnesser.votes(
global.epochIndex - 1,
parsedObj.hash,
)
).toJSON();
makeRpcRequest(api, 'witness_count', parsedObj.hash).then(
async (result: any) => {
if (global.currentBlock === currentBlockNumber && result) {
let total = global.currentAuthorities - result.failing_count;
// check the previous epoch as well! could be a false positive after rotation!
if (total < global.currentAuthorities * 0.1) {
const previousEpochVote = (
await api.query.witnesser.votes(
global.epochIndex - 1,
parsedObj.hash,
)
)?.toJSON();
if (previousEpochVote) {
total +=
hex2bin(previousEpochVote).match(/1/g)?.length || 0;
}
metric.labels(parsedObj.type, '10').set(total);

// log the hash if not all the validator witnessed it so we can quickly look up the hash and check which validator failed to do so
if (total < global.currentAuthorities) {
// log the list of validators if the total is below 90%
if (total <= global.currentAuthorities * 0.9) {
const votes = await customRpc(
api,
'witness_count',
parsedObj.hash,
);
const validators: string[] = [];
votes.validators.forEach(
([ss58address, vanity, witness]) => {
if (!witness) {
validators.push(ss58address);
}
},
);
logger.info(
`Block ${blockNumber}: ${parsedObj.type} hash ${parsedObj.hash} witnesssed by ${total} validators after 10 blocks!
Validators: [${validators}]`,
);
metricWitnessFailure
.labels(
`${parsedObj.type}`,
`${validators}`,
`${total}`,
)
.set(1);
toDelete.set(
JSON.stringify({
extrinsic: `${parsedObj.type}`,
validators: `${validators}`,
witnessedBy: `${total}`,
}),
currentBlockNumber + 50,
);
} else {
logger.info(
`Block ${blockNumber}: ${parsedObj.type} hash ${parsedObj.hash} witnesssed by ${total} validators after 10 blocks!`,
);
}
}
metric.labels(parsedObj.type, '10').set(total);
// log the hash if not all the validator witnessed it so we can quickly look up the hash and check which validator failed to do so
if (total < global.currentAuthorities) {
const validators: string[] = [];
result.validators.forEach(
([ss58address, vanity, witness]: [
string,
string,
boolean,
]) => {
if (!witness) {
validators.push(ss58address);
}
},
);
logger.info(
`Block ${blockNumber}: ${parsedObj.type} hash ${parsedObj.hash} witnesssed by ${total} validators after 10 blocks!
Validators: [${validators}]`,
);
// in case less than 90% witnessed it
// create a temporary metric so that we can fetch the list of validators in our alerting system
if (total <= global.currentAuthorities * 0.9) {
metricWitnessFailure
.labels(
`${parsedObj.type}`,
`${validators}`,
`${total}`,
)
.set(1);
toDelete.set(
JSON.stringify({
extrinsic: `${parsedObj.type}`,
validators: `${validators}`,
witnessedBy: `${total}`,
}),
currentBlockNumber + 40,
);
}
}
}
});
},
);
}
}
}
Expand Down
60 changes: 27 additions & 33 deletions src/metrics/chainflip/gaugeWitnessCount.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import promClient, { Gauge } from 'prom-client';
import { Context } from '../../lib/interfaces';
import { hex2bin, insertOrReplace } from '../../utils/utils';
import { customRpc } from '../../utils/makeRpcRequest';
import makeRpcRequest, { customRpc } from '../../utils/makeRpcRequest';

const witnessExtrinsicHash10 = new Map<number, Set<string>>();
const witnessExtrinsicHash50 = new Map<number, Set<string>>();
Expand Down Expand Up @@ -55,35 +55,32 @@ export const gaugeWitnessCount = async (context: Context): Promise<void> => {
witnessExtrinsicHash10.delete(blockNumber);
for (const hash of tmpSet) {
const parsedObj = JSON.parse(hash);
api.query.witnesser
.votes(global.epochIndex, parsedObj.hash)
.then(async (votes: { toJSON: () => any }) => {
const vote = votes.toJSON();
if (vote) {
const binary = hex2bin(vote);
const total = binary.match(/1/g)?.length || 0;

makeRpcRequest(api, 'witness_count', parsedObj.hash).then(
async (result: any) => {
if (global.currentBlock === currentBlockNumber && result) {
const total = global.currentAuthorities - result.failing_count;
metric.labels(parsedObj.type, '10').set(total);
// log the hash if not all the validator witnessed it so we can quickly look up the hash and check which validator failed to do so
if (total < global.currentAuthorities) {
// log the list of validators if the total is below 90%
const validators: string[] = [];
result.validators.forEach(
([ss58address, vanity, witness]: [
string,
string,
boolean,
]) => {
if (!witness) {
validators.push(ss58address);
}
},
);
logger.info(
`Block ${blockNumber}: ${parsedObj.type} hash ${parsedObj.hash} witnesssed by ${total} validators after 10 blocks!
Validators: [${validators}]`,
);
// in case less than 90% witnessed it
// create a temporary metric so that we can fetch the list of validators in our alerting system
if (total <= global.currentAuthorities * 0.67) {
const votes = await customRpc(
api,
'witness_count',
parsedObj.hash,
);
const validators: string[] = [];
votes.validators.forEach(
([ss58address, vanity, witness]) => {
if (!witness) {
validators.push(ss58address);
}
},
);
logger.info(
`Block ${blockNumber}: ${parsedObj.type} hash ${parsedObj.hash} witnesssed by ${total} validators after 10 blocks!
Validators: [${validators}]`,
);
metricWitnessFailure
.labels(
`${parsedObj.type}`,
Expand All @@ -97,16 +94,13 @@ export const gaugeWitnessCount = async (context: Context): Promise<void> => {
validators: `${validators}`,
witnessedBy: `${total}`,
}),
currentBlockNumber + 20,
);
} else {
logger.info(
`Block ${blockNumber}: ${parsedObj.type} hash ${parsedObj.hash} witnesssed by ${total} validators after 10 blocks!`,
currentBlockNumber + 10,
);
}
}
}
});
},
);
}
}
}
Expand Down
39 changes: 18 additions & 21 deletions src/utils/makeRpcRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,29 +110,26 @@ export default async function makeRpcRequest<M extends RpcCall>(
method: M,
...args: RpcParamsMap[M]
): Promise<RpcReturnValue[M]> {
const result = await apiPromise.rpc.cf[method](...args);

const parsed = validators[method].parse(result.toJSON());
// console.log(method, result.toJSON(), parsed);

return parsed as RpcReturnValue[M];
const result: any = await apiPromise.rpc(`cf_${method}`, ...args);
// const parsed = validators[method].parse(result.toJSON());
return result as RpcReturnValue[M];
}

export async function customRpc<M extends RpcCall>(
apiPromise: CustomApiPromise,
method: M,
...args: RpcParamsMap[M]
): Promise<RpcReturnValue[M]> {
const url = env.CF_WS_ENDPOINT.split('wss');
// export async function customRpc<M extends RpcCall>(
// apiPromise: CustomApiPromise,
// method: M,
// ...args: RpcParamsMap[M]
// ): Promise<RpcReturnValue[M]> {
// const url = env.CF_WS_ENDPOINT.split('wss');

const { data } = await axios.post(`https${url[1]}`, {
id: 1,
jsonrpc: '2.0',
method: `cf_${method}`,
params: args,
});
// const { data } = await axios.post(`https${url[1]}`, {
// id: 1,
// jsonrpc: '2.0',
// method: `cf_${method}`,
// params: args,
// });

const parsed = validators[method].parse(data.result);
// const parsed = validators[method].parse(data.result);

return parsed as RpcReturnValue[M];
}
// return parsed as RpcReturnValue[M];
// }

0 comments on commit 9df8e49

Please sign in to comment.