Skip to content

Commit ccd661b

Browse files
committed
fix(API): short-circuit read-only path before heavy imports and tighten network match
Two fixes from bugbot review of #1627: 1. Move dynamic imports of wallet / fullNodeRpc / persistance / V1+V2 models / fullNode AFTER the read-only short-circuit. The PR description said the read-only path short-circuits before fetch, but the heavy imports were happening unconditionally, which (a) made public observer nodes load DB and wallet modules they don't need and (b) caused /diagnostics to fail in the exact scenarios it's designed to survive (e.g. V2 model module body failing to initialize). 2. Use exact equality (not substring containment) for the network match. `"testnet10".includes("testnet1")` is true, so the previous code reported a false match when the configured network was a prefix of the actual one. The diagnostics endpoint's job is to tell the truth; the existing assertChiaNetworkMatchInConfiguration still uses the substring rule, but the `actual` and `configured` fields in the response let operators spot whether the loose-match assertion would also have considered them equivalent.
1 parent 367ff89 commit ccd661b

1 file changed

Lines changed: 24 additions & 8 deletions

File tree

src/routes/diagnostics.js

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -225,21 +225,29 @@ const buildTrustedPeerView = (connectionsResult, chiaConfigResult) => {
225225
export const getDiagnosticsResponse = async ({ readOnly = false } = {}) => {
226226
const timestamp = new Date().toISOString();
227227

228-
const wallet = (await import('../datalayer/wallet.js')).default;
229-
const fullNodeRpc = (await import('../datalayer/fullNodeRpc.js')).default;
230-
const persistance = await import('../datalayer/persistance.js');
231-
const { Organization } = await import('../models/index.js');
232-
const { OrganizationsV2 } = await import('../models/v2/index.js');
233-
const fullNodeModule = await import('../datalayer/fullNode.js');
234-
235228
const configV1 = getConfig();
236229
const configV2 = getConfigV2();
237230
const appConfig = configV1.APP || {};
238231

232+
// Short-circuit BEFORE pulling in the heavy wallet/datalayer/model
233+
// dependencies. The read-only path only needs system-info / process-scan /
234+
// chia-tools probes plus the synchronously-available config, so importing
235+
// wallet.js or models/v2/index.js here would (a) defeat the "no
236+
// authenticated RPC on unauthenticated public hits" property and (b)
237+
// make /diagnostics itself fail whenever the DB/wallet modules can't
238+
// initialize -- which is precisely the failure mode this endpoint exists
239+
// to diagnose.
239240
if (readOnly) {
240241
return buildReadOnlyResponse({ timestamp, configV1, configV2, appConfig });
241242
}
242243

244+
const wallet = (await import('../datalayer/wallet.js')).default;
245+
const fullNodeRpc = (await import('../datalayer/fullNodeRpc.js')).default;
246+
const persistance = await import('../datalayer/persistance.js');
247+
const { Organization } = await import('../models/index.js');
248+
const { OrganizationsV2 } = await import('../models/v2/index.js');
249+
const fullNodeModule = await import('../datalayer/fullNode.js');
250+
243251
// Kick off every external call in parallel. None of these can throw.
244252
const [
245253
activeNetworkRes,
@@ -340,12 +348,20 @@ export const getDiagnosticsResponse = async ({ readOnly = false } = {}) => {
340348
};
341349

342350
// ---- Chia: network match ------------------------------------------------
351+
// We use exact equality here, NOT the substring semantics of
352+
// assertChiaNetworkMatchInConfiguration (which treats `CHIA_NETWORK:
353+
// "testnet"` as matching any actual network containing "testnet"). That
354+
// substring rule has a real false-positive: `"testnet10".includes("testnet1")`
355+
// is true. The diagnostics endpoint's job is to surface the truth so
356+
// operators can spot a stale or mistyped config; the `actual` and
357+
// `configured` fields above let them judge whether the existing assertion
358+
// would also have considered them a match.
343359
const actualNetwork = activeNetworkRes.ok
344360
? activeNetworkRes.value?.network_name || null
345361
: null;
346362
const configuredNetwork = appConfig.CHIA_NETWORK || null;
347363
const networkMatches =
348-
actualNetwork && configuredNetwork ? actualNetwork.includes(configuredNetwork) : null;
364+
actualNetwork && configuredNetwork ? actualNetwork === configuredNetwork : null;
349365

350366
// ---- Chia: wallet -------------------------------------------------------
351367
// connectionError is non-empty whenever the wallet is unreachable, even

0 commit comments

Comments
 (0)