Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 27 additions & 49 deletions src/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,6 @@ import {
} from "../workers/config.ts";
import { answerRpcUsage } from "./rpc-usage-answer.ts";
import { loadChainServingColdTier } from "./chain-serving-loader.ts";
import { enrichValidatorNominatorCounts } from "./validator-nominator-counts-cold-tier.ts";
import {
accountSummaryGapMessage,
answerAccountSummary,
Expand Down Expand Up @@ -3871,25 +3870,18 @@ const rootValue = {
// REST/MCP fan-out.
const details = [];
for (const hotkey of parsed) {
// #9146: enriched per detail, since nominator_count is one of the fields
// this comparison projects -- see the MCP compare_validators tool's own
// note for why an unenriched detail here would contradict the
// single-validator field for the same hotkey.
details.push(
await enrichValidatorNominatorCounts(
((await tryPostgresTier(
context.env,
((await tryPostgresTier(
context.env,
postgresTierRequest(
context,
`/api/v1/validators/${encodeURIComponent(hotkey)}`,
),
"METAGRAPH_NEURONS_SOURCE",
)) as Row | null) ??
buildValidatorDetail([], hotkey, {
priceByNetuid: NO_ALPHA_PRICES,
}),
),
postgresTierRequest(
context,
`/api/v1/validators/${encodeURIComponent(hotkey)}`,
),
"METAGRAPH_NEURONS_SOURCE",
)) as Row | null) ??
buildValidatorDetail([], hotkey, {
priceByNetuid: NO_ALPHA_PRICES,
}),
);
}
return composeValidatorComparison(details, { netuid: netuid ?? null });
Expand Down Expand Up @@ -4984,25 +4976,18 @@ const rootValue = {
const params = new URLSearchParams();
params.set("sort", requestedSort);
params.set("limit", String(GLOBAL_VALIDATOR_LIMIT_MAX));
// #9146: nominator_count has no D1 home, so the tier answers null for every
// row -- filled from the lakehouse by the same loader REST and MCP call.
// Applied before paginate() so a page carries the field regardless of which
// slice of the leaderboard the cursor lands on.
const data = (await enrichValidatorNominatorCounts(
context.env,
overlayFeaturedValidators(
((await tryPostgresTier(
context.env,
postgresTierRequest(context, "/api/v1/validators", params),
"METAGRAPH_NEURONS_SOURCE",
)) as Row | null) ??
buildGlobalValidators([], {
sort: requestedSort,
limit: GLOBAL_VALIDATOR_LIMIT_MAX,
priceByNetuid: NO_ALPHA_PRICES,
}),
)!,
)) as Row;
const data = overlayFeaturedValidators(
((await tryPostgresTier(
context.env,
postgresTierRequest(context, "/api/v1/validators", params),
"METAGRAPH_NEURONS_SOURCE",
)) as Row | null) ??
buildGlobalValidators([], {
sort: requestedSort,
limit: GLOBAL_VALIDATOR_LIMIT_MAX,
priceByNetuid: NO_ALPHA_PRICES,
}),
)! as Row;
const nodes = (data.validators || []).map(validatorNode);
const { page, total, nextCursor } = paginate(
nodes,
Expand Down Expand Up @@ -5137,20 +5122,13 @@ const rootValue = {
},

async validator({ hotkey }: QueryValidatorArgs, context: GqlContext) {
// #9146: the single-hotkey half of the same side-table gap the `validators`
// resolver fills. A null tier body carries no hotkey to look up, so the
// loader passes it straight through to validatorDetailNode's own
// normalization rather than needing a guard here.
const data = await enrichValidatorNominatorCounts(
const data = await tryPostgresTier(
context.env,
await tryPostgresTier(
context.env,
postgresTierRequest(
context,
`/api/v1/validators/${encodeURIComponent(hotkey)}`,
),
"METAGRAPH_NEURONS_SOURCE",
postgresTierRequest(
context,
`/api/v1/validators/${encodeURIComponent(hotkey)}`,
),
"METAGRAPH_NEURONS_SOURCE",
);
return validatorDetailNode(data as Row, hotkey);
},
Expand Down
49 changes: 17 additions & 32 deletions src/mcp-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -993,7 +993,6 @@ import { CHAIN_SIGNERS_SORTS } from "./chain-query-loaders.ts";
import { loadBulkHealthTrends } from "./bulk-health-trends.ts";
import { answerRpcUsage } from "./rpc-usage-answer.ts";
import { loadChainServingColdTier } from "./chain-serving-loader.ts";
import { enrichValidatorNominatorCounts } from "./validator-nominator-counts-cold-tier.ts";
import {
accountSummaryGapMessage,
answerAccountSummary,
Expand Down Expand Up @@ -6675,21 +6674,17 @@ export const MCP_TOOLS: McpToolDefinition[] = [
GLOBAL_VALIDATOR_LIMIT_DEFAULT,
GLOBAL_VALIDATOR_LIMIT_MAX,
);
// #9146: nominator_count has no D1 home, so the tier answers null for
// every row -- filled from the lakehouse by the same loader REST and
// GraphQL call.
return await enrichValidatorNominatorCounts(
ctx.env,
return (
(await tryPostgresTier(
ctx.env,
mcpNeuronsTierRequest("/api/v1/validators", { sort, limit }),
"METAGRAPH_NEURONS_SOURCE",
)) ??
buildGlobalValidators([], {
sort,
limit,
priceByNetuid: NO_ALPHA_PRICES,
}),
buildGlobalValidators([], {
sort,
limit,
priceByNetuid: NO_ALPHA_PRICES,
})
);
},
},
Expand All @@ -6711,17 +6706,15 @@ export const MCP_TOOLS: McpToolDefinition[] = [
ctx: McpCtx,
) {
const hotkey = requireHotkey(args);
// #9146: same side-table gap as list_global_validators, one hotkey wide.
return await enrichValidatorNominatorCounts(
ctx.env,
return (
(await tryPostgresTier(
ctx.env,
mcpNeuronsTierRequest(
`/api/v1/validators/${encodeURIComponent(hotkey)}`,
),
"METAGRAPH_NEURONS_SOURCE",
)) ??
buildValidatorDetail([], hotkey, { priceByNetuid: NO_ALPHA_PRICES }),
buildValidatorDetail([], hotkey, { priceByNetuid: NO_ALPHA_PRICES })
);
},
},
Expand Down Expand Up @@ -6761,25 +6754,17 @@ export const MCP_TOOLS: McpToolDefinition[] = [
// fan-out's request pattern identical to N get_validator_detail calls.
const details = [];
for (const hotkey of hotkeys) {
// #9146: enriched per detail, inside the loop, because nominator_count
// is one of the fields this comparison projects (and one of the four
// this tool's own description promises) -- an unenriched detail here
// would answer null for it while get_validator_detail answered a
// number for the same hotkey.
details.push(
await enrichValidatorNominatorCounts(
(await tryPostgresTier(
ctx.env,
(await tryPostgresTier(
ctx.env,
mcpNeuronsTierRequest(
`/api/v1/validators/${encodeURIComponent(hotkey)}`,
),
"METAGRAPH_NEURONS_SOURCE",
)) ??
buildValidatorDetail([], hotkey, {
priceByNetuid: NO_ALPHA_PRICES,
}),
),
mcpNeuronsTierRequest(
`/api/v1/validators/${encodeURIComponent(hotkey)}`,
),
"METAGRAPH_NEURONS_SOURCE",
)) ??
buildValidatorDetail([], hotkey, {
priceByNetuid: NO_ALPHA_PRICES,
}),
);
}
return composeValidatorComparison(details, { netuid });
Expand Down
146 changes: 0 additions & 146 deletions src/validator-nominator-counts-cold-tier.ts

This file was deleted.

Loading