Skip to content
Merged
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
46 changes: 32 additions & 14 deletions runtime/tests/runtime-signing.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ test("full chain clean -> summarize -> classify verifies with schema using parti

async function verifyReceiptWithTimeout(receipt) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 5000);
const timeout = setTimeout(() => controller.abort(), 10000);

try {
const res = await fetch(`${srv.base}/verify?schema=1`, {
Expand All @@ -492,10 +492,6 @@ test("full chain clean -> summarize -> classify verifies with schema using parti
json = null;
}

if (!res.ok && res.status !== 202) {
throw new Error(`HTTP ${res.status}: ${text}`);
}

return { res, text, json };
} catch (err) {
const message = err?.name === "AbortError" ? "AbortError" : err?.message || String(err);
Expand Down Expand Up @@ -528,16 +524,38 @@ test("full chain clean -> summarize -> classify verifies with schema using parti

assert.equal(finalReceipt.x402.entry, "x402://classifyagent.eth/classify/v1.1.0");

console.log("[chain] before verify request");
let verifyAttempt = await verifyReceiptWithTimeout(finalReceipt);
console.log("[chain] after verify response", verifyAttempt.res.status, verifyAttempt.json ?? verifyAttempt.text);
let verifyAttempt = null;

if (verifyAttempt.res.status === 202) {
console.log("[chain] verify warmup 202 response", verifyAttempt.json ?? verifyAttempt.text);
await new Promise((resolve) => setTimeout(resolve, 1200));
console.log("[chain] before verify request retry");
for (let attempt = 1; attempt <= 3; attempt++) {
console.log(`[chain] before verify request attempt ${attempt}`);
verifyAttempt = await verifyReceiptWithTimeout(finalReceipt);
console.log("[chain] after verify response retry", verifyAttempt.res.status, verifyAttempt.json ?? verifyAttempt.text);
console.log(`[chain] after verify response attempt ${attempt}`, verifyAttempt.res.status, verifyAttempt.json ?? verifyAttempt.text);

const verifyRes = verifyAttempt.res;
const verifyJson = verifyAttempt.json;

if (verifyRes.status === 200) break;

if (verifyRes.status !== 202) {
throw new Error(`verify attempt ${attempt} returned unexpected status ${verifyRes.status}: ${verifyAttempt.text}`);
}

const schemaErrors = Array.isArray(verifyJson?.errors?.schema_errors) ? verifyJson.errors.schema_errors : [];
const hasWarmupPending = schemaErrors.some((entry) => entry?.message === "validator_not_warmed_yet");

if (!hasWarmupPending) {
throw new Error(`verify attempt ${attempt} returned unexpected 202 payload: ${verifyAttempt.text}`);
}

if (attempt === 3) {
throw new Error(
`verify warmup did not complete after 3 attempts; last status ${verifyRes.status}; last body: ${verifyAttempt.text}`
);
}

const retryAfterMs = Number(verifyJson?.retry_after_ms);
const delayMs = Number.isFinite(retryAfterMs) && retryAfterMs > 0 ? retryAfterMs : 1000;
await new Promise((resolve) => setTimeout(resolve, delayMs));
}

const verifyRes = verifyAttempt.res;
Expand All @@ -546,7 +564,7 @@ test("full chain clean -> summarize -> classify verifies with schema using parti
assert.ok(verifyJson, "verify returned non-JSON response");

if (verifyRes.status !== 200) {
throw new Error(`verify retry failed with status ${verifyRes.status}: ${verifyAttempt.text}`);
throw new Error(`verify failed with status ${verifyRes.status}: ${verifyAttempt.text}`);
}

assert.equal(verifyJson.checks.signature_valid, true);
Expand Down
3 changes: 1 addition & 2 deletions server.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1880,8 +1880,7 @@ app.post("/verify", async (req, res) => {
if (!verb) {
schemaErrors = [{ message: "missing receipt.x402.verb" }];
} else if (VERIFY_SCHEMA_CACHED_ONLY && !hasValidatorCached(verb)) {
warmQueue.add(verb);
startWarmWorker();
warmValidatorForVerb(verb);

return res.status(202).json({
ok: false,
Expand Down
Loading