Skip to content
This repository has been archived by the owner on Sep 26, 2024. It is now read-only.

Commit

Permalink
refactor: Moved things around to clean up the code and make the namin…
Browse files Browse the repository at this point in the history
…g at least somewhat sane
  • Loading branch information
frol authored and shelegdmitriy committed May 13, 2021
1 parent 724b266 commit fb7ba55
Show file tree
Hide file tree
Showing 36 changed files with 686 additions and 650 deletions.
11 changes: 6 additions & 5 deletions backend/src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,17 @@ exports.regularSyncMissingNearcoreStateInterval =
parseInt(process.env.NEAR_REGULAR_SYNC_MISSING_NEARCORE_STATE_INTERVAL) ||
60000;

exports.regularQueryRPCInterval =
parseInt(process.env.NEAR_REGULAR_QUERY_RPC_INTERVAL) || 1000;
exports.regularPublishFinalityStatusInterval =
parseInt(process.env.NEAR_REGULAR_PUBLISH_FINALITY_STATUS_INTERVAL) || 1000;

exports.regularQueryStatsInterval =
parseInt(process.env.NEAR_REGULAR_QUERY_STATS_INTERVAL) || 1000;

exports.regularCheckNodeStatusInterval =
parseInt(process.env.NEAR_REGULAR_QUERY_NODE_INTERVAL) || 1000;
exports.regularPublishNetworkInfoInterval =
parseInt(process.env.NEAR_REGULAR_PUBLISH_NETWORK_INFO_INTERVAL) || 1000;

exports.regularCheckNodeValidatorsExtraInfo = 15000;
exports.regularFetchStakingPoolsInfoInterval =
parseInt(process.env.NEAR_REGULAR_FETCH_STAKING_POOLS_INFO_INTERVAL) || 15000;

exports.regularStatsInterval =
parseInt(process.env.NEAR_REGULAR_STATS_INTERVAL) || 3600000;
Expand Down
4 changes: 2 additions & 2 deletions backend/src/db-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const queryGenesisAccountCount = async () => {
};

