@aztec/prover-client 0.65.1 → 0.66.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/block_builder/index.d.ts +6 -0
- package/dest/block_builder/index.d.ts.map +1 -0
- package/dest/block_builder/index.js +2 -0
- package/dest/block_builder/light.d.ts +32 -0
- package/dest/block_builder/light.d.ts.map +1 -0
- package/dest/block_builder/light.js +71 -0
- package/dest/config.d.ts +4 -10
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +8 -7
- package/dest/index.d.ts +2 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +3 -3
- package/dest/mocks/fixtures.d.ts +1 -2
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +3 -7
- package/dest/mocks/test_context.d.ts +28 -10
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +59 -21
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +10 -18
- package/dest/orchestrator/block-proving-state.js +2 -2
- package/dest/orchestrator/epoch-proving-state.d.ts +5 -6
- package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/epoch-proving-state.js +10 -12
- package/dest/orchestrator/orchestrator.d.ts +8 -6
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +83 -72
- package/dest/orchestrator/tx-proving-state.d.ts +0 -1
- package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/tx-proving-state.js +2 -34
- package/dest/prover-agent/memory-proving-queue.d.ts +10 -8
- package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -1
- package/dest/prover-agent/memory-proving-queue.js +35 -35
- package/dest/prover-agent/prover-agent.d.ts +1 -0
- package/dest/prover-agent/prover-agent.d.ts.map +1 -1
- package/dest/prover-agent/prover-agent.js +12 -9
- package/dest/prover-client/factory.d.ts +6 -0
- package/dest/prover-client/factory.d.ts.map +1 -0
- package/dest/prover-client/factory.js +6 -0
- package/dest/prover-client/index.d.ts +3 -0
- package/dest/prover-client/index.d.ts.map +1 -0
- package/dest/prover-client/index.js +3 -0
- package/dest/prover-client/prover-client.d.ts +41 -0
- package/dest/prover-client/prover-client.d.ts.map +1 -0
- package/dest/prover-client/prover-client.js +107 -0
- package/dest/proving_broker/caching_broker_facade.d.ts +30 -0
- package/dest/proving_broker/caching_broker_facade.d.ts.map +1 -0
- package/dest/proving_broker/caching_broker_facade.js +150 -0
- package/dest/proving_broker/factory.d.ts +5 -0
- package/dest/proving_broker/factory.d.ts.map +1 -0
- package/dest/proving_broker/factory.js +17 -0
- package/dest/proving_broker/index.d.ts +9 -0
- package/dest/proving_broker/index.d.ts.map +1 -0
- package/dest/proving_broker/index.js +9 -0
- package/dest/proving_broker/proof_store.d.ts +46 -0
- package/dest/proving_broker/proof_store.d.ts.map +1 -0
- package/dest/proving_broker/proof_store.js +37 -0
- package/dest/proving_broker/prover_cache/memory.d.ts +9 -0
- package/dest/proving_broker/prover_cache/memory.d.ts.map +1 -0
- package/dest/proving_broker/prover_cache/memory.js +16 -0
- package/dest/proving_broker/proving_agent.d.ts +16 -6
- package/dest/proving_broker/proving_agent.d.ts.map +1 -1
- package/dest/proving_broker/proving_agent.js +59 -20
- package/dest/proving_broker/proving_agent_instrumentation.d.ts +8 -0
- package/dest/proving_broker/proving_agent_instrumentation.d.ts.map +1 -0
- package/dest/proving_broker/proving_agent_instrumentation.js +16 -0
- package/dest/proving_broker/proving_broker.d.ts +22 -16
- package/dest/proving_broker/proving_broker.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker.js +79 -25
- package/dest/proving_broker/proving_broker_database/memory.d.ts +14 -0
- package/dest/proving_broker/proving_broker_database/memory.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker_database/memory.js +35 -0
- package/dest/proving_broker/proving_broker_database/persisted.d.ts +17 -0
- package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker_database/persisted.js +43 -0
- package/dest/proving_broker/{proving_job_database.d.ts → proving_broker_database.d.ts} +8 -8
- package/dest/proving_broker/proving_broker_database.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker_database.js +2 -0
- package/dest/proving_broker/proving_broker_instrumentation.d.ts +25 -0
- package/dest/proving_broker/proving_broker_instrumentation.d.ts.map +1 -0
- package/dest/proving_broker/proving_broker_instrumentation.js +91 -0
- package/dest/proving_broker/proving_job_controller.d.ts +13 -8
- package/dest/proving_broker/proving_job_controller.d.ts.map +1 -1
- package/dest/proving_broker/proving_job_controller.js +43 -43
- package/dest/proving_broker/rpc.d.ts +11 -0
- package/dest/proving_broker/rpc.d.ts.map +1 -0
- package/dest/proving_broker/rpc.js +44 -0
- package/dest/test/mock_prover.d.ts +16 -2
- package/dest/test/mock_prover.d.ts.map +1 -1
- package/dest/test/mock_prover.js +37 -1
- package/package.json +17 -14
- package/src/block_builder/index.ts +6 -0
- package/src/block_builder/light.ts +117 -0
- package/src/config.ts +17 -16
- package/src/index.ts +2 -2
- package/src/mocks/fixtures.ts +2 -14
- package/src/mocks/test_context.ts +81 -25
- package/src/orchestrator/block-building-helpers.ts +22 -33
- package/src/orchestrator/block-proving-state.ts +1 -1
- package/src/orchestrator/epoch-proving-state.ts +10 -13
- package/src/orchestrator/orchestrator.ts +97 -77
- package/src/orchestrator/tx-proving-state.ts +1 -56
- package/src/prover-agent/memory-proving-queue.ts +43 -44
- package/src/prover-agent/prover-agent.ts +16 -20
- package/src/prover-client/factory.ts +15 -0
- package/src/prover-client/index.ts +2 -0
- package/src/prover-client/prover-client.ts +172 -0
- package/src/proving_broker/caching_broker_facade.ts +312 -0
- package/src/proving_broker/factory.ts +25 -0
- package/src/proving_broker/index.ts +8 -0
- package/src/proving_broker/proof_store.ts +106 -0
- package/src/proving_broker/prover_cache/memory.ts +20 -0
- package/src/proving_broker/proving_agent.ts +90 -20
- package/src/proving_broker/proving_agent_instrumentation.ts +21 -0
- package/src/proving_broker/proving_broker.ts +143 -67
- package/src/proving_broker/proving_broker_database/memory.ts +43 -0
- package/src/proving_broker/proving_broker_database/persisted.ts +60 -0
- package/src/proving_broker/{proving_job_database.ts → proving_broker_database.ts} +7 -12
- package/src/proving_broker/proving_broker_instrumentation.ts +130 -0
- package/src/proving_broker/proving_job_controller.ts +54 -46
- package/src/proving_broker/rpc.ts +64 -0
- package/src/test/mock_prover.ts +52 -0
- package/dest/proving_broker/proving_broker_interface.d.ts +0 -61
- package/dest/proving_broker/proving_broker_interface.d.ts.map +0 -1
- package/dest/proving_broker/proving_broker_interface.js +0 -2
- package/dest/proving_broker/proving_job_database/memory.d.ts +0 -14
- package/dest/proving_broker/proving_job_database/memory.d.ts.map +0 -1
- package/dest/proving_broker/proving_job_database/memory.js +0 -35
- package/dest/proving_broker/proving_job_database/persisted.d.ts +0 -15
- package/dest/proving_broker/proving_job_database/persisted.d.ts.map +0 -1
- package/dest/proving_broker/proving_job_database/persisted.js +0 -35
- package/dest/proving_broker/proving_job_database.d.ts.map +0 -1
- package/dest/proving_broker/proving_job_database.js +0 -2
- package/dest/tx-prover/factory.d.ts +0 -5
- package/dest/tx-prover/factory.d.ts.map +0 -1
- package/dest/tx-prover/factory.js +0 -6
- package/dest/tx-prover/tx-prover.d.ts +0 -38
- package/dest/tx-prover/tx-prover.d.ts.map +0 -1
- package/dest/tx-prover/tx-prover.js +0 -93
- package/src/proving_broker/proving_broker_interface.ts +0 -74
- package/src/proving_broker/proving_job_database/memory.ts +0 -43
- package/src/proving_broker/proving_job_database/persisted.ts +0 -45
- package/src/tx-prover/factory.ts +0 -9
- package/src/tx-prover/tx-prover.ts +0 -130
|
@@ -1,29 +1,34 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type ProofUri,
|
|
3
|
+
type ProvingJob,
|
|
4
|
+
type ProvingJobConsumer,
|
|
5
|
+
type ProvingJobFilter,
|
|
6
|
+
type ProvingJobId,
|
|
7
|
+
type ProvingJobProducer,
|
|
8
|
+
type ProvingJobSettledResult,
|
|
9
|
+
type ProvingJobStatus,
|
|
2
10
|
ProvingRequestType,
|
|
3
|
-
type V2ProofOutput,
|
|
4
|
-
type V2ProvingJob,
|
|
5
|
-
type V2ProvingJobId,
|
|
6
|
-
type V2ProvingJobResult,
|
|
7
|
-
type V2ProvingJobStatus,
|
|
8
11
|
} from '@aztec/circuit-types';
|
|
9
12
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
10
|
-
import { RunningPromise } from '@aztec/foundation/promise';
|
|
13
|
+
import { type PromiseWithResolvers, RunningPromise, promiseWithResolvers } from '@aztec/foundation/promise';
|
|
11
14
|
import { PriorityMemoryQueue } from '@aztec/foundation/queue';
|
|
15
|
+
import { Timer } from '@aztec/foundation/timer';
|
|
16
|
+
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
12
17
|
|
|
13
18
|
import assert from 'assert';
|
|
14
19
|
|
|
15
|
-
import
|
|
16
|
-
import { type
|
|
20
|
+
import { type ProvingBrokerDatabase } from './proving_broker_database.js';
|
|
21
|
+
import { type MonitorCallback, ProvingBrokerInstrumentation } from './proving_broker_instrumentation.js';
|
|
17
22
|
|
|
18
23
|
type InProgressMetadata = {
|
|
19
|
-
id:
|
|
24
|
+
id: ProvingJobId;
|
|
20
25
|
startedAt: number;
|
|
21
26
|
lastUpdatedAt: number;
|
|
22
27
|
};
|
|
23
28
|
|
|
24
29
|
type ProofRequestBrokerConfig = {
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
timeoutIntervalMs?: number;
|
|
31
|
+
jobTimeoutMs?: number;
|
|
27
32
|
maxRetries?: number;
|
|
28
33
|
};
|
|
29
34
|
|
|
@@ -33,60 +38,88 @@ type ProofRequestBrokerConfig = {
|
|
|
33
38
|
*/
|
|
34
39
|
export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
35
40
|
private queues: ProvingQueues = {
|
|
36
|
-
[ProvingRequestType.PUBLIC_VM]: new PriorityMemoryQueue<
|
|
37
|
-
[ProvingRequestType.TUBE_PROOF]: new PriorityMemoryQueue<
|
|
38
|
-
[ProvingRequestType.PRIVATE_KERNEL_EMPTY]: new PriorityMemoryQueue<
|
|
41
|
+
[ProvingRequestType.PUBLIC_VM]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
42
|
+
[ProvingRequestType.TUBE_PROOF]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
43
|
+
[ProvingRequestType.PRIVATE_KERNEL_EMPTY]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
39
44
|
|
|
40
|
-
[ProvingRequestType.PRIVATE_BASE_ROLLUP]: new PriorityMemoryQueue<
|
|
41
|
-
[ProvingRequestType.PUBLIC_BASE_ROLLUP]: new PriorityMemoryQueue<
|
|
42
|
-
[ProvingRequestType.MERGE_ROLLUP]: new PriorityMemoryQueue<
|
|
43
|
-
[ProvingRequestType.ROOT_ROLLUP]: new PriorityMemoryQueue<
|
|
45
|
+
[ProvingRequestType.PRIVATE_BASE_ROLLUP]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
46
|
+
[ProvingRequestType.PUBLIC_BASE_ROLLUP]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
47
|
+
[ProvingRequestType.MERGE_ROLLUP]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
48
|
+
[ProvingRequestType.ROOT_ROLLUP]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
44
49
|
|
|
45
|
-
[ProvingRequestType.BLOCK_MERGE_ROLLUP]: new PriorityMemoryQueue<
|
|
46
|
-
[ProvingRequestType.BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue<
|
|
47
|
-
[ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue<
|
|
50
|
+
[ProvingRequestType.BLOCK_MERGE_ROLLUP]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
51
|
+
[ProvingRequestType.BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
52
|
+
[ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
48
53
|
|
|
49
|
-
[ProvingRequestType.BASE_PARITY]: new PriorityMemoryQueue<
|
|
50
|
-
[ProvingRequestType.ROOT_PARITY]: new PriorityMemoryQueue<
|
|
54
|
+
[ProvingRequestType.BASE_PARITY]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
55
|
+
[ProvingRequestType.ROOT_PARITY]: new PriorityMemoryQueue<ProvingJob>(provingJobComparator),
|
|
51
56
|
};
|
|
52
57
|
|
|
53
58
|
// holds a copy of the database in memory in order to quickly fulfill requests
|
|
54
59
|
// this is fine because this broker is the only one that can modify the database
|
|
55
|
-
private jobsCache = new Map<
|
|
60
|
+
private jobsCache = new Map<ProvingJobId, ProvingJob>();
|
|
56
61
|
// as above, but for results
|
|
57
|
-
private resultsCache = new Map<
|
|
62
|
+
private resultsCache = new Map<ProvingJobId, ProvingJobSettledResult>();
|
|
63
|
+
|
|
64
|
+
// tracks when each job was enqueued
|
|
65
|
+
private enqueuedAt = new Map<ProvingJobId, Timer>();
|
|
58
66
|
|
|
59
67
|
// keeps track of which jobs are currently being processed
|
|
60
68
|
// in the event of a crash this information is lost, but that's ok
|
|
61
69
|
// the next time the broker starts it will recreate jobsCache and still
|
|
62
70
|
// accept results from the workers
|
|
63
|
-
private inProgress = new Map<
|
|
71
|
+
private inProgress = new Map<ProvingJobId, InProgressMetadata>();
|
|
64
72
|
|
|
65
73
|
// keep track of which proving job has been retried
|
|
66
|
-
private retries = new Map<
|
|
74
|
+
private retries = new Map<ProvingJobId, number>();
|
|
75
|
+
|
|
76
|
+
// a map of promises that will be resolved when a job is settled
|
|
77
|
+
private promises = new Map<ProvingJobId, PromiseWithResolvers<ProvingJobSettledResult>>();
|
|
67
78
|
|
|
68
79
|
private timeoutPromise: RunningPromise;
|
|
69
80
|
private timeSource = () => Math.floor(Date.now() / 1000);
|
|
70
|
-
private
|
|
81
|
+
private jobTimeoutMs: number;
|
|
71
82
|
private maxRetries: number;
|
|
72
83
|
|
|
84
|
+
private instrumentation: ProvingBrokerInstrumentation;
|
|
85
|
+
|
|
73
86
|
public constructor(
|
|
74
|
-
private database:
|
|
75
|
-
|
|
76
|
-
|
|
87
|
+
private database: ProvingBrokerDatabase,
|
|
88
|
+
client: TelemetryClient,
|
|
89
|
+
{ jobTimeoutMs = 30_000, timeoutIntervalMs = 10_000, maxRetries = 3 }: ProofRequestBrokerConfig = {},
|
|
90
|
+
private logger = createDebugLogger('aztec:prover-client:proving-broker'),
|
|
77
91
|
) {
|
|
78
|
-
this.
|
|
79
|
-
this.
|
|
92
|
+
this.instrumentation = new ProvingBrokerInstrumentation(client);
|
|
93
|
+
this.timeoutPromise = new RunningPromise(this.timeoutCheck, timeoutIntervalMs);
|
|
94
|
+
this.jobTimeoutMs = jobTimeoutMs;
|
|
80
95
|
this.maxRetries = maxRetries;
|
|
81
96
|
}
|
|
82
97
|
|
|
83
|
-
|
|
84
|
-
|
|
98
|
+
private measureQueueDepth: MonitorCallback = (type: ProvingRequestType) => {
|
|
99
|
+
return this.queues[type].length();
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
private countActiveJobs: MonitorCallback = (type: ProvingRequestType) => {
|
|
103
|
+
let count = 0;
|
|
104
|
+
for (const { id } of this.inProgress.values()) {
|
|
105
|
+
const job = this.jobsCache.get(id);
|
|
106
|
+
if (job?.type === type) {
|
|
107
|
+
count++;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return count;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
public start(): Promise<void> {
|
|
85
115
|
for (const [item, result] of this.database.allProvingJobs()) {
|
|
86
116
|
this.logger.info(`Restoring proving job id=${item.id} settled=${!!result}`);
|
|
87
117
|
|
|
88
118
|
this.jobsCache.set(item.id, item);
|
|
119
|
+
this.promises.set(item.id, promiseWithResolvers());
|
|
120
|
+
|
|
89
121
|
if (result) {
|
|
122
|
+
this.promises.get(item.id)!.resolve(result);
|
|
90
123
|
this.resultsCache.set(item.id, result);
|
|
91
124
|
} else {
|
|
92
125
|
this.logger.debug(`Re-enqueuing proving job id=${item.id}`);
|
|
@@ -95,13 +128,18 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
95
128
|
}
|
|
96
129
|
|
|
97
130
|
this.timeoutPromise.start();
|
|
131
|
+
|
|
132
|
+
this.instrumentation.monitorQueueDepth(this.measureQueueDepth);
|
|
133
|
+
this.instrumentation.monitorActiveJobs(this.countActiveJobs);
|
|
134
|
+
|
|
135
|
+
return Promise.resolve();
|
|
98
136
|
}
|
|
99
137
|
|
|
100
138
|
public stop(): Promise<void> {
|
|
101
139
|
return this.timeoutPromise.stop();
|
|
102
140
|
}
|
|
103
141
|
|
|
104
|
-
public async enqueueProvingJob(job:
|
|
142
|
+
public async enqueueProvingJob(job: ProvingJob): Promise<void> {
|
|
105
143
|
if (this.jobsCache.has(job.id)) {
|
|
106
144
|
const existing = this.jobsCache.get(job.id);
|
|
107
145
|
assert.deepStrictEqual(job, existing, 'Duplicate proving job ID');
|
|
@@ -113,20 +151,35 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
113
151
|
this.enqueueJobInternal(job);
|
|
114
152
|
}
|
|
115
153
|
|
|
116
|
-
public
|
|
154
|
+
public waitForJobToSettle(id: ProvingJobId): Promise<ProvingJobSettledResult> {
|
|
155
|
+
const promiseWithResolvers = this.promises.get(id);
|
|
156
|
+
if (!promiseWithResolvers) {
|
|
157
|
+
return Promise.resolve({ status: 'rejected', reason: `Job ${id} not found` });
|
|
158
|
+
}
|
|
159
|
+
return promiseWithResolvers.promise;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
public async removeAndCancelProvingJob(id: ProvingJobId): Promise<void> {
|
|
117
163
|
this.logger.info(`Cancelling job id=${id}`);
|
|
118
164
|
await this.database.deleteProvingJobAndResult(id);
|
|
119
165
|
|
|
166
|
+
// notify listeners of the cancellation
|
|
167
|
+
if (!this.resultsCache.has(id)) {
|
|
168
|
+
this.promises.get(id)?.resolve({ status: 'rejected', reason: 'Aborted' });
|
|
169
|
+
}
|
|
170
|
+
|
|
120
171
|
this.jobsCache.delete(id);
|
|
172
|
+
this.promises.delete(id);
|
|
121
173
|
this.resultsCache.delete(id);
|
|
122
174
|
this.inProgress.delete(id);
|
|
123
175
|
this.retries.delete(id);
|
|
124
176
|
}
|
|
125
177
|
|
|
126
|
-
|
|
127
|
-
public async getProvingJobStatus(id: V2ProvingJobId): Promise<V2ProvingJobStatus> {
|
|
178
|
+
public getProvingJobStatus(id: ProvingJobId): Promise<ProvingJobStatus> {
|
|
128
179
|
const result = this.resultsCache.get(id);
|
|
129
|
-
if (
|
|
180
|
+
if (result) {
|
|
181
|
+
return Promise.resolve(result);
|
|
182
|
+
} else {
|
|
130
183
|
// no result yet, check if we know the item
|
|
131
184
|
const item = this.jobsCache.get(id);
|
|
132
185
|
|
|
@@ -136,29 +189,26 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
136
189
|
}
|
|
137
190
|
|
|
138
191
|
return Promise.resolve({ status: this.inProgress.has(id) ? 'in-progress' : 'in-queue' });
|
|
139
|
-
} else if ('value' in result) {
|
|
140
|
-
return Promise.resolve({ status: 'resolved', value: result.value });
|
|
141
|
-
} else {
|
|
142
|
-
return Promise.resolve({ status: 'rejected', error: result.error });
|
|
143
192
|
}
|
|
144
193
|
}
|
|
145
194
|
|
|
146
195
|
// eslint-disable-next-line require-await
|
|
147
|
-
async getProvingJob
|
|
148
|
-
filter: ProvingJobFilter
|
|
149
|
-
): Promise<{ job:
|
|
150
|
-
const allowedProofs: ProvingRequestType[] =
|
|
151
|
-
|
|
152
|
-
|
|
196
|
+
async getProvingJob(
|
|
197
|
+
filter: ProvingJobFilter = { allowList: [] },
|
|
198
|
+
): Promise<{ job: ProvingJob; time: number } | undefined> {
|
|
199
|
+
const allowedProofs: ProvingRequestType[] =
|
|
200
|
+
Array.isArray(filter.allowList) && filter.allowList.length > 0
|
|
201
|
+
? [...filter.allowList]
|
|
202
|
+
: Object.values(ProvingRequestType).filter((x): x is ProvingRequestType => typeof x === 'number');
|
|
153
203
|
allowedProofs.sort(proofTypeComparator);
|
|
154
204
|
|
|
155
205
|
for (const proofType of allowedProofs) {
|
|
156
206
|
const queue = this.queues[proofType];
|
|
157
|
-
let job:
|
|
207
|
+
let job: ProvingJob | undefined;
|
|
158
208
|
// exhaust the queue and make sure we're not sending a job that's already in progress
|
|
159
209
|
// or has already been completed
|
|
160
210
|
// this can happen if the broker crashes and restarts
|
|
161
|
-
// it's possible agents will report progress or results for jobs that are
|
|
211
|
+
// it's possible agents will report progress or results for jobs that are in the queue (after the restart)
|
|
162
212
|
while ((job = queue.getImmediate())) {
|
|
163
213
|
if (!this.inProgress.has(job.id) && !this.resultsCache.has(job.id)) {
|
|
164
214
|
const time = this.timeSource();
|
|
@@ -167,6 +217,10 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
167
217
|
startedAt: time,
|
|
168
218
|
lastUpdatedAt: time,
|
|
169
219
|
});
|
|
220
|
+
const enqueuedAt = this.enqueuedAt.get(job.id);
|
|
221
|
+
if (enqueuedAt) {
|
|
222
|
+
this.instrumentation.recordJobWait(job.type, enqueuedAt);
|
|
223
|
+
}
|
|
170
224
|
|
|
171
225
|
return { job, time };
|
|
172
226
|
}
|
|
@@ -176,7 +230,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
176
230
|
return undefined;
|
|
177
231
|
}
|
|
178
232
|
|
|
179
|
-
async reportProvingJobError(id:
|
|
233
|
+
async reportProvingJobError(id: ProvingJobId, err: string, retry = false): Promise<void> {
|
|
180
234
|
const info = this.inProgress.get(id);
|
|
181
235
|
const item = this.jobsCache.get(id);
|
|
182
236
|
const retries = this.retries.get(id) ?? 0;
|
|
@@ -196,21 +250,31 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
196
250
|
this.logger.info(`Retrying proving job id=${id} type=${ProvingRequestType[item.type]} retry=${retries + 1}`);
|
|
197
251
|
this.retries.set(id, retries + 1);
|
|
198
252
|
this.enqueueJobInternal(item);
|
|
253
|
+
this.instrumentation.incRetriedJobs(item.type);
|
|
199
254
|
return;
|
|
200
255
|
}
|
|
201
256
|
|
|
202
257
|
this.logger.debug(
|
|
203
258
|
`Marking proving job id=${id} type=${ProvingRequestType[item.type]} totalAttempts=${retries + 1} as failed`,
|
|
204
259
|
);
|
|
260
|
+
|
|
205
261
|
await this.database.setProvingJobError(id, err);
|
|
206
|
-
|
|
262
|
+
|
|
263
|
+
const result: ProvingJobSettledResult = { status: 'rejected', reason: String(err) };
|
|
264
|
+
this.resultsCache.set(id, result);
|
|
265
|
+
this.promises.get(id)!.resolve(result);
|
|
266
|
+
this.instrumentation.incRejectedJobs(item.type);
|
|
267
|
+
if (info) {
|
|
268
|
+
const duration = this.timeSource() - info.startedAt;
|
|
269
|
+
this.instrumentation.recordJobDuration(item.type, duration * 1000);
|
|
270
|
+
}
|
|
207
271
|
}
|
|
208
272
|
|
|
209
|
-
reportProvingJobProgress
|
|
210
|
-
id:
|
|
273
|
+
reportProvingJobProgress(
|
|
274
|
+
id: ProvingJobId,
|
|
211
275
|
startedAt: number,
|
|
212
|
-
filter?: ProvingJobFilter
|
|
213
|
-
): Promise<{ job:
|
|
276
|
+
filter?: ProvingJobFilter,
|
|
277
|
+
): Promise<{ job: ProvingJob; time: number } | undefined> {
|
|
214
278
|
const job = this.jobsCache.get(id);
|
|
215
279
|
if (!job) {
|
|
216
280
|
this.logger.warn(`Proving job id=${id} does not exist`);
|
|
@@ -255,7 +319,7 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
255
319
|
}
|
|
256
320
|
}
|
|
257
321
|
|
|
258
|
-
async reportProvingJobSuccess(id:
|
|
322
|
+
async reportProvingJobSuccess(id: ProvingJobId, value: ProofUri): Promise<void> {
|
|
259
323
|
const info = this.inProgress.get(id);
|
|
260
324
|
const item = this.jobsCache.get(id);
|
|
261
325
|
const retries = this.retries.get(id) ?? 0;
|
|
@@ -273,8 +337,13 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
273
337
|
this.logger.debug(
|
|
274
338
|
`Proving job complete id=${id} type=${ProvingRequestType[item.type]} totalAttempts=${retries + 1}`,
|
|
275
339
|
);
|
|
340
|
+
|
|
276
341
|
await this.database.setProvingJobResult(id, value);
|
|
277
|
-
|
|
342
|
+
|
|
343
|
+
const result: ProvingJobSettledResult = { status: 'fulfilled', value };
|
|
344
|
+
this.resultsCache.set(id, result);
|
|
345
|
+
this.promises.get(id)!.resolve(result);
|
|
346
|
+
this.instrumentation.incResolvedJobs(item.type);
|
|
278
347
|
}
|
|
279
348
|
|
|
280
349
|
private timeoutCheck = () => {
|
|
@@ -287,23 +356,28 @@ export class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer {
|
|
|
287
356
|
continue;
|
|
288
357
|
}
|
|
289
358
|
|
|
290
|
-
const
|
|
291
|
-
if (
|
|
359
|
+
const msSinceLastUpdate = (this.timeSource() - metadata.lastUpdatedAt) * 1000;
|
|
360
|
+
if (msSinceLastUpdate >= this.jobTimeoutMs) {
|
|
292
361
|
this.logger.warn(`Proving job id=${id} timed out. Adding it back to the queue.`);
|
|
293
362
|
this.inProgress.delete(id);
|
|
294
363
|
this.enqueueJobInternal(item);
|
|
364
|
+
this.instrumentation.incTimedOutJobs(item.type);
|
|
295
365
|
}
|
|
296
366
|
}
|
|
297
367
|
};
|
|
298
368
|
|
|
299
|
-
private enqueueJobInternal(job:
|
|
369
|
+
private enqueueJobInternal(job: ProvingJob): void {
|
|
370
|
+
if (!this.promises.has(job.id)) {
|
|
371
|
+
this.promises.set(job.id, promiseWithResolvers());
|
|
372
|
+
}
|
|
300
373
|
this.queues[job.type].put(job);
|
|
374
|
+
this.enqueuedAt.set(job.id, new Timer());
|
|
301
375
|
this.logger.debug(`Enqueued new proving job id=${job.id}`);
|
|
302
376
|
}
|
|
303
377
|
}
|
|
304
378
|
|
|
305
379
|
type ProvingQueues = {
|
|
306
|
-
[K in ProvingRequestType]: PriorityMemoryQueue<
|
|
380
|
+
[K in ProvingRequestType]: PriorityMemoryQueue<ProvingJob>;
|
|
307
381
|
};
|
|
308
382
|
|
|
309
383
|
/**
|
|
@@ -312,10 +386,12 @@ type ProvingQueues = {
|
|
|
312
386
|
* @param b - Another proving job
|
|
313
387
|
* @returns A number indicating the relative priority of the two proving jobs
|
|
314
388
|
*/
|
|
315
|
-
function provingJobComparator(a:
|
|
316
|
-
|
|
389
|
+
function provingJobComparator(a: ProvingJob, b: ProvingJob): -1 | 0 | 1 {
|
|
390
|
+
const aBlockNumber = a.blockNumber ?? 0;
|
|
391
|
+
const bBlockNumber = b.blockNumber ?? 0;
|
|
392
|
+
if (aBlockNumber < bBlockNumber) {
|
|
317
393
|
return -1;
|
|
318
|
-
} else if (
|
|
394
|
+
} else if (aBlockNumber > bBlockNumber) {
|
|
319
395
|
return 1;
|
|
320
396
|
} else {
|
|
321
397
|
return 0;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ProofUri, ProvingJob, ProvingJobId, ProvingJobSettledResult } from '@aztec/circuit-types';
|
|
2
|
+
|
|
3
|
+
import { type ProvingBrokerDatabase } from '../proving_broker_database.js';
|
|
4
|
+
|
|
5
|
+
export class InMemoryBrokerDatabase implements ProvingBrokerDatabase {
|
|
6
|
+
private jobs = new Map<ProvingJobId, ProvingJob>();
|
|
7
|
+
private results = new Map<ProvingJobId, ProvingJobSettledResult>();
|
|
8
|
+
|
|
9
|
+
getProvingJob(id: ProvingJobId): ProvingJob | undefined {
|
|
10
|
+
return this.jobs.get(id);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
getProvingJobResult(id: ProvingJobId): ProvingJobSettledResult | undefined {
|
|
14
|
+
return this.results.get(id);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
addProvingJob(request: ProvingJob): Promise<void> {
|
|
18
|
+
this.jobs.set(request.id, request);
|
|
19
|
+
return Promise.resolve();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
setProvingJobResult(id: ProvingJobId, value: ProofUri): Promise<void> {
|
|
23
|
+
this.results.set(id, { status: 'fulfilled', value });
|
|
24
|
+
return Promise.resolve();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setProvingJobError(id: ProvingJobId, reason: string): Promise<void> {
|
|
28
|
+
this.results.set(id, { status: 'rejected', reason });
|
|
29
|
+
return Promise.resolve();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
deleteProvingJobAndResult(id: ProvingJobId): Promise<void> {
|
|
33
|
+
this.jobs.delete(id);
|
|
34
|
+
this.results.delete(id);
|
|
35
|
+
return Promise.resolve();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
*allProvingJobs(): Iterable<[ProvingJob, ProvingJobSettledResult | undefined]> {
|
|
39
|
+
for (const item of this.jobs.values()) {
|
|
40
|
+
yield [item, this.results.get(item.id)] as const;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { type ProofUri, ProvingJob, type ProvingJobId, ProvingJobSettledResult } from '@aztec/circuit-types';
|
|
2
|
+
import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
|
|
3
|
+
import { type AztecKVStore, type AztecMap } from '@aztec/kv-store';
|
|
4
|
+
import { LmdbMetrics, Metrics, type TelemetryClient } from '@aztec/telemetry-client';
|
|
5
|
+
|
|
6
|
+
import { type ProvingBrokerDatabase } from '../proving_broker_database.js';
|
|
7
|
+
|
|
8
|
+
export class KVBrokerDatabase implements ProvingBrokerDatabase {
|
|
9
|
+
private jobs: AztecMap<ProvingJobId, string>;
|
|
10
|
+
private jobResults: AztecMap<ProvingJobId, string>;
|
|
11
|
+
private metrics: LmdbMetrics;
|
|
12
|
+
|
|
13
|
+
constructor(private store: AztecKVStore, client: TelemetryClient) {
|
|
14
|
+
this.metrics = new LmdbMetrics(
|
|
15
|
+
client.getMeter('KVBrokerDatabase'),
|
|
16
|
+
{
|
|
17
|
+
name: Metrics.PROVING_QUEUE_DB_MAP_SIZE,
|
|
18
|
+
description: 'Database map size for the proving broker',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: Metrics.PROVING_QUEUE_DB_USED_SIZE,
|
|
22
|
+
description: 'Database used size for the proving broker',
|
|
23
|
+
},
|
|
24
|
+
{ name: Metrics.PROVING_QUEUE_DB_NUM_ITEMS, description: 'Number of items in the broker database' },
|
|
25
|
+
() => store.estimateSize(),
|
|
26
|
+
);
|
|
27
|
+
this.jobs = store.openMap('proving_jobs');
|
|
28
|
+
this.jobResults = store.openMap('proving_job_results');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async addProvingJob(job: ProvingJob): Promise<void> {
|
|
32
|
+
await this.jobs.set(job.id, jsonStringify(job));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
*allProvingJobs(): Iterable<[ProvingJob, ProvingJobSettledResult | undefined]> {
|
|
36
|
+
for (const jobStr of this.jobs.values()) {
|
|
37
|
+
const job = jsonParseWithSchema(jobStr, ProvingJob);
|
|
38
|
+
const resultStr = this.jobResults.get(job.id);
|
|
39
|
+
const result = resultStr ? jsonParseWithSchema(resultStr, ProvingJobSettledResult) : undefined;
|
|
40
|
+
yield [job, result];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
deleteProvingJobAndResult(id: ProvingJobId): Promise<void> {
|
|
45
|
+
return this.store.transaction(() => {
|
|
46
|
+
void this.jobs.delete(id);
|
|
47
|
+
void this.jobResults.delete(id);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async setProvingJobError(id: ProvingJobId, reason: string): Promise<void> {
|
|
52
|
+
const result: ProvingJobSettledResult = { status: 'rejected', reason };
|
|
53
|
+
await this.jobResults.set(id, jsonStringify(result));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async setProvingJobResult(id: ProvingJobId, value: ProofUri): Promise<void> {
|
|
57
|
+
const result: ProvingJobSettledResult = { status: 'fulfilled', value };
|
|
58
|
+
await this.jobResults.set(id, jsonStringify(result));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -1,30 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type V2ProofOutput,
|
|
3
|
-
type V2ProvingJob,
|
|
4
|
-
type V2ProvingJobId,
|
|
5
|
-
type V2ProvingJobResult,
|
|
6
|
-
} from '@aztec/circuit-types';
|
|
1
|
+
import { type ProofUri, type ProvingJob, type ProvingJobId, type ProvingJobSettledResult } from '@aztec/circuit-types';
|
|
7
2
|
|
|
8
3
|
/**
|
|
9
4
|
* A database for storing proof requests and their results
|
|
10
5
|
*/
|
|
11
|
-
export interface
|
|
6
|
+
export interface ProvingBrokerDatabase {
|
|
12
7
|
/**
|
|
13
8
|
* Saves a proof request so it can be retrieved later
|
|
14
9
|
* @param request - The proof request to save
|
|
15
10
|
*/
|
|
16
|
-
addProvingJob(request:
|
|
11
|
+
addProvingJob(request: ProvingJob): Promise<void>;
|
|
17
12
|
|
|
18
13
|
/**
|
|
19
14
|
* Removes a proof request from the backend
|
|
20
15
|
* @param id - The ID of the proof request to remove
|
|
21
16
|
*/
|
|
22
|
-
deleteProvingJobAndResult(id:
|
|
17
|
+
deleteProvingJobAndResult(id: ProvingJobId): Promise<void>;
|
|
23
18
|
|
|
24
19
|
/**
|
|
25
20
|
* Returns an iterator over all saved proving jobs
|
|
26
21
|
*/
|
|
27
|
-
allProvingJobs(): Iterable<[
|
|
22
|
+
allProvingJobs(): Iterable<[ProvingJob, ProvingJobSettledResult | undefined]>;
|
|
28
23
|
|
|
29
24
|
/**
|
|
30
25
|
* Saves the result of a proof request
|
|
@@ -32,7 +27,7 @@ export interface ProvingJobDatabase {
|
|
|
32
27
|
* @param ProvingRequestType - The type of proof that was requested
|
|
33
28
|
* @param value - The result of the proof request
|
|
34
29
|
*/
|
|
35
|
-
setProvingJobResult(id:
|
|
30
|
+
setProvingJobResult(id: ProvingJobId, value: ProofUri): Promise<void>;
|
|
36
31
|
|
|
37
32
|
/**
|
|
38
33
|
* Saves an error that occurred while processing a proof request
|
|
@@ -40,5 +35,5 @@ export interface ProvingJobDatabase {
|
|
|
40
35
|
* @param ProvingRequestType - The type of proof that was requested
|
|
41
36
|
* @param err - The error that occurred while processing the proof request
|
|
42
37
|
*/
|
|
43
|
-
setProvingJobError(id:
|
|
38
|
+
setProvingJobError(id: ProvingJobId, err: string): Promise<void>;
|
|
44
39
|
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { ProvingRequestType } from '@aztec/circuit-types';
|
|
2
|
+
import { type Timer } from '@aztec/foundation/timer';
|
|
3
|
+
import {
|
|
4
|
+
Attributes,
|
|
5
|
+
type Histogram,
|
|
6
|
+
Metrics,
|
|
7
|
+
type ObservableGauge,
|
|
8
|
+
type ObservableResult,
|
|
9
|
+
type TelemetryClient,
|
|
10
|
+
type UpDownCounter,
|
|
11
|
+
ValueType,
|
|
12
|
+
millisecondBuckets,
|
|
13
|
+
} from '@aztec/telemetry-client';
|
|
14
|
+
|
|
15
|
+
export type MonitorCallback = (proofType: ProvingRequestType) => number;
|
|
16
|
+
|
|
17
|
+
export class ProvingBrokerInstrumentation {
|
|
18
|
+
private queueSize: ObservableGauge;
|
|
19
|
+
private activeJobs: ObservableGauge;
|
|
20
|
+
private resolvedJobs: UpDownCounter;
|
|
21
|
+
private rejectedJobs: UpDownCounter;
|
|
22
|
+
private timedOutJobs: UpDownCounter;
|
|
23
|
+
private jobWait: Histogram;
|
|
24
|
+
private jobDuration: Histogram;
|
|
25
|
+
private retriedJobs: UpDownCounter;
|
|
26
|
+
|
|
27
|
+
constructor(client: TelemetryClient, name = 'ProvingBroker') {
|
|
28
|
+
const meter = client.getMeter(name);
|
|
29
|
+
|
|
30
|
+
this.queueSize = meter.createObservableGauge(Metrics.PROVING_QUEUE_SIZE, {
|
|
31
|
+
valueType: ValueType.INT,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
this.activeJobs = meter.createObservableGauge(Metrics.PROVING_QUEUE_ACTIVE_JOBS, {
|
|
35
|
+
valueType: ValueType.INT,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
this.resolvedJobs = meter.createUpDownCounter(Metrics.PROVING_QUEUE_RESOLVED_JOBS, {
|
|
39
|
+
valueType: ValueType.INT,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
this.rejectedJobs = meter.createUpDownCounter(Metrics.PROVING_QUEUE_REJECTED_JOBS, {
|
|
43
|
+
valueType: ValueType.INT,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
this.retriedJobs = meter.createUpDownCounter(Metrics.PROVING_QUEUE_RETRIED_JOBS, {
|
|
47
|
+
valueType: ValueType.INT,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
this.timedOutJobs = meter.createUpDownCounter(Metrics.PROVING_QUEUE_TIMED_OUT_JOBS, {
|
|
51
|
+
valueType: ValueType.INT,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
this.jobWait = meter.createHistogram(Metrics.PROVING_QUEUE_JOB_WAIT, {
|
|
55
|
+
description: 'Records how long a job sits in the queue',
|
|
56
|
+
unit: 'ms',
|
|
57
|
+
valueType: ValueType.INT,
|
|
58
|
+
advice: {
|
|
59
|
+
explicitBucketBoundaries: millisecondBuckets(1), // 10ms -> ~327s
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
this.jobDuration = meter.createHistogram(Metrics.PROVING_QUEUE_JOB_DURATION, {
|
|
64
|
+
description: 'Records how long a job takes to complete',
|
|
65
|
+
unit: 'ms',
|
|
66
|
+
valueType: ValueType.INT,
|
|
67
|
+
advice: {
|
|
68
|
+
explicitBucketBoundaries: millisecondBuckets(1), // 10ms -> ~327s
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
monitorQueueDepth(fn: MonitorCallback) {
|
|
74
|
+
this.queueSize.addCallback(obs => this.observe(obs, fn));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
monitorActiveJobs(fn: MonitorCallback) {
|
|
78
|
+
this.activeJobs.addCallback(obs => this.observe(obs, fn));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
incResolvedJobs(proofType: ProvingRequestType) {
|
|
82
|
+
this.resolvedJobs.add(1, {
|
|
83
|
+
[Attributes.PROVING_JOB_TYPE]: ProvingRequestType[proofType],
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
incRejectedJobs(proofType: ProvingRequestType) {
|
|
88
|
+
this.rejectedJobs.add(1, {
|
|
89
|
+
[Attributes.PROVING_JOB_TYPE]: ProvingRequestType[proofType],
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
incRetriedJobs(proofType: ProvingRequestType) {
|
|
94
|
+
this.retriedJobs.add(1, {
|
|
95
|
+
[Attributes.PROVING_JOB_TYPE]: ProvingRequestType[proofType],
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
incTimedOutJobs(proofType: ProvingRequestType) {
|
|
100
|
+
this.timedOutJobs.add(1, {
|
|
101
|
+
[Attributes.PROVING_JOB_TYPE]: ProvingRequestType[proofType],
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
recordJobWait(proofType: ProvingRequestType, msOrTimer: Timer | number) {
|
|
106
|
+
const duration = typeof msOrTimer === 'number' ? msOrTimer : Math.floor(msOrTimer.ms());
|
|
107
|
+
this.jobWait.record(duration, {
|
|
108
|
+
[Attributes.PROVING_JOB_TYPE]: ProvingRequestType[proofType],
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
recordJobDuration(proofType: ProvingRequestType, msOrTimer: Timer | number) {
|
|
113
|
+
const duration = typeof msOrTimer === 'number' ? msOrTimer : Math.floor(msOrTimer.ms());
|
|
114
|
+
this.jobDuration.record(duration, {
|
|
115
|
+
[Attributes.PROVING_JOB_TYPE]: ProvingRequestType[proofType],
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private observe(obs: ObservableResult, fn: MonitorCallback) {
|
|
120
|
+
for (const proofType of Object.values(ProvingRequestType)) {
|
|
121
|
+
// a type predicate for TypeScript to recognize that we're only iterating over enum values
|
|
122
|
+
if (typeof proofType !== 'number') {
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
obs.observe(fn(proofType), {
|
|
126
|
+
[Attributes.PROVING_JOB_TYPE]: ProvingRequestType[proofType],
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|