feat: backfill Vector proofs from the Surplus support export
Some checks failed
CI / typecheck + vitest (Node 20) (push) Has been cancelled

This commit is contained in:
david
2026-08-28 12:29:45 +02:00
parent a6eabe6b98
commit a5cb4b03e1
7 changed files with 427 additions and 7 deletions

View File

@@ -0,0 +1,98 @@
import { mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { loadHistoricalSalesCsv } from "../../supplier/src/surplus/historyExport.js";
const HEADER =
"request_id,settled_at,model,input_tokens,output_tokens,seller_earned_usd,settlement_status,settlement_type,tx_hash";
const directories: string[] = [];
async function csvFile(content: string): Promise<string> {
const directory = await mkdtemp(join(tmpdir(), "surplus-history-"));
directories.push(directory);
const path = join(directory, "sales.csv");
await writeFile(path, content, "utf8");
return path;
}
afterEach(async () => {
await Promise.all(directories.splice(0).map((path) =>
rm(path, { recursive: true, force: true })
));
});
describe("loadHistoricalSalesCsv", () => {
it("maps settled export rows onto publisher sales and skips unsettled rows", async () => {
const baseTx = "0x" + "A".repeat(64);
const path = await csvFile([
HEADER,
`"01SALE1","2026-08-28T07:39:33.869Z","deepseek-v4-flash","151204","805","0.000607","confirmed","onchain","${baseTx}"`,
`"01SALE2","2026-08-28T07:39:22.308Z","deepseek-v4-flash","10","2","1.5","confirmed","onchain",""`,
`"01SALE3","2026-08-28T07:39:48.036Z","deepseek-v4-flash","47257","1761","0.000202","accrued","credit",""`,
].join("\n"));
const result = await loadHistoricalSalesCsv(path, "offer-1");
expect(result.skippedUnsettled).toBe(1);
expect(result.settledWithoutTx).toBe(1);
expect(result.sales).toHaveLength(2);
expect(result.sales[0]).toMatchObject({
id: "01SALE1",
offerId: "offer-1",
model: "deepseek-v4-flash",
settlementStatus: "confirmed",
createdAt: "2026-08-28T07:39:33.869Z",
createdAtMs: Date.parse("2026-08-28T07:39:33.869Z"),
sellerCostMicroUsd: 607,
inputTokens: 151_204,
outputTokens: 805,
cacheReadTokens: 0,
effectiveInputUsdPer1m: 0,
effectiveOutputUsdPer1m: 0,
transactionHash: baseTx.toLowerCase(),
});
expect(result.sales[1]).toMatchObject({
id: "01SALE2",
sellerCostMicroUsd: 1_500_000,
transactionHash: null,
});
});
it("rejects an unexpected header, duplicate ids, and malformed rows", async () => {
const wrongHeader = await csvFile("request_id,foo\n\"a\",\"b\"");
await expect(loadHistoricalSalesCsv(wrongHeader, "offer-1")).rejects.toThrow(
/header must be exactly/,
);
const duplicate = await csvFile([
HEADER,
`"01SAME","2026-08-28T07:39:33.869Z","m","1","1","0.1","confirmed","onchain",""`,
`"01SAME","2026-08-28T07:39:33.869Z","m","1","1","0.1","confirmed","onchain",""`,
].join("\n"));
await expect(loadHistoricalSalesCsv(duplicate, "offer-1")).rejects.toThrow(
/repeats request_id/,
);
const badTx = await csvFile([
HEADER,
`"01SALE","2026-08-28T07:39:33.869Z","m","1","1","0.1","confirmed","onchain","0x123"`,
].join("\n"));
await expect(loadHistoricalSalesCsv(badTx, "offer-1")).rejects.toThrow(
/invalid tx_hash/,
);
const badTokens = await csvFile([
HEADER,
`"01SALE","2026-08-28T07:39:33.869Z","m","-4","1","0.1","confirmed","onchain",""`,
].join("\n"));
await expect(loadHistoricalSalesCsv(badTokens, "offer-1")).rejects.toThrow(
/input_tokens/,
);
await expect(loadHistoricalSalesCsv(badTokens, " ")).rejects.toThrow(
/non-empty offer id/,
);
});
});

View File

@@ -209,6 +209,54 @@ describe("SurplusVectorProofPublisher", () => {
]);
expect(ledger.dashboardProof("01EXPIRED")).toMatchObject({ status: "confirmed" });
});
it("anchors export-only settlements per Base tx and never re-ingests known sale ids", async () => {
const baseTxA = "0x" + "a".repeat(64);
const baseTxB = "0x" + "b".repeat(64);
const observed = sale("01OBSERVED", { transactionHash: baseTxA });
const { ledger, publisher, anchors } = await harness({ sales: [observed] });
await ledger.ingestSales([observed]);
const conflictingExportCopy = sale("01OBSERVED", {
transactionHash: baseTxA,
inputTokens: 999_999,
cacheReadTokens: 0,
});
const historical = [
conflictingExportCopy,
sale("01HISTA2", { transactionHash: baseTxA, cacheReadTokens: 0 }),
sale("01HISTB1", {
transactionHash: baseTxB,
cacheReadTokens: 0,
createdAtMs: Date.parse("2026-08-27T01:00:00.000Z"),
createdAt: "2026-08-27T01:00:00.000Z",
}),
];
const historicalPublisher = new SurplusVectorProofPublisher({
ledger,
earnings: async () => earningsWith([observed]),
historicalSales: async () => historical,
anchor: publisher["options"].anchor,
awaitTx: async () => undefined,
balanceLovelace: async () => 25_000_000n,
reserveLovelace: 5_000_000n,
feeBudgetLovelace: 1_000_000n,
settledStatuses: ["confirmed"],
intervalMs: 60_000,
confirmTimeoutMs: 1_000,
log: () => undefined,
});
const result = await historicalPublisher.runCycle();
expect(result).toMatchObject({ ingested: 2, anchored: 2, failed: false });
expect(anchors.map((metadata) => metadata.first)).toEqual([
"01HISTB1",
"01HISTA2",
]);
expect(ledger.dashboardProof("01OBSERVED")).toMatchObject({ status: "confirmed" });
expect(ledger.dashboardProof("01HISTA2")).toMatchObject({ status: "confirmed" });
expect(ledger.dashboardProof("01HISTB1")).toMatchObject({ status: "confirmed" });
});
it("marks a confirmation timeout as a confirm-stage failure", async () => {
const { ledger, publisher } = await harness({