diff --git a/README.md b/README.md index 4ebd7dba7..a992b4785 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ import Task from "@divviup/dap"; const task = new Task({ type: "sum", bits: 8, - taskId: "3XTBHxTtUAtI516GeXZsVIKjBPYVNIYmF94vEBb4jcY", + id: "3XTBHxTtUAtI516GeXZsVIKjBPYVNIYmF94vEBb4jcY", leader: "http://localhost:8080", helper: "http://localhost:8081", timePrecisionSeconds: 3600, diff --git a/packages/dap/src/report.ts b/packages/dap/src/report.ts index 95be0c9cc..484caaa72 100644 --- a/packages/dap/src/report.ts +++ b/packages/dap/src/report.ts @@ -53,14 +53,14 @@ export class PlaintextInputShare implements Encodable { export class InputShareAad implements Encodable { constructor( - public taskId: TaskId, + public id: TaskId, public metadata: ReportMetadata, public publicShare: Buffer, ) {} encode(): Buffer { return Buffer.concat([ - this.taskId.encode(), + this.id.encode(), this.metadata.encode(), encodeOpaque32(this.publicShare), ]); diff --git a/packages/dap/src/task.spec.ts b/packages/dap/src/task.spec.ts index bd0fb3194..debad7050 100644 --- a/packages/dap/src/task.spec.ts +++ b/packages/dap/src/task.spec.ts @@ -80,7 +80,7 @@ function buildParams(): { bits: number; helper: string; leader: string; - taskId: TaskId; + id: TaskId; timePrecisionSeconds: number; } { return { @@ -88,7 +88,7 @@ function buildParams(): { bits: 16, leader: "https://a.example.com/v1", helper: "https://b.example.com/dap/", - taskId: TaskId.random(), + id: TaskId.random(), timePrecisionSeconds: 1, }; } @@ -105,28 +105,28 @@ async function withHpkeConfigs< describe("Task", () => { describe("constructor variations", () => { - it("accepts a string taskId that is the base64url encoding of a taskId", () => { + it("accepts a string id that is the base64url encoding of a id", () => { const task = new Task({ ...buildParams(), - taskId: "3XTBHxTtUAtI516GeXZsVIKjBPYVNIYmF94vEBb4jcY", + id: "3XTBHxTtUAtI516GeXZsVIKjBPYVNIYmF94vEBb4jcY", }); assert.equal( - task.taskId.toString(), + task.id.toString(), "3XTBHxTtUAtI516GeXZsVIKjBPYVNIYmF94vEBb4jcY", ); }); - it("accepts a buffer taskId", () => { + it("accepts a buffer id", () => { const task = new Task({ ...buildParams(), - taskId: Buffer.from( + id: Buffer.from( "3XTBHxTtUAtI516GeXZsVIKjBPYVNIYmF94vEBb4jcY", "base64url", ), }); assert.equal( - task.taskId.toString(), + task.id.toString(), "3XTBHxTtUAtI516GeXZsVIKjBPYVNIYmF94vEBb4jcY", ); }); @@ -137,7 +137,7 @@ describe("Task", () => { buckets: [10, 20, 30], helper: "http://helper", leader: "http://leader", - taskId: "3XTBHxTtUAtI516GeXZsVIKjBPYVNIYmF94vEBb4jcY", + id: "3XTBHxTtUAtI516GeXZsVIKjBPYVNIYmF94vEBb4jcY", timePrecisionSeconds: 3600, }); @@ -150,7 +150,7 @@ describe("Task", () => { bits: 8, helper: "http://helper", leader: "http://leader", - taskId: "3XTBHxTtUAtI516GeXZsVIKjBPYVNIYmF94vEBb4jcY", + id: "3XTBHxTtUAtI516GeXZsVIKjBPYVNIYmF94vEBb4jcY", timePrecisionSeconds: 3600, }); @@ -163,7 +163,7 @@ describe("Task", () => { bits: 8, helper: "http://helper", leader: "http://leader", - taskId: "3XTBHxTtUAtI516GeXZsVIKjBPYVNIYmF94vEBb4jcY", + id: "3XTBHxTtUAtI516GeXZsVIKjBPYVNIYmF94vEBb4jcY", timePrecisionSeconds: 3600, }); @@ -189,13 +189,13 @@ describe("Task", () => { await buildHpkeConfigList(), await buildHpkeConfigList(), ]; - const taskId = params.taskId.buffer.toString("base64url"); + const id = params.id.buffer.toString("base64url"); const fetch = mockFetch({ - [`https://a.example.com/v1/hpke_config?task_id=${taskId}`]: [ + [`https://a.example.com/v1/hpke_config?task_id=${id}`]: [ await hpkeConfigResponse(hpkeConfig1), ], - [`https://b.example.com/dap/hpke_config?task_id=${taskId}`]: [ + [`https://b.example.com/dap/hpke_config?task_id=${id}`]: [ await hpkeConfigResponse(hpkeConfig2), ], }); @@ -213,13 +213,13 @@ describe("Task", () => { it("throws an error if the status is not 200", async () => { const params = buildParams(); - const taskId = params.taskId.buffer.toString("base64url"); + const id = params.id.buffer.toString("base64url"); const fetch = mockFetch({ - [`https://a.example.com/v1/hpke_config?task_id=${taskId}`]: [ + [`https://a.example.com/v1/hpke_config?task_id=${id}`]: [ { status: 418 }, ], - [`https://b.example.com/dap/hpke_config?task_id=${taskId}`]: [ + [`https://b.example.com/dap/hpke_config?task_id=${id}`]: [ { status: 500 }, ], }); @@ -245,15 +245,15 @@ describe("Task", () => { it("throws an error if the content type is not correct", async () => { const params = buildParams(); - const taskId = params.taskId.buffer.toString("base64url"); + const id = params.id.buffer.toString("base64url"); const fetch = mockFetch({ - [`https://a.example.com/v1/hpke_config?task_id=${taskId}`]: [ + [`https://a.example.com/v1/hpke_config?task_id=${id}`]: [ { contentType: "application/text", body: (await buildHpkeConfigList()).encode(), }, ], - [`https://b.example.com/dap/hpke_config?task_id=${taskId}`]: [ + [`https://b.example.com/dap/hpke_config?task_id=${id}`]: [ { contentType: "application/text", body: (await buildHpkeConfigList()).encode(), @@ -272,7 +272,7 @@ describe("Task", () => { const privateKeys = [] as [CryptoKey, number][]; const task = new Task({ ...buildParams(), - taskId: new TaskId(Buffer.alloc(32, 1)), + id: new TaskId(Buffer.alloc(32, 1)), }); const kem = new DhkemP256HkdfSha256(); const kdf = KdfId.HkdfSha256; @@ -301,7 +301,7 @@ describe("Task", () => { ); const aad = Buffer.concat([ - task.taskId.encode(), + task.id.encode(), report.metadata.encode(), encodeOpaque32(report.publicShare), ]); @@ -367,12 +367,12 @@ describe("Task", () => { it("fetches hpke configs if needed", async () => { const params = buildParams(); - const taskId = params.taskId.buffer.toString("base64url"); + const id = params.id.buffer.toString("base64url"); const fetch = mockFetch({ - [`https://a.example.com/v1/hpke_config?task_id=${taskId}`]: [ + [`https://a.example.com/v1/hpke_config?task_id=${id}`]: [ await hpkeConfigResponse(), ], - [`https://b.example.com/dap/hpke_config?task_id=${taskId}`]: [ + [`https://b.example.com/dap/hpke_config?task_id=${id}`]: [ await hpkeConfigResponse(), ], }); @@ -386,9 +386,9 @@ describe("Task", () => { describe("sending reports", () => { it("can succeed", async () => { const params = buildParams(); - const taskId = params.taskId.buffer.toString("base64url"); + const id = params.id.buffer.toString("base64url"); const fetch = mockFetch({ - [`https://a.example.com/v1/tasks/${taskId}/reports`]: [{ status: 201 }], + [`https://a.example.com/v1/tasks/${id}/reports`]: [{ status: 201 }], }); const task = await withHpkeConfigs(new Task(params)); task.fetch = fetch; @@ -397,10 +397,7 @@ describe("Task", () => { assert.equal(fetch.calls.length, 1); const [[url, args]] = fetch.calls; const request = new Request(url, args); - assert.equal( - request.url, - `https://a.example.com/v1/tasks/${taskId}/reports`, - ); + assert.equal(request.url, `https://a.example.com/v1/tasks/${id}/reports`); assert(!!args); assert.deepEqual(args.body, report.encode()); assert.equal(request.method, "PUT"); @@ -423,15 +420,15 @@ describe("Task", () => { describe("sending measurement", () => { it("makes the correct number of http requests when all goes well", async () => { const params = buildParams(); - const taskId = params.taskId.buffer.toString("base64url"); + const id = params.id.buffer.toString("base64url"); const fetch = mockFetch({ - [`https://a.example.com/v1/hpke_config?task_id=${taskId}`]: [ + [`https://a.example.com/v1/hpke_config?task_id=${id}`]: [ await hpkeConfigResponse(), ], - [`https://b.example.com/dap/hpke_config?task_id=${taskId}`]: [ + [`https://b.example.com/dap/hpke_config?task_id=${id}`]: [ await hpkeConfigResponse(), ], - [`https://a.example.com/v1/tasks/${taskId}/reports`]: [{ status: 201 }], + [`https://a.example.com/v1/tasks/${id}/reports`]: [{ status: 201 }], }); const task = new Task(params); @@ -442,17 +439,17 @@ describe("Task", () => { it("retries once if the configs were outdated", async () => { const params = buildParams(); - const taskId = params.taskId.buffer.toString("base64url"); + const id = params.id.buffer.toString("base64url"); const fetch = mockFetch({ - [`https://a.example.com/v1/hpke_config?task_id=${taskId}`]: [ + [`https://a.example.com/v1/hpke_config?task_id=${id}`]: [ await hpkeConfigResponse(), await hpkeConfigResponse(), ], - [`https://b.example.com/dap/hpke_config?task_id=${taskId}`]: [ + [`https://b.example.com/dap/hpke_config?task_id=${id}`]: [ await hpkeConfigResponse(), await hpkeConfigResponse(), ], - [`https://a.example.com/v1/tasks/${taskId}/reports`]: [ + [`https://a.example.com/v1/tasks/${id}/reports`]: [ { status: 400, contentType: "application/problem+json", @@ -464,7 +461,7 @@ describe("Task", () => { detail: "The message was generated using an outdated configuration.", instance: "..", - taskid: params.taskId.toString(), + taskid: params.id.toString(), }), }, {}, @@ -479,19 +476,19 @@ describe("Task", () => { it("does not retry more than once if the [refetched] configs were [still] outdated", async () => { const params = buildParams(); - const taskId = params.taskId.buffer.toString("base64url"); + const id = params.id.buffer.toString("base64url"); const fetch = mockFetch({ - [`https://a.example.com/v1/hpke_config?task_id=${taskId}`]: [ + [`https://a.example.com/v1/hpke_config?task_id=${id}`]: [ await hpkeConfigResponse(), await hpkeConfigResponse(), ], - [`https://b.example.com/dap/hpke_config?task_id=${taskId}`]: [ + [`https://b.example.com/dap/hpke_config?task_id=${id}`]: [ await hpkeConfigResponse(), await hpkeConfigResponse(), ], - [`https://a.example.com/v1/tasks/${taskId}/reports`]: [ - outdatedConfigResponse(params.taskId), - outdatedConfigResponse(params.taskId), + [`https://a.example.com/v1/tasks/${id}/reports`]: [ + outdatedConfigResponse(params.id), + outdatedConfigResponse(params.id), ], }); @@ -506,7 +503,7 @@ describe("Task", () => { }); }); -function outdatedConfigResponse(taskId: TaskId): ResponseSpec { +function outdatedConfigResponse(id: TaskId): ResponseSpec { return { status: 400, contentType: "application/problem+json", @@ -516,7 +513,7 @@ function outdatedConfigResponse(taskId: TaskId): ResponseSpec { status: 400, detail: "The message was generated using an outdated configuration.", instance: "..", - taskid: taskId.toString(), + taskid: id.toString(), }), }; } diff --git a/packages/dap/src/task.ts b/packages/dap/src/task.ts index 0e54864d6..9a6b52007 100644 --- a/packages/dap/src/task.ts +++ b/packages/dap/src/task.ts @@ -32,7 +32,7 @@ export interface ClientParameters { either as a Buffer, a {@linkcode TaskId} or a base64url-encoded string **/ - taskId: TaskId | Buffer | string; + id: TaskId | Buffer | string; /** the url of the leader aggregator, specified as either a string or a {@linkcode URL} @@ -103,7 +103,7 @@ export class Task< Measurement extends VdafMeasurement, > { #vdaf: ClientVdaf; - #taskId: TaskId; + #id: TaskId; #aggregators: Aggregator[]; #timePrecisionSeconds: number; #extensions: Extension[] = []; @@ -118,7 +118,7 @@ export class Task< */ constructor(parameters: ClientParameters & Spec) { this.#vdaf = vdafFromSpec(parameters) as ClientVdaf; - this.#taskId = taskIdFromDefinition(parameters.taskId); + this.#id = idFromDefinition(parameters.id); this.#aggregators = aggregatorsFromParameters(parameters); if (typeof parameters.timePrecisionSeconds !== "number") { throw new Error("timePrecisionSeconds must be a number"); @@ -146,8 +146,8 @@ export class Task< /** @internal */ //this exists for testing, and should not be considered part of the public api. - get taskId(): TaskId { - return this.#taskId; + get id(): TaskId { + return this.#id; } /** @@ -177,7 +177,7 @@ export class Task< const time = roundedTime(this.#timePrecisionSeconds, options?.timestamp); const metadata = new ReportMetadata(reportId, time); - const aad = new InputShareAad(this.taskId, metadata, publicShare); + const aad = new InputShareAad(this.id, metadata, publicShare); const ciphertexts = await Promise.all( this.#aggregators.map((aggregator, i) => aggregator.seal( @@ -200,9 +200,9 @@ export class Task< async sendReport(report: Report) { const body = report.encode(); const leader = this.#aggregators[0]; - const taskId = this.#taskId.toString(); + const id = this.#id.toString(); const response = await this.#fetch( - new URL(`tasks/${taskId}/reports`, leader.url).toString(), + new URL(`tasks/${id}/reports`, leader.url).toString(), { method: "PUT", headers: { "Content-Type": CONTENT_TYPES.REPORT }, @@ -276,7 +276,7 @@ export class Task< await Promise.all( this.#aggregators.map(async (aggregator) => { const url = new URL("hpke_config", aggregator.url); - url.searchParams.append("task_id", this.#taskId.toString()); + url.searchParams.append("task_id", this.#id.toString()); const response = await this.#fetch(url.toString(), { headers: { Accept: CONTENT_TYPES.HPKE_CONFIG_LIST }, @@ -314,11 +314,9 @@ function aggregatorsFromParameters({ return [Aggregator.leader(leader), Aggregator.helper(helper)]; } -function taskIdFromDefinition( - taskIdDefinition: Buffer | TaskId | string, -): TaskId { - if (taskIdDefinition instanceof TaskId) return taskIdDefinition; - else return new TaskId(taskIdDefinition); +function idFromDefinition(idDefinition: Buffer | TaskId | string): TaskId { + if (idDefinition instanceof TaskId) return idDefinition; + else return new TaskId(idDefinition); } function roundedTime(timePrecisionSeconds: number, date?: Date): number { diff --git a/packages/dap/src/taskId.spec.ts b/packages/dap/src/taskId.spec.ts index e6fb0c1cd..55dae7b3a 100644 --- a/packages/dap/src/taskId.spec.ts +++ b/packages/dap/src/taskId.spec.ts @@ -11,18 +11,18 @@ describe("DAP TaskId", () => { it("generates a random TaskId", () => { // this is a weak test but it's probably fine because the code is simple - const taskId = TaskId.random(); + const id = TaskId.random(); const otherTaskId = TaskId.random(); - assert.notEqual(taskId.toString(), otherTaskId.toString()); + assert.notEqual(id.toString(), otherTaskId.toString()); }); it("stringifies as the base64url representation", () => { - const taskId = new TaskId( + const id = new TaskId( Buffer.from( "dd74c11f14ed500b48e75e8679766c5482a304f61534862617de2f1016f88dc6", "hex", ), ); - assert.equal(taskId, "3XTBHxTtUAtI516GeXZsVIKjBPYVNIYmF94vEBb4jcY"); + assert.equal(id, "3XTBHxTtUAtI516GeXZsVIKjBPYVNIYmF94vEBb4jcY"); }); }); diff --git a/packages/interop-test-client/src/index.spec.ts b/packages/interop-test-client/src/index.spec.ts index fcd98326e..c6183a3d3 100644 --- a/packages/interop-test-client/src/index.spec.ts +++ b/packages/interop-test-client/src/index.spec.ts @@ -148,9 +148,9 @@ async function checkResponseError( } class Aggregator extends Container { - async endpointForTask(taskId: EncodedBlob, role: string): Promise { + async endpointForTask(id: EncodedBlob, role: string): Promise { const rawBody = await this.sendRequest("endpoint_for_task", { - task_id: taskId.toString(), + task_id: id.toString(), role: role, hostname: this.name, }); @@ -168,7 +168,7 @@ class Aggregator extends Container { /** Send an /internal/test/add_task request. */ async addTask( - taskId: EncodedBlob, + id: EncodedBlob, role: string, leaderEndpoint: URL, helperEndpoint: URL, @@ -183,7 +183,7 @@ class Aggregator extends Container { taskExpiration: number, ): Promise { const requestBody: Record = { - task_id: taskId.toString(), + task_id: id.toString(), leader: leaderEndpoint.toString(), helper: helperEndpoint.toString(), vdaf: vdaf, @@ -207,13 +207,13 @@ class Aggregator extends Container { class Collector extends Container { /** Send an /internal/test/add_task request, and return the encoded collector HPKE configuration. */ async addTask( - taskId: EncodedBlob, + id: EncodedBlob, leaderEndpoint: URL, vdaf: object, collectorAuthToken: string, ): Promise { const rawBody = await this.sendRequest("add_task", { - task_id: taskId.toString(), + task_id: id.toString(), leader: leaderEndpoint.toString(), vdaf: vdaf, collector_authentication_token: collectorAuthToken, @@ -233,12 +233,12 @@ class Collector extends Container { /** Send an /internal/test/collection_start request, and return the handle for the request. */ async collectionStart( - taskId: EncodedBlob, + id: EncodedBlob, batchIntervalStart: number, batchIntervalDuration: number, ): Promise { const rawBody = await this.sendRequest("collection_start", { - task_id: taskId.toString(), + task_id: id.toString(), agg_param: "", query: { type: 1, @@ -299,7 +299,7 @@ type Collection = { async function upload( clientPort: number, - taskId: EncodedBlob, + id: EncodedBlob, leaderEndpoint: URL, helperEndpoint: URL, vdaf: object, @@ -314,7 +314,7 @@ async function upload( "Content-Type": "application/json", }, body: JSON.stringify({ - task_id: taskId.toString(), + task_id: id.toString(), leader: leaderEndpoint.toString(), helper: helperEndpoint.toString(), vdaf: vdaf, @@ -395,22 +395,22 @@ async function runIntegrationTest( await helper.waitForReady(); await collector.waitForReady(); - const taskId = EncodedBlob.random(32); + const id = EncodedBlob.random(32); const aggregatorAuthToken = `aggregator-${randomSuffix()}`; const collectorAuthToken = `collector-${randomSuffix()}`; const vdafVerifyKey = EncodedBlob.random(16); - const leaderEndpoint = await leader.endpointForTask(taskId, "leader"); - const helperEndpoint = await helper.endpointForTask(taskId, "helper"); + const leaderEndpoint = await leader.endpointForTask(id, "leader"); + const helperEndpoint = await helper.endpointForTask(id, "helper"); const collectorHpkeConfig = await collector.addTask( - taskId, + id, leaderEndpoint, vdaf, collectorAuthToken, ); await leader.addTask( - taskId, + id, "leader", leaderEndpoint, helperEndpoint, @@ -425,7 +425,7 @@ async function runIntegrationTest( taskExpiration, ); await helper.addTask( - taskId, + id, "helper", leaderEndpoint, helperEndpoint, @@ -462,7 +462,7 @@ async function runIntegrationTest( for (const measurement of measurements) { await upload( clientPort, - taskId, + id, leaderEndpointForClient, helperEndpointForClient, vdaf, @@ -472,7 +472,7 @@ async function runIntegrationTest( } const collectHandle = await collector.collectionStart( - taskId, + id, Math.floor(start.getTime() / 1000 / timePrecision) * timePrecision, timePrecision * 2, ); diff --git a/packages/interop-test-client/src/index.ts b/packages/interop-test-client/src/index.ts index 672761ae9..c30ee7a94 100644 --- a/packages/interop-test-client/src/index.ts +++ b/packages/interop-test-client/src/index.ts @@ -240,7 +240,7 @@ async function uploadHandler(req: Request, res: Response): Promise { switch (body.vdaf.type) { case "Prio3Count": await new Task({ - taskId: body.task_id, + id: body.task_id, leader: body.leader, helper: body.helper, timePrecisionSeconds: body.time_precision, @@ -250,7 +250,7 @@ async function uploadHandler(req: Request, res: Response): Promise { case "Prio3Sum": await new Task({ - taskId: body.task_id, + id: body.task_id, leader: body.leader, helper: body.helper, timePrecisionSeconds: body.time_precision, @@ -261,7 +261,7 @@ async function uploadHandler(req: Request, res: Response): Promise { case "Prio3Histogram": await new Task({ - taskId: body.task_id, + id: body.task_id, leader: body.leader, helper: body.helper, timePrecisionSeconds: body.time_precision, diff --git a/scripts/benchmarks.ts b/scripts/benchmarks.ts index f2e921d8d..b3ba1ed5a 100644 --- a/scripts/benchmarks.ts +++ b/scripts/benchmarks.ts @@ -33,7 +33,7 @@ function buildClient< new Task({ helper: "http://helper.example.com", leader: "http://leader.example.com", - taskId: TaskId.random(), + id: TaskId.random(), timePrecisionSeconds: 1, ...spec, }) diff --git a/scripts/liveTest.ts b/scripts/liveTest.ts index d1cb2b22d..41316e8aa 100644 --- a/scripts/liveTest.ts +++ b/scripts/liveTest.ts @@ -1,7 +1,7 @@ import Task from "dap"; async function main() { const client = new Task({ - taskId: process.argv[2], + id: process.argv[2], leader: "http://localhost:8080", helper: "http://localhost:8081", type: "histogram",