@aztec/prover-client 0.73.0 → 0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2

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.
Files changed (138) hide show
  1. package/dest/bin/get-proof-inputs.js +18 -16
  2. package/dest/block_builder/index.js +0 -1
  3. package/dest/block_builder/light.js +23 -13
  4. package/dest/config.js +9 -11
  5. package/dest/index.js +0 -1
  6. package/dest/mocks/fixtures.js +28 -26
  7. package/dest/mocks/test_context.js +55 -31
  8. package/dest/orchestrator/block-building-helpers.js +90 -90
  9. package/dest/orchestrator/block-proving-state.js +95 -70
  10. package/dest/orchestrator/epoch-proving-state.js +53 -40
  11. package/dest/orchestrator/index.js +0 -1
  12. package/dest/orchestrator/orchestrator.js +649 -653
  13. package/dest/orchestrator/orchestrator_metrics.js +4 -3
  14. package/dest/orchestrator/tx-proving-state.js +52 -51
  15. package/dest/prover-agent/index.js +0 -1
  16. package/dest/prover-agent/memory-proving-queue.js +237 -248
  17. package/dest/prover-agent/prover-agent.js +184 -187
  18. package/dest/prover-agent/proving-error.js +0 -1
  19. package/dest/prover-agent/queue_metrics.js +6 -5
  20. package/dest/prover-agent/rpc.js +6 -4
  21. package/dest/prover-client/factory.js +0 -1
  22. package/dest/prover-client/index.js +0 -1
  23. package/dest/prover-client/prover-client.js +30 -25
  24. package/dest/prover-client/server-epoch-prover.js +4 -4
  25. package/dest/proving_broker/broker_prover_facade.js +70 -59
  26. package/dest/proving_broker/config.js +22 -37
  27. package/dest/proving_broker/factory.js +1 -2
  28. package/dest/proving_broker/fixtures.js +0 -1
  29. package/dest/proving_broker/index.js +0 -1
  30. package/dest/proving_broker/proof_store/factory.js +9 -12
  31. package/dest/proving_broker/proof_store/gcs_proof_store.js +11 -7
  32. package/dest/proving_broker/proof_store/index.js +0 -1
  33. package/dest/proving_broker/proof_store/inline_proof_store.js +11 -7
  34. package/dest/proving_broker/proof_store/proof_store.js +3 -2
  35. package/dest/proving_broker/proving_agent.js +121 -110
  36. package/dest/proving_broker/proving_agent_instrumentation.js +3 -3
  37. package/dest/proving_broker/proving_broker.js +491 -451
  38. package/dest/proving_broker/proving_broker_database/memory.js +19 -13
  39. package/dest/proving_broker/proving_broker_database/persisted.js +41 -21
  40. package/dest/proving_broker/proving_broker_database.js +3 -2
  41. package/dest/proving_broker/proving_broker_instrumentation.js +28 -21
  42. package/dest/proving_broker/proving_job_controller.js +81 -62
  43. package/dest/proving_broker/rpc.js +23 -15
  44. package/dest/test/mock_prover.js +11 -9
  45. package/package.json +13 -11
  46. package/src/index.ts +1 -1
  47. package/src/orchestrator/block-building-helpers.ts +1 -1
  48. package/src/proving_broker/proving_agent.ts +30 -11
  49. package/src/proving_broker/proving_broker.ts +53 -27
  50. package/src/proving_broker/rpc.ts +8 -2
  51. package/dest/bin/get-proof-inputs.d.ts +0 -2
  52. package/dest/bin/get-proof-inputs.d.ts.map +0 -1
  53. package/dest/block_builder/index.d.ts +0 -6
  54. package/dest/block_builder/index.d.ts.map +0 -1
  55. package/dest/block_builder/light.d.ts +0 -31
  56. package/dest/block_builder/light.d.ts.map +0 -1
  57. package/dest/config.d.ts +0 -17
  58. package/dest/config.d.ts.map +0 -1
  59. package/dest/index.d.ts +0 -4
  60. package/dest/index.d.ts.map +0 -1
  61. package/dest/mocks/fixtures.d.ts +0 -19
  62. package/dest/mocks/fixtures.d.ts.map +0 -1
  63. package/dest/mocks/test_context.d.ts +0 -49
  64. package/dest/mocks/test_context.d.ts.map +0 -1
  65. package/dest/orchestrator/block-building-helpers.d.ts +0 -50
  66. package/dest/orchestrator/block-building-helpers.d.ts.map +0 -1
  67. package/dest/orchestrator/block-proving-state.d.ts +0 -71
  68. package/dest/orchestrator/block-proving-state.d.ts.map +0 -1
  69. package/dest/orchestrator/epoch-proving-state.d.ts +0 -56
  70. package/dest/orchestrator/epoch-proving-state.d.ts.map +0 -1
  71. package/dest/orchestrator/index.d.ts +0 -2
  72. package/dest/orchestrator/index.d.ts.map +0 -1
  73. package/dest/orchestrator/orchestrator.d.ts +0 -108
  74. package/dest/orchestrator/orchestrator.d.ts.map +0 -1
  75. package/dest/orchestrator/orchestrator_metrics.d.ts +0 -8
  76. package/dest/orchestrator/orchestrator_metrics.d.ts.map +0 -1
  77. package/dest/orchestrator/tx-proving-state.d.ts +0 -31
  78. package/dest/orchestrator/tx-proving-state.d.ts.map +0 -1
  79. package/dest/prover-agent/index.d.ts +0 -4
  80. package/dest/prover-agent/index.d.ts.map +0 -1
  81. package/dest/prover-agent/memory-proving-queue.d.ts +0 -82
  82. package/dest/prover-agent/memory-proving-queue.d.ts.map +0 -1
  83. package/dest/prover-agent/prover-agent.d.ts +0 -43
  84. package/dest/prover-agent/prover-agent.d.ts.map +0 -1
  85. package/dest/prover-agent/proving-error.d.ts +0 -5
  86. package/dest/prover-agent/proving-error.d.ts.map +0 -1
  87. package/dest/prover-agent/queue_metrics.d.ts +0 -10
  88. package/dest/prover-agent/queue_metrics.d.ts.map +0 -1
  89. package/dest/prover-agent/rpc.d.ts +0 -11
  90. package/dest/prover-agent/rpc.d.ts.map +0 -1
  91. package/dest/prover-client/factory.d.ts +0 -6
  92. package/dest/prover-client/factory.d.ts.map +0 -1
  93. package/dest/prover-client/index.d.ts +0 -3
  94. package/dest/prover-client/index.d.ts.map +0 -1
  95. package/dest/prover-client/prover-client.d.ts +0 -42
  96. package/dest/prover-client/prover-client.d.ts.map +0 -1
  97. package/dest/prover-client/server-epoch-prover.d.ts +0 -25
  98. package/dest/prover-client/server-epoch-prover.d.ts.map +0 -1
  99. package/dest/proving_broker/broker_prover_facade.d.ts +0 -39
  100. package/dest/proving_broker/broker_prover_facade.d.ts.map +0 -1
  101. package/dest/proving_broker/config.d.ts +0 -61
  102. package/dest/proving_broker/config.d.ts.map +0 -1
  103. package/dest/proving_broker/factory.d.ts +0 -5
  104. package/dest/proving_broker/factory.d.ts.map +0 -1
  105. package/dest/proving_broker/fixtures.d.ts +0 -5
  106. package/dest/proving_broker/fixtures.d.ts.map +0 -1
  107. package/dest/proving_broker/index.d.ts +0 -10
  108. package/dest/proving_broker/index.d.ts.map +0 -1
  109. package/dest/proving_broker/proof_store/factory.d.ts +0 -6
  110. package/dest/proving_broker/proof_store/factory.d.ts.map +0 -1
  111. package/dest/proving_broker/proof_store/gcs_proof_store.d.ts +0 -13
  112. package/dest/proving_broker/proof_store/gcs_proof_store.d.ts.map +0 -1
  113. package/dest/proving_broker/proof_store/index.d.ts +0 -4
  114. package/dest/proving_broker/proof_store/index.d.ts.map +0 -1
  115. package/dest/proving_broker/proof_store/inline_proof_store.d.ts +0 -14
  116. package/dest/proving_broker/proof_store/inline_proof_store.d.ts.map +0 -1
  117. package/dest/proving_broker/proof_store/proof_store.d.ts +0 -35
  118. package/dest/proving_broker/proof_store/proof_store.d.ts.map +0 -1
  119. package/dest/proving_broker/proving_agent.d.ts +0 -44
  120. package/dest/proving_broker/proving_agent.d.ts.map +0 -1
  121. package/dest/proving_broker/proving_agent_instrumentation.d.ts +0 -8
  122. package/dest/proving_broker/proving_agent_instrumentation.d.ts.map +0 -1
  123. package/dest/proving_broker/proving_broker.d.ts +0 -75
  124. package/dest/proving_broker/proving_broker.d.ts.map +0 -1
  125. package/dest/proving_broker/proving_broker_database/memory.d.ts +0 -16
  126. package/dest/proving_broker/proving_broker_database/memory.d.ts.map +0 -1
  127. package/dest/proving_broker/proving_broker_database/persisted.d.ts +0 -21
  128. package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +0 -1
  129. package/dest/proving_broker/proving_broker_database.d.ts +0 -39
  130. package/dest/proving_broker/proving_broker_database.d.ts.map +0 -1
  131. package/dest/proving_broker/proving_broker_instrumentation.d.ts +0 -25
  132. package/dest/proving_broker/proving_broker_instrumentation.d.ts.map +0 -1
  133. package/dest/proving_broker/proving_job_controller.d.ts +0 -31
  134. package/dest/proving_broker/proving_job_controller.d.ts.map +0 -1
  135. package/dest/proving_broker/rpc.d.ts +0 -11
  136. package/dest/proving_broker/rpc.d.ts.map +0 -1
  137. package/dest/test/mock_prover.d.ts +0 -33
  138. package/dest/test/mock_prover.d.ts.map +0 -1
