Skip to Content
GuidesStress Testing

Stress Testing

stressTest runs adversarial scenarios against your policy and produces a risk report. Six attack vectors probe different failure modes — timing races, coordinated drains, RPC failures, staleness, boundary conditions, and approval floods.

Installation

npm install @txfence/verify

Basic usage

import { stressTest } from '@txfence/verify' const report = await stressTest(policy, { agentCount: 10, transactionsPerScenario: 20, timingJitterMs: 100, timeoutMs: 5000, }) console.log(`Survival rate: ${report.survivalRate * 100}%`) console.log(`Recommendation: ${report.recommendation}`)

StressTestConfig fields: agentCount, transactionsPerScenario, timingJitterMs, rpcFailureRate, vectors, seed, timeoutMs — all optional.

Six attack vectors

rapid_fire

One agent submits N transactions in rapid succession, each just under the per-tx cap. Tests timing races against the cap lock. Three scenarios: simultaneous burst, jittered burst, multi-agent burst.

coordinated_drain

Multiple agents coordinate to drain a shared cap simultaneously. Tests whether two-phase cap locking prevents collective over-spend. Three scenarios: simultaneous, 1ms-staggered, two-wave.

rpc_failure

Injects RPC failures at simulation and execution stages. Tests that the pipeline returns well-defined results rather than throwing unhandled exceptions. Three scenarios: simulation-stage failure, execution-stage failure, intermittent failure.

stale_simulation

Injects simulation staleness beyond the configured threshold. Tests the simulationStalenessMs check. Two scenarios: 2× threshold, threshold+1.

cap_boundary

Off-by-one tests around maxSpendPerTx. Tests exact cap, cap+1n, cap-1n, and zero amount. Four scenarios.

approval_flood

Multiple agents simultaneously submit transactions above the approval threshold. Tests approval timeout handling. Two scenarios.

chain_reorg (opt-in)

A seventh attack vector exists in the AttackVector type but is not included in DEFAULT_VECTORS. Opt in explicitly via the vectors option if you want to exercise reorg handling — useful when running on chains with frequent reorgs or testing your monitor’s onReorgDetected callback.

RiskReport

type RiskReport = { policy: Policy totalScenarios: number survived: number failed: number survivalRate: number // survived / totalScenarios failedScenarios: ScenarioResult[] // sorted by severity byVector: Partial<Record<AttackVector, VectorStats>> bySeverity: Partial<Record<ScenarioSeverity, number>> generatedAt: number durationMs: number recommendation: string // actionable guidance }

recommendation suggests circuit breaker, rate limiting, cap tuning, or other mitigations based on failure patterns.

ScenarioOutcome

type ScenarioOutcome = | 'survived' // pipeline returned a well-defined ExecutionResult | 'system_error' // unhandled exception escaped runPipeline | 'timeout' // scenario exceeded timeoutMs | 'false_acceptance' // reserved for future detection | 'false_rejection' // reserved for future detection

system_error is the most serious outcome — it means an exception escaped the pipeline boundary.

Selecting vectors

const report = await stressTest(policy, { vectors: ['rapid_fire', 'cap_boundary'], })

CLI

txfence stress-test --config ./txfence.config.ts \ --agents 10 \ --transactions 20 \ --vectors rapid_fire,cap_boundary \ --only-failures \ --json

Exits 0 when all scenarios survive, 1 when any fail — CI-friendly.

Last updated on