Skip to content

Commit

Permalink
implement getVoters API with MongoDB and Elasticsearch support
Browse files Browse the repository at this point in the history
  • Loading branch information
lealbrunocalhau committed Nov 13, 2024
1 parent 2b2f8c4 commit 9bde6d9
Show file tree
Hide file tree
Showing 5 changed files with 345 additions and 38 deletions.
94 changes: 57 additions & 37 deletions src/api/routes/v2-state/get_voters/get_voters.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,83 @@
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
import {timedQuery} from "../../../helpers/functions.js";
import {getSkipLimit} from "../../v2-history/get_actions/functions.js";
import {estypes} from "@elastic/elasticsearch";
import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { timedQuery } from "../../../helpers/functions.js";
import { getSkipLimit } from "../../v2-history/get_actions/functions.js";

async function getVoters(fastify: FastifyInstance, request: FastifyRequest) {
import { estypes } from "@elastic/elasticsearch";
import { IVoter } from "../../../../interfaces/table-voter.js";

async function getVoters(fastify: FastifyInstance, request: FastifyRequest) {
console.log(`Entrei no getVoters`);
const query: any = request.query;
const {skip, limit} = getSkipLimit(request.query);
const { skip, limit } = getSkipLimit(request.query);
const maxDocs = fastify.manager.config.api.limits.get_voters ?? 100;

const response: any = {
voter_count: 0,
'voters': []
};
let queryStruct: any = {
"bool": {
"must": []
}
voters: []
};

if (query.producer) {
for (const bp of query.producer.split(",")) {
queryStruct.bool.must.push({"term": {"producers": bp}});
let stateResult: IVoter[];

if (fastify.manager.config.indexer.experimental_mongodb_state && fastify.manager.conn.mongodb && query.useMongo === 'true') {
const dbName = `${fastify.manager.conn.mongodb.database_prefix}_${fastify.manager.chain}`;
const collection = fastify.mongo.client.db(dbName).collection<IVoter>('voters');

const mongoQuery: any = {};
if (query.producer) {
mongoQuery.producers = { $all: query.producer.split(",") };
}
if (query.proxy === 'true') {
mongoQuery.is_proxy = true;
}
}

if (query.proxy === 'true') {
queryStruct.bool.must.push({"term": {"is_proxy": true}});
}
response.voter_count = await collection.countDocuments(mongoQuery);

if (queryStruct.bool.must.length === 0) {
queryStruct = {
"match_all": {}
};
stateResult = await collection
.find(mongoQuery, { projection: { _id: 0, voter: 1, last_vote_weight: 1, block_num: 1 } })
.skip(skip || 0)
.limit(limit || 50)
.toArray();

console.log(`State Result mongo:`);
} else {
let queryStruct: any = { bool: { must: [] } };
if (query.producer) {
for (const bp of query.producer.split(",")) {
queryStruct.bool.must.push({ term: { producers: bp } });
}
}
if (query.proxy === 'true') {
queryStruct.bool.must.push({ term: { is_proxy: true } });
}
if (queryStruct.bool.must.length === 0) {
queryStruct = { match_all: {} };
}

const esResult = await fastify.elastic.search<any>({
index: `${fastify.manager.chain}-table-voters-*`,
from: skip || 0,
size: (limit > maxDocs ? maxDocs : limit) || 10,
query: queryStruct,
sort: [{ last_vote_weight: "desc" }]
});
stateResult = esResult.hits.hits.map((hit: any) => hit._source);
console.log(`State Result elastic:`);
response.voter_count = (esResult.hits.total as estypes.SearchTotalHits).value;
}

const maxDocs = fastify.manager.config.api.limits.get_voters ?? 100;
const results = await fastify.elastic.search<any>({
"index": fastify.manager.chain + '-table-voters-*',
"from": skip || 0,
"size": (limit > maxDocs ? maxDocs : limit) || 10,
"query": queryStruct,
"sort": [{"last_vote_weight": "desc"}]
});
const hits = results.hits.hits;
for (const hit of hits) {
const voter = hit._source;
for (const voter of stateResult) {
response.voters.push({
account: voter.voter,
weight: voter.last_vote_weight,
last_vote: voter.block_num
});
}
console.log(results.hits.total);
response.voter_count = (results.hits.total as estypes.SearchTotalHits).value;

return response;
}

export function getVotersHandler(fastify: FastifyInstance, route: string) {
return async (request: FastifyRequest, reply: FastifyReply) => {
reply.send(await timedQuery(getVoters, fastify, request, route));
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { timedQuery } from "../../../helpers/functions.js";
import { getSkipLimit } from "../../v2-history/get_actions/functions.js";

import { estypes } from "@elastic/elasticsearch";
import { IVoter } from "../../../../interfaces/table-voter.js";

async function getVoters(fastify: FastifyInstance, request: FastifyRequest) {
console.log(`Entrei no getVoters`);
const query: any = request.query;
const { skip, limit } = getSkipLimit(request.query);
const maxDocs = fastify.manager.config.api.limits.get_voters ?? 100;

const response: any = {
voter_count: 0,
voters: []
};

let stateResult: IVoter[];

if (fastify.manager.config.indexer.experimental_mongodb_state && fastify.manager.conn.mongodb) {
const dbName = `${fastify.manager.conn.mongodb.database_prefix}_${fastify.manager.chain}`;
const collection = fastify.mongo.client.db(dbName).collection<IVoter>('voters');

const mongoQuery: any = {};
if (query.producer) {
mongoQuery.producers = { $all: query.producer.split(",") };
}
if (query.proxy === 'true') {
mongoQuery.is_proxy = true;
}

stateResult = await collection
.find(mongoQuery, { projection: { _id: 0, voter: 1, last_vote_weight: 1, block_num: 1 } })
.skip(skip || 0)
.limit(limit || 50)
.toArray();

console.log(`State Result mongo:`);
} else {
let queryStruct: any = { bool: { must: [] } };
if (query.producer) {
for (const bp of query.producer.split(",")) {
queryStruct.bool.must.push({ term: { producers: bp } });
}
}
if (query.proxy === 'true') {
queryStruct.bool.must.push({ term: { is_proxy: true } });
}
if (queryStruct.bool.must.length === 0) {
queryStruct = { match_all: {} };
}

const esResult = await fastify.elastic.search<any>({
index: `${fastify.manager.chain}-table-voters-*`,
from: skip || 0,
size: Math.min(limit, maxDocs) || 10,
query: queryStruct,
sort: [{ last_vote_weight: "desc" }]
});
stateResult = esResult.hits.hits.map((hit: any) => hit._source);
console.log(`State Result elastic:`);
response.voter_count = (esResult.hits.total as estypes.SearchTotalHits).value;
}

for (const voter of stateResult) {
response.voters.push({
account: voter.voter,
weight: voter.last_vote_weight,
last_vote: voter.block_num
});
}

return response;
}

export function getVotersHandler(fastify: FastifyInstance, route: string) {
return async (request: FastifyRequest, reply: FastifyReply) => {
reply.send(await timedQuery(getVoters, fastify, request, route));
};
}
1 change: 0 additions & 1 deletion src/api/routes/v2-state/get_voters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export default function (fastify: FastifyInstance, opts: any, next) {
description: 'filter by voted producer (comma separated)',
type: 'string',
minLength: 1,
maxLength: 12
}
}),
response: extendResponseSchema({
Expand Down
Loading

0 comments on commit 9bde6d9

Please sign in to comment.