Skip to content

Commit

Permalink
refactor getVoters API by removing debug logs and enhance getProposal…
Browse files Browse the repository at this point in the history
…s response schema with detailed proposal structure
  • Loading branch information
lealbrunocalhau committed Nov 14, 2024
1 parent 2de952a commit 5b65680
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 74 deletions.
181 changes: 112 additions & 69 deletions src/api/routes/v2-state/get_proposals/get_proposals.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
import {getTrackTotalHits, timedQuery} from "../../../helpers/functions.js";
import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import { getTrackTotalHits, timedQuery } from "../../../helpers/functions.js";
import { estypes } from '@elastic/elasticsearch';

async function getProposals(fastify: FastifyInstance, request: FastifyRequest) {

const query: any = request.query;

// Pagination
Expand All @@ -17,87 +17,130 @@ async function getProposals(fastify: FastifyInstance, request: FastifyRequest) {
return 'invalid limit parameter';
}

let queryStruct: any = {
"bool": {
"must": []
}
const maxDocs = fastify.manager.config.api.limits.get_proposals ?? 100;

const response: any = {
query_time_ms: 0,
cached: false,
total: 0,
proposals: [],
last_indexed_block: 0,
last_indexed_block_time: ''
};

// Filter by accounts
if (query.account) {
const accounts = query.account.split(',');
for(const acc of accounts) {
queryStruct.bool.must.push({
"bool": {
"should": [
{"term": {"requested_approvals.actor": acc}},
{"term": {"provided_approvals.actor": acc}}
]
}
});
let stateResult: any[];
const startTime = Date.now(); // Inicia o cronômetro para a consulta

// Verifica se a consulta deve ser feita no MongoDB
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('proposals');

const mongoQuery: any = {};
if (query.account) {
const accounts = query.account.split(',');
mongoQuery.$or = [
{ "requested_approvals.actor": { $in: accounts } },
{ "provided_approvals.actor": { $in: accounts } }
];
}
if (query.proposer) {
mongoQuery.proposer = query.proposer;
}
if (query.proposal) {
mongoQuery.proposal_name = query.proposal;
}
if (typeof query.executed !== 'undefined') {
mongoQuery.executed = query.executed;
}
if (query.requested) {
mongoQuery["requested_approvals.actor"] = query.requested;
}
if (query.provided) {
mongoQuery["provided_approvals.actor"] = query.provided;
}
}

// Filter by proposer account
if (query.proposer) {
queryStruct.bool.must.push({"term": {"proposer": query.proposer}});
}

// Filter by proposal name
if (query.proposal) {
queryStruct.bool.must.push({"term": {"proposal_name": query.proposal}});
}

// Filter by execution status
if (typeof query.executed !== 'undefined') {
queryStruct.bool.must.push({"term": {"executed": query.executed}});
}
// Consultar MongoDB
console.log(`Consultar Mongo`)
const lastBlockResult = await fastify.mongo.client.db(dbName).collection('proposals').find().sort({ block_num: -1 }).limit(1).toArray();
response.last_indexed_block = lastBlockResult[0]?.block_num || 0;
response.last_indexed_block_time = lastBlockResult[0]?.block_time || '';

response.total = await collection.countDocuments(mongoQuery);
stateResult = await collection
.find(mongoQuery)
.skip(skip || 0)
.limit(limit || 50)
.toArray();

} else {
// Caso não seja no MongoDB, faz a consulta no Elasticsearch
console.log(`Consultar Elastic`)
let queryStruct: any = { bool: { must: [] } };
if (query.account) {
const accounts = query.account.split(',');
for (const acc of accounts) {
queryStruct.bool.must.push({
bool: {
should: [
{ term: { "requested_approvals.actor": acc } },
{ term: { "provided_approvals.actor": acc } }
]
}
});
}
}
if (query.proposer) {
queryStruct.bool.must.push({ term: { proposer: query.proposer } });
}
if (query.proposal) {
queryStruct.bool.must.push({ term: { proposal_name: query.proposal } });
}
if (typeof query.executed !== 'undefined') {
queryStruct.bool.must.push({ term: { executed: query.executed } });
}
if (query.requested) {
queryStruct.bool.must.push({ term: { "requested_approvals.actor": query.requested } });
}
if (query.provided) {
queryStruct.bool.must.push({ term: { "provided_approvals.actor": query.provided } });
}

// Filter by requested actors
if (query.requested) {
queryStruct.bool.must.push({"term": {"requested_approvals.actor": query.requested}});
}
if (queryStruct.bool.must.length === 0) {
queryStruct = { match_all: {} };
}

// Filter by provided actors
if (query.provided) {
queryStruct.bool.must.push({"term": {"provided_approvals.actor": query.provided}});
// Consultar Elasticsearch
const esResult = await fastify.elastic.search<any>({
index: `${fastify.manager.chain}-table-proposals-*`,
from: skip || 0,
size: (limit > maxDocs ? maxDocs : limit) || 10,
track_total_hits: getTrackTotalHits(request.query),
query: queryStruct,
sort: [{ block_num: "desc" }]
});

stateResult = esResult.hits.hits.map((hit: any) => hit._source);
response.total = (esResult.hits.total as estypes.SearchTotalHits).value;

// Pegando o último bloco indexado
response.last_indexed_block = esResult.hits.hits.length > 0 ? esResult.hits.hits[0]._source.block_num : 0;
response.last_indexed_block_time = esResult.hits.hits.length > 0 ? esResult.hits.hits[0]._source.block_time : '';
}

// If no filter switch to full match
if (queryStruct.bool.must.length === 0) {
queryStruct = {
"match_all": {}
};
// Formatar resposta com os dados obtidos
for (const proposal of stateResult) {
response.proposals.push(proposal);
}

const maxDocs = fastify.manager.config.api.limits.get_proposals ?? 100;
const results = await fastify.elastic.search<any>({
"index": fastify.manager.chain + '-table-proposals-*',
"from": skip || 0,
"size": (limit > maxDocs ? maxDocs : limit) || 10,
"track_total_hits": getTrackTotalHits(request.query),
"query": queryStruct,
"sort": [{"block_num": "desc"}]
});

const response: any = {
query_time: null,
cached: false,
total: results.hits.total,
proposals: []
};

const hits = results.hits.hits;
for (const hit of hits) {
const prop = hit._source;
response.proposals.push(prop);
}
// Calculando o tempo de consulta
response.query_time_ms = Date.now() - startTime;

return response;
}

export function getProposalsHandler(fastify: FastifyInstance, route: string) {
return async (request: FastifyRequest, reply: FastifyReply) => {
reply.send(await timedQuery(getProposals, fastify, request, route));
}
};
}
92 changes: 90 additions & 2 deletions src/api/routes/v2-state/get_proposals/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {FastifyInstance} from "fastify";
import {getProposalsHandler} from "./get_proposals.js";
import {addApiRoute, getRouteName} from "../../../helpers/functions.js";
import {addApiRoute, extendResponseSchema, getRouteName} from "../../../helpers/functions.js";

export default function (fastify: FastifyInstance, opts: any, next) {
const schema = {
Expand Down Expand Up @@ -49,8 +49,96 @@ export default function (fastify: FastifyInstance, opts: any, next) {
minimum: 1
}
}
}
},
response: extendResponseSchema({
total: {
type: "object",
properties: {
value: {type: "number"},
relation: {type: "string"}
}
},
proposals: {
type: "array",
items: {
type: "object",
properties: {
proposal_name: { type: "string" },
block_num: { type: "number" },
proposer: { type: "string" },
executed: { type: "boolean" },
primary_key: { type: "string" },
trx: {
type: "object",
properties: {
expiration: { type: "string" },
ref_block_num: { type: "number" },
ref_block_prefix: { type: "number" },
max_net_usage_words: { type: "number" },
max_cpu_usage_ms: { type: "number" },
delay_sec: { type: "number" },
context_free_actions: { type: "array", items: { type: "object" } },
actions: {
type: "array",
items: {
type: "object",
properties: {
account: { type: "string" },
name: { type: "string" },
authorization: {
type: "array",
items: {
type: "object",
properties: {
actor: { type: "string" },
permission: { type: "string" }
}
}
},
data: {
type: "object",
properties: {
from: { type: "string" },
to: { type: "string" },
quantity: { type: "string" },
memo: { type: "string" }
}
}
}
}
},
transaction_extensions: { type: "array", items: { type: "object" } }
}
},
requested_approvals: {
type: "array",
items: {
type: "object",
properties: {
actor: { type: "string" },
permission: { type: "string" },
time: { type: "string" }
}
}
},
provided_approvals: {
type: "array",
items: {
type: "object",
properties: {
actor: { type: "string" },
permission: { type: "string" },
time: { type: "string" }
}
}
},
earliest_exec_time: { type: "string", nullable: true }
}
}
}
})
};

addApiRoute(
fastify,
'GET',
Expand Down
3 changes: 0 additions & 3 deletions src/api/routes/v2-state/get_voters/get_voters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ 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;
Expand Down Expand Up @@ -38,7 +37,6 @@ async function getVoters(fastify: FastifyInstance, request: FastifyRequest) {
.limit(limit || 50)
.toArray();

console.log(`State Result mongo:`);
} else {
let queryStruct: any = { bool: { must: [] } };
if (query.producer) {
Expand All @@ -61,7 +59,6 @@ async function getVoters(fastify: FastifyInstance, request: FastifyRequest) {
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;
}

Expand Down

0 comments on commit 5b65680

Please sign in to comment.