You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(complexity): price the SDK's real queries and size the default limit for them
The wbclient full-detail account-history query measures 10,101 at
first:100 — over the previous 10,000 default — because the shared
stateChangeFragments const gained 8 Blend fragments (+27 fields per
state-change node, ×100 edges). The regression test could not catch this:
it asserted a hand-copied mirror of the SDK query that had drifted (no
Blend fragments, aliases the builder never emits), and the integration
container overrode the limit to 30,000.
pkg/wbclient now exports Queries(), the exact documents the client
sends, and both server-side guards consume it: schema validation (which
previously missed the three Blend queries) and the complexity regression
test, which prices every SDK query at the largest accepted page size
against the flag's own FlagDefault. Measured: BlendPools=26,150,
full-detail history=10,101, state-change queries=8,401,
blendPositions=7,583.
The default limit rises to 30,000, documented as sized for the SDK's
heaviest shipped queries with the DoS tradeoff stated (deployments not
serving Blend should lower it). The integration container no longer
overrides GRAPHQL_COMPLEXITY_LIMIT, so the suite proves the shipped
default serves the SDK's full-selection queries end-to-end.
Usage: "The maximum complexity limit for GraphQL queries. Complexity is calculated based on fields and pagination parameters. gqlgen sums mutually exclusive inline fragments, so the limit must accommodate a full-detail query selecting every BaseStateChange implementer (~7600 at first:100).",
197
+
Usage: "The maximum complexity limit for GraphQL queries, computed from the selected fields and the pagination arguments. The default admits the heaviest queries pkg/wbclient ships: the full-detail account-history query costs ~10,100 at first:100 (gqlgen sums mutually exclusive inline fragments, so every BaseStateChange implementer is charged), and the blendPools catalog query ~26,150. This limit is the primary guard against resource exhaustion via expensive queries, so a deployment that does not serve Blend should lower it.",
t.Logf("%s: computed complexity at first:%d = %d", name, maxRequestedPageSize, c)
241
85
242
-
require.Greater(t, c, tc.floor, "query should be substantial enough to be a meaningful worst case; a near-zero value likely means LoadQuery silently dropped selections")
243
-
require.Less(t, c, 10_000, "freighter's full-detail query must stay under the default complexity limit (GRAPHQL_COMPLEXITY_LIMIT=10000)")
86
+
require.Positive(t, c, "a zero complexity means LoadQueryWithRules silently dropped the selection set")
87
+
iffloor, ok:=substantialQueryFloors[name]; ok {
88
+
require.Greater(t, c, floor, "query should be substantial enough to be a meaningful worst case")
89
+
}
90
+
require.LessOrEqual(t, c, limit, "every query the SDK ships must be servable under the default complexity limit (%d)", limit)
t.Logf("freighter transactions query complexity with a hypothetical AccountTransactionEdge multiplier = %d", regressed)
283
-
require.Greater(t, regressed, 10_000, "this confirms the guard above is load-bearing: without it, the freighter transactions query blows the complexity limit")
t.Logf("full-detail account-history query complexity with a hypothetical AccountTransactionEdge multiplier = %d", regressed)
132
+
require.Greater(t, regressed, defaultComplexityLimit(t), "this confirms the guard above is load-bearing: without it, the full-detail account-history query blows the complexity limit")
0 commit comments