// query for node information
const addNodeInfo = async (nodes) => {
const extendWithTelemetryInfo = async (nodes) => {
const accountArray = nodes.map((node) => node.account_id);
let nodesInfo = await queryRows([
`SELECT ip_address AS ipAddress, account_id AS accountId, node_id AS nodeId,
Expand Down Expand Up @@ -531,7 +531,7 @@ const queryPartnerUniqueUserAmount = async () => {

// node part
exports.queryOnlineNodes = queryOnlineNodes;
exports.addNodeInfo = addNodeInfo;
exports.extendWithTelemetryInfo = extendWithTelemetryInfo;
exports.pickOnlineValidatingNode = pickOnlineValidatingNode;

// genesis
Expand Down
188 changes: 98 additions & 90 deletions backend/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ const {
regularCheckGenesisInterval,
regularSyncNewNearcoreStateInterval,
regularSyncMissingNearcoreStateInterval,
regularQueryRPCInterval,
regularPublishFinalityStatusInterval,
regularQueryStatsInterval,
regularCheckNodeStatusInterval,
regularCheckNodeValidatorsExtraInfo,
regularPublishNetworkInfoInterval,
regularFetchStakingPoolsInfoInterval,
regularStatsInterval,
} = require("./config");
const { DS_LEGACY_SYNC_BACKEND, DS_INDEXER_BACKEND } = require("./consts");

const { nearRpc, queryFinalTimestamp, queryNodeStats } = require("./near");
const { nearRpc, queryFinalBlock, queryEpochStats } = require("./near");

const {
syncNewNearcoreState,
Expand All @@ -27,7 +27,7 @@ const {
const { setupWamp, wampPublish } = require("./wamp");

const {
addNodeInfo,
extendWithTelemetryInfo,
queryOnlineNodes,
pickOnlineValidatingNode,
getSyncedGenesis,
Expand All @@ -53,10 +53,9 @@ const {
aggregateLiveAccountsCountByDate,
} = require("./stats");

let validators = null;
let proposals = null;
let validatorsExtraInfo = null;
let proposalsExtraInfo = null;
let currentValidators = [];
let currentProposals = [];
let stakingPoolsInfo = new Map();

async function startLegacySync() {
console.log("Starting NEAR Explorer legacy syncing service...");
Expand Down Expand Up @@ -240,118 +239,127 @@ async function main() {
console.log("Starting WAMP worker...");
wamp.open();

// regular check finalTimesamp and publish to final-timestamp uri
const regularCheckFinalTimestamp = async () => {
// regularly publish the latest information about the height and timestamp of the final block
const regularPublishFinalityStatus = async () => {
console.log("Starting regular final timestamp check...");
try {
if (wamp.session) {
const finalTimestamp = await queryFinalTimestamp();
wampPublish("final-timestamp", { finalTimestamp }, wamp);
const finalBlock = await queryFinalBlock();
wampPublish(
"finality-status",
{
finalBlockTimestampNanosecond: finalBlock.header.timestamp_nanosec,
finalBlockHeight: finalBlock.header.height,
},
wamp
);
}
console.log("Regular final timestamp check is completed.");
} catch (error) {
console.warn("Regular final timestamp check crashed due to:", error);
}
setTimeout(regularCheckFinalTimestamp, regularQueryRPCInterval);
setTimeout(
regularPublishFinalityStatus,
regularPublishFinalityStatusInterval
);
};
setTimeout(regularCheckFinalTimestamp, 0);
setTimeout(regularPublishFinalityStatus, 0);

// regular check node status and publish to nodes uri
const regularCheckNodeStatus = async () => {
console.log("Starting regular node status check...");
// regularly publish information about validators, proposals, staking pools, and online nodes
const regularPublishNetworkInfo = async () => {
console.log("Starting regular network info publishing...");
try {
if (wamp.session) {
let {
currentValidators,
currentProposals,
seatPrice,
totalStake,
epochStartHeight,
epochLength,
} = await queryNodeStats();
validators = await addNodeInfo(currentValidators);
proposals = await addNodeInfo(currentProposals);
let onlineValidatingNodes = pickOnlineValidatingNode(validators);
let onlineNodes = await queryOnlineNodes();

if (validatorsExtraInfo) {
validators = validatorsExtraInfo;
}

if (proposalsExtraInfo) {
proposals = proposalsExtraInfo;
const epochStats = await queryEpochStats();
currentValidators = await extendWithTelemetryInfo(
epochStats.currentValidators
);
currentProposals = await extendWithTelemetryInfo(
epochStats.currentProposals
);
const onlineValidatingNodes = pickOnlineValidatingNode(
currentValidators
);
const onlineNodes = await queryOnlineNodes();

if (stakingPoolsInfo) {
currentValidators.forEach((validator) => {
const stakingPoolInfo = stakingPoolsInfo.get(validator.account_id);
if (stakingPoolInfo) {
validator.fee = stakingPoolInfo.fee;
validator.delegatorsCount = stakingPoolInfo.delegatorsCount;
}
});
currentProposals.forEach((validator) => {
const stakingPoolInfo = stakingPoolsInfo.get(validator.account_id);
if (stakingPoolInfo) {
validator.fee = stakingPoolInfo.fee;
validator.delegatorsCount = stakingPoolInfo.delegatorsCount;
}
});
}

wampPublish(
"nodes",
{ onlineNodes, validators, proposals, onlineValidatingNodes },
{
onlineNodes,
currentValidators,
currentProposals,
onlineValidatingNodes,
},
wamp
);
wampPublish(
"node-stats",
"network-stats",
{
validatorAmount: validators.length,
seatPriceAmount: seatPrice,
onlineNodeAmount: onlineNodes.length,
proposalAmount: proposals.length,
totalStakeAmount: totalStake,
epochStartHeight,
epochLength,
currentValidatorsCount: currentValidators.length,
currentProposalsCount: currentProposals.length,
onlineNodesCount: onlineNodes.length,
epochLength: epochStats.epochLength,
epochStartHeight: epochStats.epochStartHeight,
totalStake: epochStats.totalStake,
seatPrice: epochStats.seatPrice,
},
wamp
);
}
console.log("Regular node status check is completed.");
console.log("Regular regular network info publishing is completed.");
} catch (error) {
console.warn("Regular node status check crashed due to:", error);
console.warn(
"Regular regular network info publishing crashed due to:",
error
);
}
setTimeout(regularCheckNodeStatus, regularCheckNodeStatusInterval);
setTimeout(regularPublishNetworkInfo, regularPublishNetworkInfoInterval);
};
setTimeout(regularCheckNodeStatus, 0);

// Periodic check of validator's fee and delegators
const regularCheckValidatorsExtraInfo = async () => {
if (validators) {
validatorsExtraInfo = validatorsExtraInfo || validators;

for (let i = 0; i < validatorsExtraInfo.length; i++) {
const { account_id } = validatorsExtraInfo[i];
validatorsExtraInfo[i].fee = await nearRpc.callViewMethod(
account_id,
"get_reward_fee_fraction",
{}
);
validatorsExtraInfo[i].delegators = await nearRpc.callViewMethod(
account_id,
"get_number_of_accounts",
{}
);
}
}

if (proposals) {
proposalsExtraInfo = proposalsExtraInfo || proposals;

for (let i = 0; i < proposalsExtraInfo.length; i++) {
const { account_id } = proposalsExtraInfo[i];
proposalsExtraInfo[i].fee = await nearRpc.callViewMethod(
account_id,
"get_reward_fee_fraction",
{}
);
proposalsExtraInfo[i].delegators = await nearRpc.callViewMethod(
account_id,
"get_number_of_accounts",
{}
);
}
setTimeout(regularPublishNetworkInfo, 0);

// Periodic check of validators' staking pool fee and delegators count
const regularFetchStakingPoolsInfo = async () => {
const stakingPoolsAccountId = new Set([
...currentValidators.map(({ account_id }) => account_id),
...currentProposals.map(({ account_id }) => account_id),
]);

for (const stakingPoolAccountId of stakingPoolsAccountId) {
const fee = await nearRpc.callViewMethod(
stakingPoolAccountId,
"get_reward_fee_fraction",
{}
);
const delegatorsCount = await nearRpc.callViewMethod(
stakingPoolAccountId,
"get_number_of_accounts",
{}
);
stakingPoolsInfo.set(stakingPoolAccountId, { fee, delegatorsCount });
}
setTimeout(
regularCheckValidatorsExtraInfo,
regularCheckNodeValidatorsExtraInfo
regularFetchStakingPoolsInfo,
regularFetchStakingPoolsInfoInterval
);
};
setTimeout(regularCheckValidatorsExtraInfo, 0);
setTimeout(regularFetchStakingPoolsInfo, 0);

if (isLegacySyncBackendEnabled) {
await startLegacySync();
Expand Down
31 changes: 15 additions & 16 deletions backend/src/near.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,25 @@ nearRpc.callViewMethod = async function (contractName, methodName, args) {
return await account.viewFunction(contractName, methodName, args);
};

const queryFinalTimestamp = async () => {
const finalBlock = await nearRpc.sendJsonRpc("block", { finality: "final" });
return finalBlock.header.timestamp_nanosec;
const queryFinalBlock = async () => {
return await nearRpc.sendJsonRpc("block", { finality: "final" });
};

const queryNodeStats = async () => {
let networkProtocolConfig = await nearRpc.sendJsonRpc(
const queryEpochStats = async () => {
const networkProtocolConfig = await nearRpc.sendJsonRpc(
"EXPERIMENTAL_protocol_config",
{ finality: "final" }
);
let epochStatus = await nearRpc.sendJsonRpc("validators", [null]);
let numSeats =
const epochStatus = await nearRpc.sendJsonRpc("validators", [null]);
const numSeats =
networkProtocolConfig.num_block_producer_seats +
networkProtocolConfig.avg_hidden_validator_seats_per_shard.reduce(
(a, b) => a + b
);
let currentProposals = epochStatus.current_proposals;
let currentValidators = getCurrentNodes(epochStatus);
let { epoch_start_height: epochStartHeight } = epochStatus;
let { epoch_length: epochLength } = networkProtocolConfig;
const currentProposals = epochStatus.current_proposals;
const currentValidators = getCurrentNodes(epochStatus);
const { epoch_start_height: epochStartHeight } = epochStatus;
const { epoch_length: epochLength } = networkProtocolConfig;

if (currentEpochStartHeight !== epochStartHeight) {
// Update seat_price and total_stake each time when epoch starts
Expand All @@ -50,12 +49,12 @@ const queryNodeStats = async () => {
}

return {
epochLength,
epochStartHeight,
currentValidators,
currentProposals,
seatPrice,
totalStake,
epochStartHeight,
epochLength,
seatPrice,
};
};

Expand Down Expand Up @@ -85,5 +84,5 @@ const getCurrentNodes = (epochStatus) => {
};

exports.nearRpc = nearRpc;
exports.queryFinalTimestamp = queryFinalTimestamp;
exports.queryNodeStats = queryNodeStats;
exports.queryFinalBlock = queryFinalBlock;
exports.queryEpochStats = queryEpochStats;
Loading

0 comments on commit fb7ba55

Please sign in to comment.