All checks were successful
deploy / deploy (push) Successful in 58s
Proof: quote-response execution now uses verifierSaltCache.getCachedFreshSalt() only, rejects verifier_salt_unavailable before signing or relay when no fresh cached salt exists, preserves stale command expiry before salt lookup, exposes salt cache and executor queue-delay state in health/sentinel/dashboard surfaces, and is covered by targeted regression tests plus full npm test and dashboard build. Assumptions: the existing verifier salt freshness policy remains safe for cached signing use; fixed in-code queue-delay warning thresholds are sufficient for operator alerts without new latency env vars; no strategy selection, pricing, edge, notional, inventory, arming, signer, or pair enablement behavior changed. Still fake: venue-native terminal fill ids and fee-complete realized PnL remain unavailable; executor concurrency remains single-consumer; live post-deploy evidence still needs collection after repo-workflow deployment.
71 lines
3.4 KiB
JavaScript
71 lines
3.4 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { readFileSync } from 'node:fs';
|
|
|
|
const source = readFileSync(new URL('../src/apps/trade-executor.mjs', import.meta.url), 'utf8');
|
|
|
|
test('trade executor dispatches each execute command once', () => {
|
|
const calls = source.match(/await handleCommand\(event\);/g) || [];
|
|
assert.equal(calls.length, 1);
|
|
});
|
|
|
|
test('own request preflight suppresses maker quote responses to avoid self-matching', () => {
|
|
assert.match(source, /withMakerSuppressed/);
|
|
assert.match(source, /own_request_preflight_in_progress/);
|
|
assert.match(source, /avoid self-matching/);
|
|
});
|
|
|
|
test('trade executor fails closed on stale execute commands before relay submission', () => {
|
|
assert.match(source, /classifyExecuteCommandExpiry/);
|
|
assert.match(source, /stale_execute_command/);
|
|
assert.match(source, /deadline elapsed before relay submission/);
|
|
});
|
|
|
|
test('trade executor exposes summarized durable command state', () => {
|
|
assert.match(source, /stateStore\.getSummary\(\{ limit: 50 \}\)/);
|
|
assert.doesNotMatch(source, /durable_state:\s*stateStore\.getState\(\)/);
|
|
});
|
|
|
|
test('trade executor records hot path timing in result payloads', () => {
|
|
assert.match(source, /node:perf_hooks/);
|
|
assert.match(source, /startExecutorTiming\(event\)/);
|
|
assert.match(source, /executor_timing/);
|
|
assert.match(source, /command_to_executor_ms/);
|
|
assert.match(source, /current_salt_ms/);
|
|
assert.match(source, /sign_ms/);
|
|
assert.match(source, /relay_response_ms/);
|
|
assert.match(source, /executor_total_ms/);
|
|
assert.match(source, /withExecutorTiming\(\{[\s\S]*?result_code: 'submission_failed'/);
|
|
});
|
|
|
|
test('trade executor uses bounded verifier salt cache instead of per-command salt RPC', () => {
|
|
assert.match(source, /createVerifierSaltCache/);
|
|
assert.match(source, /verifierSaltCache\.start\(\)/);
|
|
assert.match(source, /verifierSaltCache\.getCachedFreshSalt\(\)/);
|
|
assert.match(source, /verifier_salt_unavailable/);
|
|
assert.match(source, /fresh verifier salt unavailable; command was not signed or relayed/);
|
|
assert.match(source, /current_salt_source/);
|
|
assert.match(source, /current_salt_age_ms/);
|
|
assert.match(source, /current_salt_unavailable_reason/);
|
|
assert.match(source, /verifier_salt_cache: verifierSaltCache\.getState\(\)/);
|
|
assert.match(source, /verifierSaltCache\.stop\(\)/);
|
|
assert.doesNotMatch(source, /verifierSaltCache\.getFreshSalt\(\)/);
|
|
assert.doesNotMatch(source, /await verifierClient\.currentSalt\(\);/);
|
|
|
|
const expiryIndex = source.indexOf('const expiry = classifyExecuteCommandExpiry(event);');
|
|
const saltLookupIndex = source.indexOf('verifierSaltCache.getCachedFreshSalt()');
|
|
const saltUnavailableIndex = source.indexOf("result_code: 'verifier_salt_unavailable'");
|
|
const signIndex = source.indexOf('buildQuoteResponseSubmission({');
|
|
const relayIndex = source.indexOf("relayClient.request('quote_response'");
|
|
assert.ok(expiryIndex > 0 && expiryIndex < saltLookupIndex);
|
|
assert.ok(saltUnavailableIndex > 0 && saltUnavailableIndex < signIndex);
|
|
assert.ok(saltUnavailableIndex < relayIndex);
|
|
});
|
|
|
|
test('trade executor exposes queue delay and salt rejection state', () => {
|
|
assert.match(source, /createExecutorQueueDelayTracker/);
|
|
assert.match(source, /recordExecutorQueueDelay\(timing, payload\)/);
|
|
assert.match(source, /executor_queue_delay: executorQueueDelayTracker\.getState\(\)/);
|
|
assert.match(source, /salt_unavailable_reject_count/);
|
|
assert.match(source, /last_salt_unavailable_at/);
|
|
});
|