@@ -1,5 +1,10 @@
1
- import { __esDecorate, __runInitializers } from "tslib";
2
- import { ProvingRequestType, } from '@aztec/circuit-types';
1
+ function _ts_decorate(decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ }
7
+ import { ProvingRequestType } from '@aztec/circuit-types';
3
8
  import { randomBytes } from '@aztec/foundation/crypto';
4
9
  import { AbortError, TimeoutError } from '@aztec/foundation/error';
5
10
  import { createLogger } from '@aztec/foundation/log';
@@ -9,252 +14,236 @@ import { trackSpan } from '@aztec/telemetry-client';
9
14
  import { InlineProofStore } from '../proving_broker/proof_store/index.js';
10
15
  import { ProvingQueueMetrics } from './queue_metrics.js';
11
16
  const MAX_RETRIES = 3;
12
- const defaultIdGenerator = () => randomBytes(4).toString('hex');
13
- const defaultTimeSource = () => Date.now();
17
+ const defaultIdGenerator = ()=>randomBytes(4).toString('hex');
18
+ const defaultTimeSource = ()=>Date.now();
14
19
  /**
15
20
  * A helper class that sits in between services that need proofs created and agents that can create them.
16
21
  * The queue accumulates jobs and provides them to agents prioritized by block number.
17
- */
18
- let MemoryProvingQueue = (() => {
19
- var _a;
20
- let _instanceExtraInitializers = [];
21
- let _poll_decorators;
22
- return _a = class MemoryProvingQueue {
23
- constructor(client,
24
- /** Timeout the job if an agent doesn't report back in this time */
25
- jobTimeoutMs = 60 * 1000,
26
- /** How often to check for timed out jobs */
27
- pollingIntervalMs = 1000, generateId = defaultIdGenerator, timeSource = defaultTimeSource, proofStore = new InlineProofStore()) {
28
- this.jobTimeoutMs = (__runInitializers(this, _instanceExtraInitializers), jobTimeoutMs);
29
- this.generateId = generateId;
30
- this.timeSource = timeSource;
31
- this.proofStore = proofStore;
32
- this.log = createLogger('prover-client:prover-pool:queue');
33
- this.queue = new PriorityMemoryQueue((a, b) => (a.epochNumber ?? 0) - (b.epochNumber ?? 0));
34
- this.jobsInProgress = new Map();
35
- this.tracer = client.getTracer('MemoryProvingQueue');
36
- this.metrics = new ProvingQueueMetrics(client, 'MemoryProvingQueue');
37
- this.runningPromise = new RunningPromise(this.poll.bind(this), this.log, pollingIntervalMs);
38
- }
39
- start() {
40
- if (this.runningPromise.isRunning()) {
41
- this.log.warn('Proving queue is already running');
42
- return;
43
- }
44
- this.runningPromise.start();
45
- this.log.info('Proving queue started');
46
- }
47
- async stop() {
48
- if (!this.runningPromise.isRunning()) {
49
- this.log.warn('Proving queue is already stopped');
50
- return;
51
- }
52
- await this.runningPromise.stop();
53
- this.log.info('Proving queue stopped');
54
- }
55
- async getProvingJob({ timeoutSec = 1 } = {}) {
56
- if (!this.runningPromise.isRunning()) {
57
- throw new Error('Proving queue is not running. Start the queue before getting jobs.');
58
- }
59
- try {
60
- const job = await this.queue.get(timeoutSec);
61
- if (!job) {
62
- return undefined;
63
- }
64
- if (job.signal?.aborted) {
65
- return undefined;
66
- }
67
- job.heartbeat = this.timeSource();
68
- this.jobsInProgress.set(job.id, job);
69
- return {
70
- id: job.id,
71
- type: job.type,
72
- inputsUri: job.inputsUri,
73
- epochNumber: job.epochNumber,
74
- };
75
- }
76
- catch (err) {
77
- if (err instanceof TimeoutError) {
78
- return undefined;
79
- }
80
- throw err;
81
- }
82
- }
83
- resolveProvingJob(jobId, result) {
84
- if (!this.runningPromise.isRunning()) {
85
- throw new Error('Proving queue is not running.');
86
- }
87
- const job = this.jobsInProgress.get(jobId);
88
- if (!job) {
89
- this.log.warn(`Job id=${jobId} not found. Can't resolve`);
90
- return Promise.resolve();
91
- }
92
- this.jobsInProgress.delete(jobId);
93
- if (!job.signal?.aborted) {
94
- job.resolve(result);
95
- }
96
- return Promise.resolve();
97
- }
98
- rejectProvingJob(jobId, reason) {
99
- if (!this.runningPromise.isRunning()) {
100
- throw new Error('Proving queue is not running.');
101
- }
102
- const job = this.jobsInProgress.get(jobId);
103
- if (!job) {
104
- this.log.warn(`Job id=${jobId} not found. Can't reject`);
105
- return Promise.resolve();
106
- }
107
- this.jobsInProgress.delete(jobId);
108
- if (job.signal?.aborted) {
109
- return Promise.resolve();
110
- }
111
- // every job should be retried with the exception of the public VM since its in development and can fail
112
- if (job.attempts < MAX_RETRIES && job.type !== ProvingRequestType.PUBLIC_VM) {
113
- job.attempts++;
114
- this.log.warn(`Job id=${job.id} type=${ProvingRequestType[job.type]} failed with error: ${reason}. Retry ${job.attempts}/${MAX_RETRIES}`);
115
- this.queue.put(job);
116
- }
117
- else {
118
- const logFn = job.type === ProvingRequestType.PUBLIC_VM && !process.env.AVM_PROVING_STRICT ? this.log.warn : this.log.error;
119
- logFn(`Job id=${job.id} type=${ProvingRequestType[job.type]} failed with error: ${reason}`);
120
- job.reject(new Error(reason));
121
- }
122
- return Promise.resolve();
123
- }
124
- heartbeat(jobId) {
125
- if (!this.runningPromise.isRunning()) {
126
- throw new Error('Proving queue is not running.');
127
- }
128
- const job = this.jobsInProgress.get(jobId);
129
- if (job) {
130
- job.heartbeat = this.timeSource();
131
- }
132
- return Promise.resolve();
133
- }
134
- isJobRunning(jobId) {
135
- return this.jobsInProgress.has(jobId);
136
- }
137
- poll() {
138
- const now = this.timeSource();
139
- this.metrics.recordQueueSize(this.queue.length());
140
- for (const job of this.jobsInProgress.values()) {
141
- if (job.signal?.aborted) {
142
- this.jobsInProgress.delete(job.id);
143
- continue;
144
- }
145
- if (job.heartbeat + this.jobTimeoutMs < now) {
146
- this.log.warn(`Job ${job.id} type=${ProvingRequestType[job.type]} has timed out`);
147
- this.jobsInProgress.delete(job.id);
148
- job.heartbeat = 0;
149
- this.queue.put(job);
150
- }
151
- }
152
- }
153
- async enqueue(type, inputs, signal, epochNumber) {
154
- if (!this.runningPromise.isRunning()) {
155
- return Promise.reject(new Error('Proving queue is not running.'));
156
- }
157
- const { promise, resolve, reject } = promiseWithResolvers();
158
- const id = this.generateId();
159
- const inputsUri = await this.proofStore.saveProofInput(id, type, inputs);
160
- const item = {
161
- id,
162
- type,
163
- inputsUri,
164
- signal,
165
- promise,
166
- resolve,
167
- reject,
168
- attempts: 1,
169
- heartbeat: 0,
170
- epochNumber: epochNumber ?? 0,
171
- };
172
- if (signal) {
173
- signal.addEventListener('abort', () => reject(new AbortError('Operation has been aborted')));
174
- }
175
- this.log.debug(`Adding id=${item.id} type=${ProvingRequestType[type]} proving job to queue depth=${this.queue.length()}`);
176
- if (!this.queue.put(item)) {
177
- throw new Error();
178
- }
179
- return promise.then(({ result }) => result);
180
- }
181
- getTubeProof(inputs, signal, epochNumber) {
182
- return this.enqueue(ProvingRequestType.TUBE_PROOF, inputs, signal, epochNumber);
183
- }
184
- /**
185
- * Creates a proof for the given input.
186
- * @param input - Input to the circuit.
187
- */
188
- getBaseParityProof(inputs, signal, epochNumber) {
189
- return this.enqueue(ProvingRequestType.BASE_PARITY, inputs, signal, epochNumber);
190
- }
191
- /**
192
- * Creates a proof for the given input.
193
- * @param input - Input to the circuit.
194
- */
195
- getRootParityProof(inputs, signal, epochNumber) {
196
- return this.enqueue(ProvingRequestType.ROOT_PARITY, inputs, signal, epochNumber);
197
- }
198
- getPrivateBaseRollupProof(inputs, signal, epochNumber) {
199
- return this.enqueue(ProvingRequestType.PRIVATE_BASE_ROLLUP, inputs, signal, epochNumber);
200
- }
201
- getPublicBaseRollupProof(inputs, signal, epochNumber) {
202
- return this.enqueue(ProvingRequestType.PUBLIC_BASE_ROLLUP, inputs, signal, epochNumber);
203
- }
204
- /**
205
- * Creates a proof for the given input.
206
- * @param input - Input to the circuit.
207
- */
208
- getMergeRollupProof(inputs, signal, epochNumber) {
209
- return this.enqueue(ProvingRequestType.MERGE_ROLLUP, inputs, signal, epochNumber);
210
- }
211
- /**
212
- * Creates a proof for the given input.
213
- * @param input - Input to the circuit.
214
- */
215
- getBlockRootRollupProof(inputs, signal, epochNumber) {
216
- return this.enqueue(ProvingRequestType.BLOCK_ROOT_ROLLUP, inputs, signal, epochNumber);
217
- }
218
- getSingleTxBlockRootRollupProof(inputs, signal, epochNumber) {
219
- return this.enqueue(ProvingRequestType.SINGLE_TX_BLOCK_ROOT_ROLLUP, inputs, signal, epochNumber);
220
- }
221
- getEmptyBlockRootRollupProof(inputs, signal, epochNumber) {
222
- return this.enqueue(ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP, inputs, signal, epochNumber);
223
- }
224
- /**
225
- * Creates a proof for the given input.
226
- * @param input - Input to the circuit.
227
- */
228
- getBlockMergeRollupProof(inputs, signal, epochNumber) {
229
- return this.enqueue(ProvingRequestType.BLOCK_MERGE_ROLLUP, inputs, signal, epochNumber);
230
- }
231
- /**
232
- * Creates a proof for the given input.
233
- * @param input - Input to the circuit.
234
- */
235
- getRootRollupProof(inputs, signal, epochNumber) {
236
- return this.enqueue(ProvingRequestType.ROOT_ROLLUP, inputs, signal, epochNumber);
237
- }
238
- /**
239
- * Creates an AVM proof.
240
- */
241
- getAvmProof(inputs, signal, epochNumber) {
242
- return this.enqueue(ProvingRequestType.PUBLIC_VM, inputs, signal, epochNumber);
243
- }
244
- /**
245
- * Verifies a circuit proof
246
- */
247
- verifyProof() {
248
- return Promise.reject('not implemented');
249
- }
250
- },
251
- (() => {
252
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
253
- _poll_decorators = [trackSpan('MemoryProvingQueue.poll')];
254
- __esDecorate(_a, null, _poll_decorators, { kind: "method", name: "poll", static: false, private: false, access: { has: obj => "poll" in obj, get: obj => obj.poll }, metadata: _metadata }, null, _instanceExtraInitializers);
255
- if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
256
- })(),
257
- _a;
258
- })();
259
- export { MemoryProvingQueue };
260
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtb3J5LXByb3ZpbmctcXVldWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJvdmVyLWFnZW50L21lbW9yeS1wcm92aW5nLXF1ZXVlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBTUwsa0JBQWtCLEdBR25CLE1BQU0sc0JBQXNCLENBQUM7QUEwQjlCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ25FLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNyRCxPQUFPLEVBQTZCLGNBQWMsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzVHLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzlELE9BQU8sRUFBcUMsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFdkYsT0FBTyxFQUFFLGdCQUFnQixFQUFtQixNQUFNLHdDQUF3QyxDQUFDO0FBQzNGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBVXpELE1BQU0sV0FBVyxHQUFHLENBQUMsQ0FBQztBQUV0QixNQUFNLGtCQUFrQixHQUFHLEdBQUcsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDaEUsTUFBTSxpQkFBaUIsR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDM0M7OztHQUdHO0lBQ1Usa0JBQWtCOzs7O3NCQUFsQixrQkFBa0I7WUFXN0IsWUFDRSxNQUF1QjtZQUN2QixtRUFBbUU7WUFDM0QsZUFBZSxFQUFFLEdBQUcsSUFBSTtZQUNoQyw0Q0FBNEM7WUFDNUMsaUJBQWlCLEdBQUcsSUFBSSxFQUNoQixhQUFhLGtCQUFr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
22
+ */ export class MemoryProvingQueue {
23
+ jobTimeoutMs;
24
+ generateId;
25
+ timeSource;
26
+ proofStore;
27
+ log;
28
+ queue;
29
+ jobsInProgress;
30
+ runningPromise;
31
+ metrics;
32
+ tracer;
33
+ constructor(client, /** Timeout the job if an agent doesn't report back in this time */ jobTimeoutMs = 60 * 1000, /** How often to check for timed out jobs */ pollingIntervalMs = 1000, generateId = defaultIdGenerator, timeSource = defaultTimeSource, proofStore = new InlineProofStore()){
34
+ this.jobTimeoutMs = jobTimeoutMs;
35
+ this.generateId = generateId;
36
+ this.timeSource = timeSource;
37
+ this.proofStore = proofStore;
38
+ this.log = createLogger('prover-client:prover-pool:queue');
39
+ this.queue = new PriorityMemoryQueue((a, b)=>(a.epochNumber ?? 0) - (b.epochNumber ?? 0));
40
+ this.jobsInProgress = new Map();
41
+ this.tracer = client.getTracer('MemoryProvingQueue');
42
+ this.metrics = new ProvingQueueMetrics(client, 'MemoryProvingQueue');
43
+ this.runningPromise = new RunningPromise(this.poll.bind(this), this.log, pollingIntervalMs);
44
+ }
45
+ start() {
46
+ if (this.runningPromise.isRunning()) {
47
+ this.log.warn('Proving queue is already running');
48
+ return;
49
+ }
50
+ this.runningPromise.start();
51
+ this.log.info('Proving queue started');
52
+ }
53
+ async stop() {
54
+ if (!this.runningPromise.isRunning()) {
55
+ this.log.warn('Proving queue is already stopped');
56
+ return;
57
+ }
58
+ await this.runningPromise.stop();
59
+ this.log.info('Proving queue stopped');
60
+ }
61
+ async getProvingJob({ timeoutSec = 1 } = {}) {
62
+ if (!this.runningPromise.isRunning()) {
63
+ throw new Error('Proving queue is not running. Start the queue before getting jobs.');
64
+ }
65
+ try {
66
+ const job = await this.queue.get(timeoutSec);
67
+ if (!job) {
68
+ return undefined;
69
+ }
70
+ if (job.signal?.aborted) {
71
+ return undefined;
72
+ }
73
+ job.heartbeat = this.timeSource();
74
+ this.jobsInProgress.set(job.id, job);
75
+ return {
76
+ id: job.id,
77
+ type: job.type,
78
+ inputsUri: job.inputsUri,
79
+ epochNumber: job.epochNumber
80
+ };
81
+ } catch (err) {
82
+ if (err instanceof TimeoutError) {
83
+ return undefined;
84
+ }
85
+ throw err;
86
+ }
87
+ }
88
+ resolveProvingJob(jobId, result) {
89
+ if (!this.runningPromise.isRunning()) {
90
+ throw new Error('Proving queue is not running.');
91
+ }
92
+ const job = this.jobsInProgress.get(jobId);
93
+ if (!job) {
94
+ this.log.warn(`Job id=${jobId} not found. Can't resolve`);
95
+ return Promise.resolve();
96
+ }
97
+ this.jobsInProgress.delete(jobId);
98
+ if (!job.signal?.aborted) {
99
+ job.resolve(result);
100
+ }
101
+ return Promise.resolve();
102
+ }
103
+ rejectProvingJob(jobId, reason) {
104
+ if (!this.runningPromise.isRunning()) {
105
+ throw new Error('Proving queue is not running.');
106
+ }
107
+ const job = this.jobsInProgress.get(jobId);
108
+ if (!job) {
109
+ this.log.warn(`Job id=${jobId} not found. Can't reject`);
110
+ return Promise.resolve();
111
+ }
112
+ this.jobsInProgress.delete(jobId);
113
+ if (job.signal?.aborted) {
114
+ return Promise.resolve();
115
+ }
116
+ // every job should be retried with the exception of the public VM since its in development and can fail
117
+ if (job.attempts < MAX_RETRIES && job.type !== ProvingRequestType.PUBLIC_VM) {
118
+ job.attempts++;
119
+ this.log.warn(`Job id=${job.id} type=${ProvingRequestType[job.type]} failed with error: ${reason}. Retry ${job.attempts}/${MAX_RETRIES}`);
120
+ this.queue.put(job);
121
+ } else {
122
+ const logFn = job.type === ProvingRequestType.PUBLIC_VM && !process.env.AVM_PROVING_STRICT ? this.log.warn : this.log.error;
123
+ logFn(`Job id=${job.id} type=${ProvingRequestType[job.type]} failed with error: ${reason}`);
124
+ job.reject(new Error(reason));
125
+ }
126
+ return Promise.resolve();
127
+ }
128
+ heartbeat(jobId) {
129
+ if (!this.runningPromise.isRunning()) {
130
+ throw new Error('Proving queue is not running.');
131
+ }
132
+ const job = this.jobsInProgress.get(jobId);
133
+ if (job) {
134
+ job.heartbeat = this.timeSource();
135
+ }
136
+ return Promise.resolve();
137
+ }
138
+ isJobRunning(jobId) {
139
+ return this.jobsInProgress.has(jobId);
140
+ }
141
+ poll() {
142
+ const now = this.timeSource();
143
+ this.metrics.recordQueueSize(this.queue.length());
144
+ for (const job of this.jobsInProgress.values()){
145
+ if (job.signal?.aborted) {
146
+ this.jobsInProgress.delete(job.id);
147
+ continue;
148
+ }
149
+ if (job.heartbeat + this.jobTimeoutMs < now) {
150
+ this.log.warn(`Job ${job.id} type=${ProvingRequestType[job.type]} has timed out`);
151
+ this.jobsInProgress.delete(job.id);
152
+ job.heartbeat = 0;
153
+ this.queue.put(job);
154
+ }
155
+ }
156
+ }
157
+ async enqueue(type, inputs, signal, epochNumber) {
158
+ if (!this.runningPromise.isRunning()) {
159
+ return Promise.reject(new Error('Proving queue is not running.'));
160
+ }
161
+ const { promise, resolve, reject } = promiseWithResolvers();
162
+ const id = this.generateId();
163
+ const inputsUri = await this.proofStore.saveProofInput(id, type, inputs);
164
+ const item = {
165
+ id,
166
+ type,
167
+ inputsUri,
168
+ signal,
169
+ promise,
170
+ resolve,
171
+ reject,
172
+ attempts: 1,
173
+ heartbeat: 0,
174
+ epochNumber: epochNumber ?? 0
175
+ };
176
+ if (signal) {
177
+ signal.addEventListener('abort', ()=>reject(new AbortError('Operation has been aborted')));
178
+ }
179
+ this.log.debug(`Adding id=${item.id} type=${ProvingRequestType[type]} proving job to queue depth=${this.queue.length()}`);
180
+ if (!this.queue.put(item)) {
181
+ throw new Error();
182
+ }
183
+ return promise.then(({ result })=>result);
184
+ }
185
+ getTubeProof(inputs, signal, epochNumber) {
186
+ return this.enqueue(ProvingRequestType.TUBE_PROOF, inputs, signal, epochNumber);
187
+ }
188
+ /**
189
+ * Creates a proof for the given input.
190
+ * @param input - Input to the circuit.
191
+ */ getBaseParityProof(inputs, signal, epochNumber) {
192
+ return this.enqueue(ProvingRequestType.BASE_PARITY, inputs, signal, epochNumber);
193
+ }
194
+ /**
195
+ * Creates a proof for the given input.
196
+ * @param input - Input to the circuit.
197
+ */ getRootParityProof(inputs, signal, epochNumber) {
198
+ return this.enqueue(ProvingRequestType.ROOT_PARITY, inputs, signal, epochNumber);
199
+ }
200
+ getPrivateBaseRollupProof(inputs, signal, epochNumber) {
201
+ return this.enqueue(ProvingRequestType.PRIVATE_BASE_ROLLUP, inputs, signal, epochNumber);
202
+ }
203
+ getPublicBaseRollupProof(inputs, signal, epochNumber) {
204
+ return this.enqueue(ProvingRequestType.PUBLIC_BASE_ROLLUP, inputs, signal, epochNumber);
205
+ }
206
+ /**
207
+ * Creates a proof for the given input.
208
+ * @param input - Input to the circuit.
209
+ */ getMergeRollupProof(inputs, signal, epochNumber) {
210
+ return this.enqueue(ProvingRequestType.MERGE_ROLLUP, inputs, signal, epochNumber);
211
+ }
212
+ /**
213
+ * Creates a proof for the given input.
214
+ * @param input - Input to the circuit.
215
+ */ getBlockRootRollupProof(inputs, signal, epochNumber) {
216
+ return this.enqueue(ProvingRequestType.BLOCK_ROOT_ROLLUP, inputs, signal, epochNumber);
217
+ }
218
+ getSingleTxBlockRootRollupProof(inputs, signal, epochNumber) {
219
+ return this.enqueue(ProvingRequestType.SINGLE_TX_BLOCK_ROOT_ROLLUP, inputs, signal, epochNumber);
220
+ }
221
+ getEmptyBlockRootRollupProof(inputs, signal, epochNumber) {
222
+ return this.enqueue(ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP, inputs, signal, epochNumber);
223
+ }
224
+ /**
225
+ * Creates a proof for the given input.
226
+ * @param input - Input to the circuit.
227
+ */ getBlockMergeRollupProof(inputs, signal, epochNumber) {
228
+ return this.enqueue(ProvingRequestType.BLOCK_MERGE_ROLLUP, inputs, signal, epochNumber);
229
+ }
230
+ /**
231
+ * Creates a proof for the given input.
232
+ * @param input - Input to the circuit.
233
+ */ getRootRollupProof(inputs, signal, epochNumber) {
234
+ return this.enqueue(ProvingRequestType.ROOT_ROLLUP, inputs, signal, epochNumber);
235
+ }
236
+ /**
237
+ * Creates an AVM proof.
238
+ */ getAvmProof(inputs, signal, epochNumber) {
239
+ return this.enqueue(ProvingRequestType.PUBLIC_VM, inputs, signal, epochNumber);
240
+ }
241
+ /**
242
+ * Verifies a circuit proof
243
+ */ verifyProof() {
244
+ return Promise.reject('not implemented');
245
+ }
246
+ }
247
+ _ts_decorate([
248
+ trackSpan('MemoryProvingQueue.poll')
249
+ ], MemoryProvingQueue.prototype, "poll", null);