@aztec/prover-client 0.67.1 → 0.68.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/light.d.ts +4 -3
- package/dest/block_builder/light.d.ts.map +1 -1
- package/dest/block_builder/light.js +23 -16
- package/dest/index.d.ts +0 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -2
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +3 -3
- package/dest/mocks/test_context.d.ts +3 -2
- package/dest/mocks/test_context.d.ts.map +1 -1
- package/dest/mocks/test_context.js +22 -11
- package/dest/orchestrator/block-building-helpers.d.ts +8 -2
- package/dest/orchestrator/block-building-helpers.d.ts.map +1 -1
- package/dest/orchestrator/block-building-helpers.js +20 -7
- package/dest/orchestrator/block-proving-state.d.ts +8 -5
- package/dest/orchestrator/block-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/block-proving-state.js +16 -7
- package/dest/orchestrator/epoch-proving-state.d.ts +3 -2
- package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/epoch-proving-state.js +3 -3
- package/dest/orchestrator/orchestrator.d.ts +10 -7
- package/dest/orchestrator/orchestrator.d.ts.map +1 -1
- package/dest/orchestrator/orchestrator.js +94 -56
- package/dest/orchestrator/tx-proving-state.d.ts +2 -1
- package/dest/orchestrator/tx-proving-state.d.ts.map +1 -1
- package/dest/orchestrator/tx-proving-state.js +3 -2
- package/dest/prover-agent/memory-proving-queue.d.ts +4 -2
- package/dest/prover-agent/memory-proving-queue.d.ts.map +1 -1
- package/dest/prover-agent/memory-proving-queue.js +240 -224
- package/dest/prover-agent/prover-agent.d.ts +11 -2
- package/dest/prover-agent/prover-agent.d.ts.map +1 -1
- package/dest/prover-agent/prover-agent.js +186 -159
- package/dest/prover-client/prover-client.d.ts +2 -3
- package/dest/prover-client/prover-client.d.ts.map +1 -1
- package/dest/prover-client/prover-client.js +4 -7
- package/dest/proving_broker/{caching_broker_facade.d.ts → broker_prover_facade.d.ts} +6 -9
- package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -0
- package/dest/proving_broker/broker_prover_facade.js +107 -0
- package/dest/proving_broker/proving_agent.d.ts +4 -3
- package/dest/proving_broker/proving_agent.d.ts.map +1 -1
- package/dest/proving_broker/proving_agent.js +73 -64
- package/dest/proving_broker/proving_broker.d.ts +4 -3
- package/dest/proving_broker/proving_broker.d.ts.map +1 -1
- package/dest/proving_broker/proving_broker.js +403 -324
- package/dest/proving_broker/proving_job_controller.d.ts +2 -1
- package/dest/proving_broker/proving_job_controller.d.ts.map +1 -1
- package/dest/proving_broker/proving_job_controller.js +15 -14
- package/dest/proving_broker/rpc.d.ts.map +1 -1
- package/dest/proving_broker/rpc.js +1 -2
- package/dest/test/mock_prover.d.ts +6 -6
- package/dest/test/mock_prover.d.ts.map +1 -1
- package/dest/test/mock_prover.js +3 -6
- package/package.json +16 -15
- package/src/block_builder/light.ts +23 -16
- package/src/index.ts +0 -1
- package/src/mocks/fixtures.ts +2 -2
- package/src/mocks/test_context.ts +31 -16
- package/src/orchestrator/block-building-helpers.ts +34 -18
- package/src/orchestrator/block-proving-state.ts +18 -8
- package/src/orchestrator/epoch-proving-state.ts +1 -4
- package/src/orchestrator/orchestrator.ts +113 -62
- package/src/orchestrator/tx-proving-state.ts +6 -4
- package/src/prover-agent/memory-proving-queue.ts +21 -15
- package/src/prover-agent/prover-agent.ts +65 -46
- package/src/prover-client/prover-client.ts +3 -10
- package/src/proving_broker/{caching_broker_facade.ts → broker_prover_facade.ts} +46 -83
- package/src/proving_broker/proving_agent.ts +72 -76
- package/src/proving_broker/proving_broker.ts +114 -36
- package/src/proving_broker/proving_job_controller.ts +13 -12
- package/src/proving_broker/rpc.ts +0 -1
- package/src/test/mock_prover.ts +17 -14
- package/dest/proving_broker/caching_broker_facade.d.ts.map +0 -1
- package/dest/proving_broker/caching_broker_facade.js +0 -153
- package/dest/proving_broker/prover_cache/memory.d.ts +0 -9
- package/dest/proving_broker/prover_cache/memory.d.ts.map +0 -1
- package/dest/proving_broker/prover_cache/memory.js +0 -16
- package/src/proving_broker/prover_cache/memory.ts +0 -20
|
@@ -1,354 +1,433 @@
|
|
|
1
|
+
import { __esDecorate, __runInitializers } from "tslib";
|
|
1
2
|
import { ProvingRequestType, } from '@aztec/circuit-types';
|
|
2
3
|
import { asyncPool } from '@aztec/foundation/async-pool';
|
|
3
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
5
|
import { RunningPromise, promiseWithResolvers } from '@aztec/foundation/promise';
|
|
5
6
|
import { PriorityMemoryQueue } from '@aztec/foundation/queue';
|
|
6
7
|
import { Timer } from '@aztec/foundation/timer';
|
|
8
|
+
import { trackSpan } from '@aztec/telemetry-client';
|
|
7
9
|
import assert from 'assert';
|
|
8
10
|
import { ProvingBrokerInstrumentation } from './proving_broker_instrumentation.js';
|
|
9
11
|
/**
|
|
10
12
|
* A broker that manages proof requests and distributes them to workers based on their priority.
|
|
11
13
|
* It takes a backend that is responsible for storing and retrieving proof requests and results.
|
|
12
14
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
count
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
start() {
|
|
85
|
-
for (const [item, result] of this.database.allProvingJobs()) {
|
|
86
|
-
this.logger.info(`Restoring proving job id=${item.id} settled=${!!result}`);
|
|
87
|
-
this.jobsCache.set(item.id, item);
|
|
88
|
-
this.promises.set(item.id, promiseWithResolvers());
|
|
89
|
-
if (result) {
|
|
90
|
-
this.promises.get(item.id).resolve(result);
|
|
91
|
-
this.resultsCache.set(item.id, result);
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
this.logger.debug(`Re-enqueuing proving job id=${item.id}`);
|
|
95
|
-
this.enqueueJobInternal(item);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
this.cleanupPromise.start();
|
|
99
|
-
this.instrumentation.monitorQueueDepth(this.measureQueueDepth);
|
|
100
|
-
this.instrumentation.monitorActiveJobs(this.countActiveJobs);
|
|
101
|
-
return Promise.resolve();
|
|
102
|
-
}
|
|
103
|
-
async stop() {
|
|
104
|
-
await this.cleanupPromise.stop();
|
|
105
|
-
}
|
|
106
|
-
async enqueueProvingJob(job) {
|
|
107
|
-
if (this.jobsCache.has(job.id)) {
|
|
108
|
-
const existing = this.jobsCache.get(job.id);
|
|
109
|
-
assert.deepStrictEqual(job, existing, 'Duplicate proving job ID');
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
await this.database.addProvingJob(job);
|
|
113
|
-
this.jobsCache.set(job.id, job);
|
|
114
|
-
this.enqueueJobInternal(job);
|
|
115
|
-
}
|
|
116
|
-
waitForJobToSettle(id) {
|
|
117
|
-
const promiseWithResolvers = this.promises.get(id);
|
|
118
|
-
if (!promiseWithResolvers) {
|
|
119
|
-
return Promise.resolve({ status: 'rejected', reason: `Job ${id} not found` });
|
|
120
|
-
}
|
|
121
|
-
return promiseWithResolvers.promise;
|
|
122
|
-
}
|
|
123
|
-
async cancelProvingJob(id) {
|
|
124
|
-
// notify listeners of the cancellation
|
|
125
|
-
if (!this.resultsCache.has(id)) {
|
|
126
|
-
this.logger.info(`Cancelling job id=${id}`);
|
|
127
|
-
await this.reportProvingJobError(id, 'Aborted', false);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
async cleanUpProvingJobState(id) {
|
|
131
|
-
if (!this.resultsCache.has(id)) {
|
|
132
|
-
this.logger.warn(`Can't cleanup busy proving job: id=${id}`);
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
this.logger.debug(`Cleaning up state for job id=${id}`);
|
|
136
|
-
await this.database.deleteProvingJobAndResult(id);
|
|
137
|
-
this.jobsCache.delete(id);
|
|
138
|
-
this.promises.delete(id);
|
|
139
|
-
this.resultsCache.delete(id);
|
|
140
|
-
this.inProgress.delete(id);
|
|
141
|
-
this.retries.delete(id);
|
|
142
|
-
}
|
|
143
|
-
getProvingJobStatus(id) {
|
|
144
|
-
const result = this.resultsCache.get(id);
|
|
145
|
-
if (result) {
|
|
146
|
-
return Promise.resolve(result);
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
// no result yet, check if we know the item
|
|
150
|
-
const item = this.jobsCache.get(id);
|
|
151
|
-
if (!item) {
|
|
152
|
-
this.logger.warn(`Proving job id=${id} not found`);
|
|
153
|
-
return Promise.resolve({ status: 'not-found' });
|
|
15
|
+
let ProvingBroker = (() => {
|
|
16
|
+
var _a;
|
|
17
|
+
let _instanceExtraInitializers = [];
|
|
18
|
+
let _cleanupPass_decorators;
|
|
19
|
+
return _a = class ProvingBroker {
|
|
20
|
+
constructor(database, client, { jobTimeoutMs = 30000, timeoutIntervalMs = 10000, maxRetries = 3, maxEpochsToKeepResultsFor = 1, maxParallelCleanUps = 20, } = {}, logger = createLogger('prover-client:proving-broker')) {
|
|
21
|
+
this.database = (__runInitializers(this, _instanceExtraInitializers), database);
|
|
22
|
+
this.logger = logger;
|
|
23
|
+
this.queues = {
|
|
24
|
+
[ProvingRequestType.PUBLIC_VM]: new PriorityMemoryQueue(provingJobComparator),
|
|
25
|
+
[ProvingRequestType.TUBE_PROOF]: new PriorityMemoryQueue(provingJobComparator),
|
|
26
|
+
[ProvingRequestType.PRIVATE_KERNEL_EMPTY]: new PriorityMemoryQueue(provingJobComparator),
|
|
27
|
+
[ProvingRequestType.PRIVATE_BASE_ROLLUP]: new PriorityMemoryQueue(provingJobComparator),
|
|
28
|
+
[ProvingRequestType.PUBLIC_BASE_ROLLUP]: new PriorityMemoryQueue(provingJobComparator),
|
|
29
|
+
[ProvingRequestType.MERGE_ROLLUP]: new PriorityMemoryQueue(provingJobComparator),
|
|
30
|
+
[ProvingRequestType.ROOT_ROLLUP]: new PriorityMemoryQueue(provingJobComparator),
|
|
31
|
+
[ProvingRequestType.BLOCK_MERGE_ROLLUP]: new PriorityMemoryQueue(provingJobComparator),
|
|
32
|
+
[ProvingRequestType.BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue(provingJobComparator),
|
|
33
|
+
[ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP]: new PriorityMemoryQueue(provingJobComparator),
|
|
34
|
+
[ProvingRequestType.BASE_PARITY]: new PriorityMemoryQueue(provingJobComparator),
|
|
35
|
+
[ProvingRequestType.ROOT_PARITY]: new PriorityMemoryQueue(provingJobComparator),
|
|
36
|
+
};
|
|
37
|
+
// holds a copy of the database in memory in order to quickly fulfill requests
|
|
38
|
+
// this is fine because this broker is the only one that can modify the database
|
|
39
|
+
this.jobsCache = new Map();
|
|
40
|
+
// as above, but for results
|
|
41
|
+
this.resultsCache = new Map();
|
|
42
|
+
// tracks when each job was enqueued
|
|
43
|
+
this.enqueuedAt = new Map();
|
|
44
|
+
// keeps track of which jobs are currently being processed
|
|
45
|
+
// in the event of a crash this information is lost, but that's ok
|
|
46
|
+
// the next time the broker starts it will recreate jobsCache and still
|
|
47
|
+
// accept results from the workers
|
|
48
|
+
this.inProgress = new Map();
|
|
49
|
+
// keep track of which proving job has been retried
|
|
50
|
+
this.retries = new Map();
|
|
51
|
+
// a map of promises that will be resolved when a job is settled
|
|
52
|
+
this.promises = new Map();
|
|
53
|
+
this.msTimeSource = () => Date.now();
|
|
54
|
+
/**
|
|
55
|
+
* The broker keeps track of the highest epoch its seen.
|
|
56
|
+
* This information is used for garbage collection: once it reaches the next epoch, it can start pruning the database of old state.
|
|
57
|
+
* This clean up pass is only done against _settled_ jobs. This pass will not cancel jobs that are in-progress or in-queue.
|
|
58
|
+
* It is a client responsibility to cancel jobs if they are no longer necessary.
|
|
59
|
+
* Example:
|
|
60
|
+
* proving epoch 11 - the broker will wipe all setlled jobs for epochs 9 and lower
|
|
61
|
+
* finished proving epoch 11 and got first job for epoch 12 -> the broker will wipe all setlled jobs for epochs 10 and lower
|
|
62
|
+
* reorged back to end of epoch 10 -> epoch 11 is skipped and epoch 12 starts -> the broker will wipe all setlled jobs for epochs 10 and lower
|
|
63
|
+
*/
|
|
64
|
+
this.epochHeight = 0;
|
|
65
|
+
this.maxEpochsToKeepResultsFor = 1;
|
|
66
|
+
this.measureQueueDepth = (type) => {
|
|
67
|
+
return this.queues[type].length();
|
|
68
|
+
};
|
|
69
|
+
this.countActiveJobs = (type) => {
|
|
70
|
+
let count = 0;
|
|
71
|
+
for (const { id } of this.inProgress.values()) {
|
|
72
|
+
const job = this.jobsCache.get(id);
|
|
73
|
+
if (job?.type === type) {
|
|
74
|
+
count++;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return count;
|
|
78
|
+
};
|
|
79
|
+
this.tracer = client.getTracer('ProvingBroker');
|
|
80
|
+
this.instrumentation = new ProvingBrokerInstrumentation(client);
|
|
81
|
+
this.cleanupPromise = new RunningPromise(this.cleanupPass.bind(this), this.logger, timeoutIntervalMs);
|
|
82
|
+
this.jobTimeoutMs = jobTimeoutMs;
|
|
83
|
+
this.maxRetries = maxRetries;
|
|
84
|
+
this.maxEpochsToKeepResultsFor = maxEpochsToKeepResultsFor;
|
|
85
|
+
this.maxParallelCleanUps = maxParallelCleanUps;
|
|
154
86
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const allowedProofs = Array.isArray(filter.allowList) && filter.allowList.length > 0
|
|
161
|
-
? [...filter.allowList]
|
|
162
|
-
: Object.values(ProvingRequestType).filter((x) => typeof x === 'number');
|
|
163
|
-
allowedProofs.sort(proofTypeComparator);
|
|
164
|
-
for (const proofType of allowedProofs) {
|
|
165
|
-
const queue = this.queues[proofType];
|
|
166
|
-
let enqueuedJob;
|
|
167
|
-
// exhaust the queue and make sure we're not sending a job that's already in progress
|
|
168
|
-
// or has already been completed
|
|
169
|
-
// this can happen if the broker crashes and restarts
|
|
170
|
-
// it's possible agents will report progress or results for jobs that are in the queue (after the restart)
|
|
171
|
-
while ((enqueuedJob = queue.getImmediate())) {
|
|
172
|
-
const job = this.jobsCache.get(enqueuedJob.id);
|
|
173
|
-
if (job && !this.inProgress.has(enqueuedJob.id) && !this.resultsCache.has(enqueuedJob.id)) {
|
|
174
|
-
const time = this.msTimeSource();
|
|
175
|
-
this.inProgress.set(job.id, {
|
|
176
|
-
id: job.id,
|
|
177
|
-
startedAt: time,
|
|
178
|
-
lastUpdatedAt: time,
|
|
87
|
+
start() {
|
|
88
|
+
for (const [item, result] of this.database.allProvingJobs()) {
|
|
89
|
+
this.logger.info(`Restoring proving job id=${item.id} settled=${!!result}`, {
|
|
90
|
+
provingJobId: item.id,
|
|
91
|
+
status: result ? result.status : 'pending',
|
|
179
92
|
});
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
93
|
+
this.jobsCache.set(item.id, item);
|
|
94
|
+
this.promises.set(item.id, promiseWithResolvers());
|
|
95
|
+
if (result) {
|
|
96
|
+
this.promises.get(item.id).resolve(result);
|
|
97
|
+
this.resultsCache.set(item.id, result);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
this.enqueueJobInternal(item);
|
|
183
101
|
}
|
|
184
|
-
return { job, time };
|
|
185
102
|
}
|
|
103
|
+
this.cleanupPromise.start();
|
|
104
|
+
this.instrumentation.monitorQueueDepth(this.measureQueueDepth);
|
|
105
|
+
this.instrumentation.monitorActiveJobs(this.countActiveJobs);
|
|
106
|
+
return Promise.resolve();
|
|
186
107
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
const result = { status: 'rejected', reason: String(err) };
|
|
218
|
-
this.resultsCache.set(id, result);
|
|
219
|
-
this.promises.get(id).resolve(result);
|
|
220
|
-
this.instrumentation.incRejectedJobs(item.type);
|
|
221
|
-
if (info) {
|
|
222
|
-
const duration = this.msTimeSource() - info.startedAt;
|
|
223
|
-
this.instrumentation.recordJobDuration(item.type, duration);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
reportProvingJobProgress(id, startedAt, filter) {
|
|
227
|
-
const job = this.jobsCache.get(id);
|
|
228
|
-
if (!job) {
|
|
229
|
-
this.logger.warn(`Proving job id=${id} does not exist`);
|
|
230
|
-
return filter ? this.getProvingJob(filter) : Promise.resolve(undefined);
|
|
231
|
-
}
|
|
232
|
-
if (this.resultsCache.has(id)) {
|
|
233
|
-
this.logger.warn(`Proving job id=${id} has already been completed`);
|
|
234
|
-
return filter ? this.getProvingJob(filter) : Promise.resolve(undefined);
|
|
235
|
-
}
|
|
236
|
-
const metadata = this.inProgress.get(id);
|
|
237
|
-
const now = this.msTimeSource();
|
|
238
|
-
if (!metadata) {
|
|
239
|
-
this.logger.warn(`Proving job id=${id} type=${ProvingRequestType[job.type]} not found in the in-progress cache, adding it`);
|
|
240
|
-
// the queue will still contain the item at this point!
|
|
241
|
-
// we need to be careful when popping off the queue to make sure we're not sending
|
|
242
|
-
// a job that's already in progress
|
|
243
|
-
this.inProgress.set(id, {
|
|
244
|
-
id,
|
|
245
|
-
startedAt,
|
|
246
|
-
lastUpdatedAt: this.msTimeSource(),
|
|
247
|
-
});
|
|
248
|
-
return Promise.resolve(undefined);
|
|
249
|
-
}
|
|
250
|
-
else if (startedAt <= metadata.startedAt) {
|
|
251
|
-
if (startedAt < metadata.startedAt) {
|
|
252
|
-
this.logger.debug(`Proving job id=${id} type=${ProvingRequestType[job.type]} startedAt=${startedAt} older agent has taken job`);
|
|
108
|
+
async stop() {
|
|
109
|
+
await this.cleanupPromise.stop();
|
|
110
|
+
}
|
|
111
|
+
async enqueueProvingJob(job) {
|
|
112
|
+
if (this.jobsCache.has(job.id)) {
|
|
113
|
+
const existing = this.jobsCache.get(job.id);
|
|
114
|
+
assert.deepStrictEqual(job, existing, 'Duplicate proving job ID');
|
|
115
|
+
this.logger.debug(`Duplicate proving job id=${job.id} epochNumber=${job.epochNumber}. Ignoring`, {
|
|
116
|
+
provingJobId: job.id,
|
|
117
|
+
});
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (this.isJobStale(job)) {
|
|
121
|
+
this.logger.warn(`Tried enqueueing stale proving job id=${job.id} epochNumber=${job.epochNumber}`, {
|
|
122
|
+
provingJobId: job.id,
|
|
123
|
+
});
|
|
124
|
+
throw new Error(`Epoch too old: job epoch ${job.epochNumber}, current epoch: ${this.epochHeight}`);
|
|
125
|
+
}
|
|
126
|
+
this.logger.info(`New proving job id=${job.id} epochNumber=${job.epochNumber}`, { provingJobId: job.id });
|
|
127
|
+
try {
|
|
128
|
+
// do this first so it acts as a "lock". If this job is enqueued again while we're saving it the if at the top will catch it.
|
|
129
|
+
this.jobsCache.set(job.id, job);
|
|
130
|
+
await this.database.addProvingJob(job);
|
|
131
|
+
this.enqueueJobInternal(job);
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
this.logger.error(`Failed to save proving job id=${job.id}: ${err}`, err, { provingJobId: job.id });
|
|
135
|
+
this.jobsCache.delete(job.id);
|
|
136
|
+
throw err;
|
|
137
|
+
}
|
|
253
138
|
}
|
|
254
|
-
|
|
255
|
-
this.
|
|
139
|
+
waitForJobToSettle(id) {
|
|
140
|
+
const promiseWithResolvers = this.promises.get(id);
|
|
141
|
+
if (!promiseWithResolvers) {
|
|
142
|
+
this.logger.warn(`Job id=${id} not found`, { provingJobId: id });
|
|
143
|
+
return Promise.resolve({ status: 'rejected', reason: `Job ${id} not found` });
|
|
144
|
+
}
|
|
145
|
+
return promiseWithResolvers.promise;
|
|
256
146
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
async reportProvingJobSuccess(id, value) {
|
|
270
|
-
const info = this.inProgress.get(id);
|
|
271
|
-
const item = this.jobsCache.get(id);
|
|
272
|
-
const retries = this.retries.get(id) ?? 0;
|
|
273
|
-
if (!item) {
|
|
274
|
-
this.logger.warn(`Proving job id=${id} not found`);
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
if (!info) {
|
|
278
|
-
this.logger.warn(`Proving job id=${id} type=${ProvingRequestType[item.type]} not in the in-progress set`);
|
|
279
|
-
}
|
|
280
|
-
else {
|
|
281
|
-
this.inProgress.delete(id);
|
|
282
|
-
}
|
|
283
|
-
if (this.resultsCache.has(id)) {
|
|
284
|
-
this.logger.warn(`Proving job id=${id} already settled, ignoring result`);
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
this.logger.debug(`Proving job complete id=${id} type=${ProvingRequestType[item.type]} totalAttempts=${retries + 1}`);
|
|
288
|
-
await this.database.setProvingJobResult(id, value);
|
|
289
|
-
const result = { status: 'fulfilled', value };
|
|
290
|
-
this.resultsCache.set(id, result);
|
|
291
|
-
this.promises.get(id).resolve(result);
|
|
292
|
-
this.instrumentation.incResolvedJobs(item.type);
|
|
293
|
-
}
|
|
294
|
-
async cleanupStaleJobs() {
|
|
295
|
-
const jobIds = Array.from(this.jobsCache.keys());
|
|
296
|
-
const jobsToClean = [];
|
|
297
|
-
for (const id of jobIds) {
|
|
298
|
-
const job = this.jobsCache.get(id);
|
|
299
|
-
const isComplete = this.resultsCache.has(id);
|
|
300
|
-
if (isComplete && this.isJobStale(job)) {
|
|
301
|
-
jobsToClean.push(id);
|
|
147
|
+
async cancelProvingJob(id) {
|
|
148
|
+
if (!this.jobsCache.has(id)) {
|
|
149
|
+
this.logger.warn(`Can't cancel a job that doesn't exist id=${id}`, { provingJobId: id });
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
// notify listeners of the cancellation
|
|
153
|
+
if (!this.resultsCache.has(id)) {
|
|
154
|
+
this.logger.info(`Cancelling job id=${id}`, { provingJobId: id });
|
|
155
|
+
await this.reportProvingJobError(id, 'Aborted', false);
|
|
156
|
+
}
|
|
302
157
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
this.
|
|
158
|
+
async cleanUpProvingJobState(id) {
|
|
159
|
+
if (!this.jobsCache.has(id)) {
|
|
160
|
+
this.logger.warn(`Can't clean up a job that doesn't exist id=${id}`, { provingJobId: id });
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (!this.resultsCache.has(id)) {
|
|
164
|
+
this.logger.warn(`Can't cleanup busy proving job: id=${id}`, { provingJobId: id });
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
this.logger.debug(`Cleaning up state for job id=${id}`, { provingJobId: id });
|
|
168
|
+
await this.database.deleteProvingJobAndResult(id);
|
|
169
|
+
this.jobsCache.delete(id);
|
|
170
|
+
this.promises.delete(id);
|
|
171
|
+
this.resultsCache.delete(id);
|
|
317
172
|
this.inProgress.delete(id);
|
|
318
|
-
|
|
173
|
+
this.retries.delete(id);
|
|
319
174
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
175
|
+
getProvingJobStatus(id) {
|
|
176
|
+
const result = this.resultsCache.get(id);
|
|
177
|
+
if (result) {
|
|
178
|
+
return Promise.resolve(result);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
// no result yet, check if we know the item
|
|
182
|
+
const item = this.jobsCache.get(id);
|
|
183
|
+
if (!item) {
|
|
184
|
+
this.logger.warn(`Proving job id=${id} not found`, { provingJobId: id });
|
|
185
|
+
return Promise.resolve({ status: 'not-found' });
|
|
186
|
+
}
|
|
187
|
+
return Promise.resolve({ status: this.inProgress.has(id) ? 'in-progress' : 'in-queue' });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// eslint-disable-next-line require-await
|
|
191
|
+
async getProvingJob(filter = { allowList: [] }) {
|
|
192
|
+
const allowedProofs = Array.isArray(filter.allowList) && filter.allowList.length > 0
|
|
193
|
+
? [...filter.allowList]
|
|
194
|
+
: Object.values(ProvingRequestType).filter((x) => typeof x === 'number');
|
|
195
|
+
allowedProofs.sort(proofTypeComparator);
|
|
196
|
+
for (const proofType of allowedProofs) {
|
|
197
|
+
const queue = this.queues[proofType];
|
|
198
|
+
let enqueuedJob;
|
|
199
|
+
// exhaust the queue and make sure we're not sending a job that's already in progress
|
|
200
|
+
// or has already been completed
|
|
201
|
+
// this can happen if the broker crashes and restarts
|
|
202
|
+
// it's possible agents will report progress or results for jobs that are in the queue (after the restart)
|
|
203
|
+
while ((enqueuedJob = queue.getImmediate())) {
|
|
204
|
+
const job = this.jobsCache.get(enqueuedJob.id);
|
|
205
|
+
if (job && !this.inProgress.has(enqueuedJob.id) && !this.resultsCache.has(enqueuedJob.id)) {
|
|
206
|
+
const time = this.msTimeSource();
|
|
207
|
+
this.inProgress.set(job.id, {
|
|
208
|
+
id: job.id,
|
|
209
|
+
startedAt: time,
|
|
210
|
+
lastUpdatedAt: time,
|
|
211
|
+
});
|
|
212
|
+
const enqueuedAt = this.enqueuedAt.get(job.id);
|
|
213
|
+
if (enqueuedAt) {
|
|
214
|
+
this.instrumentation.recordJobWait(job.type, enqueuedAt);
|
|
215
|
+
}
|
|
216
|
+
return { job, time };
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return undefined;
|
|
221
|
+
}
|
|
222
|
+
async reportProvingJobError(id, err, retry = false) {
|
|
223
|
+
const info = this.inProgress.get(id);
|
|
224
|
+
const item = this.jobsCache.get(id);
|
|
225
|
+
const retries = this.retries.get(id) ?? 0;
|
|
226
|
+
if (!item) {
|
|
227
|
+
this.logger.warn(`Can't set error on unknown proving job id=${id} err=${err}`, { provingJoId: id });
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (!info) {
|
|
231
|
+
this.logger.warn(`Proving job id=${id} type=${ProvingRequestType[item.type]} not in the in-progress set`, {
|
|
232
|
+
provingJobId: id,
|
|
233
|
+
});
|
|
326
234
|
}
|
|
327
235
|
else {
|
|
328
|
-
this.logger.warn(`Proving job id=${id} timed out. Adding it back to the queue.`);
|
|
329
236
|
this.inProgress.delete(id);
|
|
237
|
+
}
|
|
238
|
+
if (this.resultsCache.has(id)) {
|
|
239
|
+
this.logger.warn(`Proving job id=${id} is already settled, ignoring err=${err}`, {
|
|
240
|
+
provingJobId: id,
|
|
241
|
+
});
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (retry && retries + 1 < this.maxRetries && !this.isJobStale(item)) {
|
|
245
|
+
this.logger.info(`Retrying proving job id=${id} type=${ProvingRequestType[item.type]} retry=${retries + 1} err=${err}`, {
|
|
246
|
+
provingJobId: id,
|
|
247
|
+
});
|
|
248
|
+
this.retries.set(id, retries + 1);
|
|
330
249
|
this.enqueueJobInternal(item);
|
|
331
|
-
this.instrumentation.
|
|
250
|
+
this.instrumentation.incRetriedJobs(item.type);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
this.logger.info(`Marking proving job as failed id=${id} type=${ProvingRequestType[item.type]} totalAttempts=${retries + 1} err=${err}`, {
|
|
254
|
+
provingJobId: id,
|
|
255
|
+
});
|
|
256
|
+
// save the result to the cache and notify clients of the job status
|
|
257
|
+
// this should work even if our database breaks because the result is cached in memory
|
|
258
|
+
const result = { status: 'rejected', reason: String(err) };
|
|
259
|
+
this.resultsCache.set(id, result);
|
|
260
|
+
this.promises.get(id).resolve(result);
|
|
261
|
+
this.instrumentation.incRejectedJobs(item.type);
|
|
262
|
+
if (info) {
|
|
263
|
+
const duration = this.msTimeSource() - info.startedAt;
|
|
264
|
+
this.instrumentation.recordJobDuration(item.type, duration);
|
|
265
|
+
}
|
|
266
|
+
try {
|
|
267
|
+
await this.database.setProvingJobError(id, err);
|
|
268
|
+
}
|
|
269
|
+
catch (saveErr) {
|
|
270
|
+
this.logger.error(`Failed to save proving job error status id=${id} jobErr=${err}`, saveErr, {
|
|
271
|
+
provingJobId: id,
|
|
272
|
+
});
|
|
273
|
+
throw saveErr;
|
|
332
274
|
}
|
|
333
275
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
276
|
+
reportProvingJobProgress(id, startedAt, filter) {
|
|
277
|
+
const job = this.jobsCache.get(id);
|
|
278
|
+
if (!job) {
|
|
279
|
+
this.logger.warn(`Proving job id=${id} does not exist`, { provingJobId: id });
|
|
280
|
+
return filter ? this.getProvingJob(filter) : Promise.resolve(undefined);
|
|
281
|
+
}
|
|
282
|
+
if (this.resultsCache.has(id)) {
|
|
283
|
+
this.logger.warn(`Proving job id=${id} has already been completed`, { provingJobId: id });
|
|
284
|
+
return filter ? this.getProvingJob(filter) : Promise.resolve(undefined);
|
|
285
|
+
}
|
|
286
|
+
const metadata = this.inProgress.get(id);
|
|
287
|
+
const now = this.msTimeSource();
|
|
288
|
+
if (!metadata) {
|
|
289
|
+
this.logger.warn(`Proving job id=${id} type=${ProvingRequestType[job.type]} not found in the in-progress cache, adding it`, { provingJobId: id });
|
|
290
|
+
// the queue will still contain the item at this point!
|
|
291
|
+
// we need to be careful when popping off the queue to make sure we're not sending
|
|
292
|
+
// a job that's already in progress
|
|
293
|
+
this.inProgress.set(id, {
|
|
294
|
+
id,
|
|
295
|
+
startedAt,
|
|
296
|
+
lastUpdatedAt: this.msTimeSource(),
|
|
297
|
+
});
|
|
298
|
+
return Promise.resolve(undefined);
|
|
299
|
+
}
|
|
300
|
+
else if (startedAt <= metadata.startedAt) {
|
|
301
|
+
if (startedAt < metadata.startedAt) {
|
|
302
|
+
this.logger.info(`Proving job id=${id} type=${ProvingRequestType[job.type]} startedAt=${startedAt} older agent has taken job`, { provingJobId: id });
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
this.logger.debug(`Proving job id=${id} type=${ProvingRequestType[job.type]} heartbeat`, { provingJobId: id });
|
|
306
|
+
}
|
|
307
|
+
metadata.startedAt = startedAt;
|
|
308
|
+
metadata.lastUpdatedAt = now;
|
|
309
|
+
return Promise.resolve(undefined);
|
|
310
|
+
}
|
|
311
|
+
else if (filter) {
|
|
312
|
+
this.logger.warn(`Proving job id=${id} type=${ProvingRequestType[job.type]} already being worked on by another agent. Sending new one`, { provingJobId: id });
|
|
313
|
+
return this.getProvingJob(filter);
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
return Promise.resolve(undefined);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
async reportProvingJobSuccess(id, value) {
|
|
320
|
+
const info = this.inProgress.get(id);
|
|
321
|
+
const item = this.jobsCache.get(id);
|
|
322
|
+
const retries = this.retries.get(id) ?? 0;
|
|
323
|
+
if (!item) {
|
|
324
|
+
this.logger.warn(`Proving job id=${id} not found`, { provingJobId: id });
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
if (!info) {
|
|
328
|
+
this.logger.warn(`Proving job id=${id} type=${ProvingRequestType[item.type]} not in the in-progress set`, {
|
|
329
|
+
provingJobId: id,
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
this.inProgress.delete(id);
|
|
334
|
+
}
|
|
335
|
+
if (this.resultsCache.has(id)) {
|
|
336
|
+
this.logger.warn(`Proving job id=${id} already settled, ignoring result`, { provingJobId: id });
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
this.logger.info(`Proving job complete id=${id} type=${ProvingRequestType[item.type]} totalAttempts=${retries + 1}`, { provingJobId: id });
|
|
340
|
+
// save result to our local cache and notify clients
|
|
341
|
+
// if save to database fails, that's ok because we have the result in memory
|
|
342
|
+
// if the broker crashes and needs the result again, we're covered because we can just recompute it
|
|
343
|
+
const result = { status: 'fulfilled', value };
|
|
344
|
+
this.resultsCache.set(id, result);
|
|
345
|
+
this.promises.get(id).resolve(result);
|
|
346
|
+
this.instrumentation.incResolvedJobs(item.type);
|
|
347
|
+
if (info) {
|
|
348
|
+
const duration = this.msTimeSource() - info.startedAt;
|
|
349
|
+
this.instrumentation.recordJobDuration(item.type, duration);
|
|
350
|
+
}
|
|
351
|
+
try {
|
|
352
|
+
await this.database.setProvingJobResult(id, value);
|
|
353
|
+
}
|
|
354
|
+
catch (saveErr) {
|
|
355
|
+
this.logger.error(`Failed to save proving job result id=${id}`, saveErr, {
|
|
356
|
+
provingJobId: id,
|
|
357
|
+
});
|
|
358
|
+
throw saveErr;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
async cleanupPass() {
|
|
362
|
+
await this.cleanupStaleJobs();
|
|
363
|
+
await this.reEnqueueExpiredJobs();
|
|
364
|
+
}
|
|
365
|
+
async cleanupStaleJobs() {
|
|
366
|
+
const jobIds = Array.from(this.jobsCache.keys());
|
|
367
|
+
const jobsToClean = [];
|
|
368
|
+
for (const id of jobIds) {
|
|
369
|
+
const job = this.jobsCache.get(id);
|
|
370
|
+
const isComplete = this.resultsCache.has(id);
|
|
371
|
+
if (isComplete && this.isJobStale(job)) {
|
|
372
|
+
jobsToClean.push(id);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
if (jobsToClean.length > 0) {
|
|
376
|
+
this.logger.info(`Cleaning up jobs=${jobsToClean.length}`);
|
|
377
|
+
await asyncPool(this.maxParallelCleanUps, jobsToClean, async (jobId) => {
|
|
378
|
+
await this.cleanUpProvingJobState(jobId);
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
async reEnqueueExpiredJobs() {
|
|
383
|
+
const inProgressEntries = Array.from(this.inProgress.entries());
|
|
384
|
+
for (const [id, metadata] of inProgressEntries) {
|
|
385
|
+
const item = this.jobsCache.get(id);
|
|
386
|
+
if (!item) {
|
|
387
|
+
this.logger.warn(`Proving job id=${id} not found. Removing it from the queue.`, { provingJobId: id });
|
|
388
|
+
this.inProgress.delete(id);
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
const now = this.msTimeSource();
|
|
392
|
+
const msSinceLastUpdate = now - metadata.lastUpdatedAt;
|
|
393
|
+
if (msSinceLastUpdate >= this.jobTimeoutMs) {
|
|
394
|
+
if (this.isJobStale(item)) {
|
|
395
|
+
// the job has timed out and it's also old, just cancel and move on
|
|
396
|
+
await this.cancelProvingJob(item.id);
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
this.logger.warn(`Proving job id=${id} timed out. Adding it back to the queue.`, { provingJobId: id });
|
|
400
|
+
this.inProgress.delete(id);
|
|
401
|
+
this.enqueueJobInternal(item);
|
|
402
|
+
this.instrumentation.incTimedOutJobs(item.type);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
enqueueJobInternal(job) {
|
|
408
|
+
if (!this.promises.has(job.id)) {
|
|
409
|
+
this.promises.set(job.id, promiseWithResolvers());
|
|
410
|
+
}
|
|
411
|
+
this.queues[job.type].put({
|
|
412
|
+
epochNumber: job.epochNumber,
|
|
413
|
+
id: job.id,
|
|
414
|
+
});
|
|
415
|
+
this.enqueuedAt.set(job.id, new Timer());
|
|
416
|
+
this.epochHeight = Math.max(this.epochHeight, job.epochNumber);
|
|
417
|
+
}
|
|
418
|
+
isJobStale(job) {
|
|
419
|
+
return job.epochNumber < this.epochHeight - this.maxEpochsToKeepResultsFor;
|
|
420
|
+
}
|
|
421
|
+
},
|
|
422
|
+
(() => {
|
|
423
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
424
|
+
_cleanupPass_decorators = [trackSpan('ProvingBroker.cleanupPass')];
|
|
425
|
+
__esDecorate(_a, null, _cleanupPass_decorators, { kind: "method", name: "cleanupPass", static: false, private: false, access: { has: obj => "cleanupPass" in obj, get: obj => obj.cleanupPass }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
426
|
+
if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
427
|
+
})(),
|
|
428
|
+
_a;
|
|
429
|
+
})();
|
|
430
|
+
export { ProvingBroker };
|
|
352
431
|
/**
|
|
353
432
|
* Compares two proving jobs and selects which one's more important
|
|
354
433
|
* @param a - A proving job
|
|
@@ -417,4 +496,4 @@ const PROOF_TYPES_IN_PRIORITY_ORDER = [
|
|
|
417
496
|
ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP,
|
|
418
497
|
ProvingRequestType.PRIVATE_KERNEL_EMPTY,
|
|
419
498
|
];
|
|
420
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmluZ19icm9rZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJvdmluZ19icm9rZXIvcHJvdmluZ19icm9rZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQVNMLGtCQUFrQixHQUNuQixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDckQsT0FBTyxFQUE2QixjQUFjLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUM1RyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHaEQsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBRzVCLE9BQU8sRUFBd0IsNEJBQTRCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQWtCekc7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLGFBQWE7SUE4RHhCLFlBQ1UsUUFBK0IsRUFDdkMsTUFBdUIsRUFDdkIsRUFDRSxZQUFZLEdBQUcsS0FBTSxFQUNyQixpQkFBaUIsR0FBRyxLQUFNLEVBQzFCLFVBQVUsR0FBRyxDQUFDLEVBQ2QseUJBQXlCLEdBQUcsQ0FBQyxFQUM3QixtQkFBbUIsR0FBRyxFQUFFLE1BQ0ksRUFBRSxFQUN4QixTQUFTLFlBQVksQ0FBQyw4QkFBOEIsQ0FBQztRQVRyRCxhQUFRLEdBQVIsUUFBUSxDQUF1QjtRQVMvQixXQUFNLEdBQU4sTUFBTSxDQUErQztRQXZFdkQsV0FBTSxHQUFrQjtZQUM5QixDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUksbUJBQW1CLENBQXFCLG9CQUFvQixDQUFDO1lBQ2pHLENBQUMsa0JBQWtCLENBQUMsVUFBVSxDQUFDLEVBQUUsSUFBSSxtQkFBbUIs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
|
|
499
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmluZ19icm9rZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJvdmluZ19icm9rZXIvcHJvdmluZ19icm9rZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFTTCxrQkFBa0IsR0FDbkIsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDekQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3JELE9BQU8sRUFBNkIsY0FBYyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDNUcsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDOUQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2hELE9BQU8sRUFBcUQsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFdkcsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBRzVCLE9BQU8sRUFBd0IsNEJBQTRCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQWtCekc7OztHQUdHO0lBQ1UsYUFBYTs7OztzQkFBYixhQUFhO1lBK0R4QixZQUNVLFFBQStCLEVBQ3ZDLE1BQXVCLEVBQ3ZCLEVBQ0UsWUFBWSxHQUFHLEtBQU0sRUFDckIsaUJBQWlCLEdBQUcsS0FBTSxFQUMxQixVQUFVLEdBQUcsQ0FBQyxFQUNkLHlCQUF5QixHQUFHLENBQUMsRUFDN0IsbUJBQW1CLEdBQUcsRUFBRSxNQUNJLEVBQUUsRUFDeEIsU0FBUyxZQUFZLENBQUMsOEJBQThCLENBQUM7Z0JBVHJELGFBQVEsSUFoRVAsbURBQWEsRUFnRWQsUUFBUSxFQUF1QjtnQkFTL0IsV0FBTSxHQUFOLE1BQU0sQ0FBK0M7Z0JBeEV2RCxXQUFNLEdBQWtCO29CQUM5QixDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUksbUJBQW1CLENB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
|