Skip to content
Open
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
42 changes: 42 additions & 0 deletions test/e2e/benchmarks/mocks/mock-responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -517,3 +517,45 @@ export function solanaCatchAllResponse(id: string | number = '1337') {
},
};
}

const SOLANA_RPC_CONTEXT = { apiVersion: '2.0.18', slot: 308460925 };

const SOLANA_MAINNET_GENESIS_HASH =
'5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d';

/**
* Well-formed results for the Solana discovery JSON-RPC methods this suite does
* not mock individually.
*
* Ported from `SOLANA_DISCOVERY_RPC_RESULTS` in `test/e2e/mock-e2e.js`, which
* #43961 completed for the shared e2e environment. The benchmark suite is a
* separate mock implementation and never loaded that helper, so it kept the
* defect: every method below fell through to `solanaCatchAllResponse`, whose
* `{ context, value: null }` is the wrong shape for a genesis hash, a version
* object, a slot number or a health string. Malformed bodies throw inside the
* Solana snap and restart discovery — the ~516-request retry storm #43961
* measured, and the ~6.5s slow path #45266 sees on 37% of iterations.
*
* Each entry is the empty/identity result for a wallet with no Solana activity,
* which is what the benchmark fixtures represent.
*/
export const SOLANA_DISCOVERY_RPC_RESULTS: Record<string, unknown> = {
getGenesisHash: SOLANA_MAINNET_GENESIS_HASH,
getHealth: 'ok',
getVersion: { 'solana-core': '2.0.18', 'feature-set': 3271415109 },
getSlot: SOLANA_RPC_CONTEXT.slot,
getMultipleAccounts: { context: SOLANA_RPC_CONTEXT, value: [] },
getProgramAccounts: [],
getTokenAccountBalance: {
context: SOLANA_RPC_CONTEXT,
value: { amount: '0', decimals: 9, uiAmount: null, uiAmountString: '0' },
},
getEpochInfo: {
absoluteSlot: 308460925,
blockHeight: 286665030,
epoch: 762,
slotIndex: 156925,
slotsInEpoch: 432000,
transactionCount: 386021115957,
},
};
23 changes: 23 additions & 0 deletions test/e2e/benchmarks/mocks/performance-mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import {
SOLANA_SIMULATE_TRANSACTION,
SOLANA_GET_SIGNATURES_FOR_ADDRESS,
solanaCatchAllResponse,
SOLANA_DISCOVERY_RPC_RESULTS,
} from './mock-responses';

const AuthMocks = AuthenticationController.Mocks;
Expand Down Expand Up @@ -1169,6 +1170,28 @@ export async function mockBenchmarkEndpoints(
.thenCallback(delayedResponse(350, SOLANA_GET_SIGNATURES_FOR_ADDRESS)),
);

// The remaining discovery methods the Solana snap calls. Each is matched on
// its own method name, so these never shadow the handlers above; they only
// answer what would otherwise reach the catch-all with a wrong-shaped body.
// 100 ms matches the "simple calls" band in the table above.
for (const [method, result] of Object.entries(SOLANA_DISCOVERY_RPC_RESULTS)) {
endpoints.push(
await server
.forPost(SOLANA_URL_REGEX)
.withJsonBodyIncluding({ method })
.asPriority(MOCK_PRIORITIES.HIGH_PRIORITY)
.always()
.thenCallback(async (req) => {
const body = (await req.body.getJson()) as { id?: string };
await new Promise((resolve) => setTimeout(resolve, 100));
return {
statusCode: 200,
json: { id: body?.id ?? '1337', jsonrpc: '2.0', result },
};
}),
);
}

endpoints.push(
await server
.forPost(SOLANA_URL_REGEX)
Expand Down
Loading