Request lifecycle
What happens, step by step, from the moment your agent sends a simulation request to the moment it gets a verdict.
POST /api/v1/simulateHTTPS request with API key and transaction payload arrives at the nearest Cloudflare data centre.
Key lookupThe edge Worker reads the API key prefix from KV (< 5ms). KV holds a mirror of tier + rate limit counters for hot-path decisions without a Postgres roundtrip.
Forward valid requestIf the key is valid and under rate limit, the request is forwarded to the Node.js gateway over HTTPS. Invalid or throttled requests are rejected at the edge with 401 or 429.
INSERT into simulation_queueThe gateway writes the job to Postgres with status=PENDING and returns 202 Accepted + job_id to the caller immediately.
SELECT FOR UPDATE SKIP LOCKEDThe Python worker polls the queue every 500ms. It claims a job atomically using Postgres advisory locks — multiple workers can run safely without double-claiming.
eth_call / eth_sendTransactionAnvil holds a persistent fork of the target chain. The worker takes an evm_snapshot, executes the transaction batch, then evm_reverts to the snapshot for the next job.
Execution trace + gasAnvil returns the full trace: opcodes, storage changes, events, gas consumed. The analytical engine parses this into the 10 safety check results.
INSERT telemetry documentThe full trace and check results are stored append-only in MongoDB for debugging, analytics, and future model training.
UPDATE simulation_queue SET status=APPROVED/REJECTEDThe job status is written back to Postgres. The gateway's polling endpoint will now return the terminal state.
GET /api/v1/simulate/:jobIdThe caller polls the result endpoint. When status is terminal (APPROVED, REJECTED, FAILED, TIMED_OUT), they get the full verdict and stop polling.
< 10ms
Edge validation
API key + rate limit at Cloudflare
< 300ms
Fork + execution
Snapshot reuse; no cold start
< 400ms
End-to-end median
Including queue + polling overhead