@aztec/prover-client 0.0.0-test.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.
Files changed (154) hide show
  1. package/README.md +1 -0
  2. package/dest/bin/get-proof-inputs.d.ts +2 -0
  3. package/dest/bin/get-proof-inputs.d.ts.map +1 -0
  4. package/dest/bin/get-proof-inputs.js +51 -0
  5. package/dest/block_builder/index.d.ts +6 -0
  6. package/dest/block_builder/index.d.ts.map +1 -0
  7. package/dest/block_builder/index.js +1 -0
  8. package/dest/block_builder/light.d.ts +33 -0
  9. package/dest/block_builder/light.d.ts.map +1 -0
  10. package/dest/block_builder/light.js +82 -0
  11. package/dest/config.d.ts +17 -0
  12. package/dest/config.d.ts.map +1 -0
  13. package/dest/config.js +39 -0
  14. package/dest/index.d.ts +4 -0
  15. package/dest/index.d.ts.map +1 -0
  16. package/dest/index.js +2 -0
  17. package/dest/mocks/fixtures.d.ts +20 -0
  18. package/dest/mocks/fixtures.d.ts.map +1 -0
  19. package/dest/mocks/fixtures.js +77 -0
  20. package/dest/mocks/test_context.d.ts +55 -0
  21. package/dest/mocks/test_context.d.ts.map +1 -0
  22. package/dest/mocks/test_context.js +193 -0
  23. package/dest/orchestrator/block-building-helpers.d.ts +55 -0
  24. package/dest/orchestrator/block-building-helpers.d.ts.map +1 -0
  25. package/dest/orchestrator/block-building-helpers.js +285 -0
  26. package/dest/orchestrator/block-proving-state.d.ts +76 -0
  27. package/dest/orchestrator/block-proving-state.d.ts.map +1 -0
  28. package/dest/orchestrator/block-proving-state.js +269 -0
  29. package/dest/orchestrator/epoch-proving-state.d.ts +60 -0
  30. package/dest/orchestrator/epoch-proving-state.d.ts.map +1 -0
  31. package/dest/orchestrator/epoch-proving-state.js +163 -0
  32. package/dest/orchestrator/index.d.ts +2 -0
  33. package/dest/orchestrator/index.d.ts.map +1 -0
  34. package/dest/orchestrator/index.js +1 -0
  35. package/dest/orchestrator/orchestrator.d.ts +110 -0
  36. package/dest/orchestrator/orchestrator.d.ts.map +1 -0
  37. package/dest/orchestrator/orchestrator.js +690 -0
  38. package/dest/orchestrator/orchestrator_metrics.d.ts +8 -0
  39. package/dest/orchestrator/orchestrator_metrics.d.ts.map +1 -0
  40. package/dest/orchestrator/orchestrator_metrics.js +17 -0
  41. package/dest/orchestrator/tx-proving-state.d.ts +34 -0
  42. package/dest/orchestrator/tx-proving-state.d.ts.map +1 -0
  43. package/dest/orchestrator/tx-proving-state.js +94 -0
  44. package/dest/prover-client/factory.d.ts +6 -0
  45. package/dest/prover-client/factory.d.ts.map +1 -0
  46. package/dest/prover-client/factory.js +5 -0
  47. package/dest/prover-client/index.d.ts +3 -0
  48. package/dest/prover-client/index.d.ts.map +1 -0
  49. package/dest/prover-client/index.js +2 -0
  50. package/dest/prover-client/prover-client.d.ts +42 -0
  51. package/dest/prover-client/prover-client.d.ts.map +1 -0
  52. package/dest/prover-client/prover-client.js +110 -0
  53. package/dest/prover-client/server-epoch-prover.d.ts +28 -0
  54. package/dest/prover-client/server-epoch-prover.d.ts.map +1 -0
  55. package/dest/prover-client/server-epoch-prover.js +40 -0
  56. package/dest/proving_broker/broker_prover_facade.d.ts +46 -0
  57. package/dest/proving_broker/broker_prover_facade.d.ts.map +1 -0
  58. package/dest/proving_broker/broker_prover_facade.js +344 -0
  59. package/dest/proving_broker/config.d.ts +83 -0
  60. package/dest/proving_broker/config.d.ts.map +1 -0
  61. package/dest/proving_broker/config.js +104 -0
  62. package/dest/proving_broker/factory.d.ts +5 -0
  63. package/dest/proving_broker/factory.d.ts.map +1 -0
  64. package/dest/proving_broker/factory.js +9 -0
  65. package/dest/proving_broker/fixtures.d.ts +5 -0
  66. package/dest/proving_broker/fixtures.d.ts.map +1 -0
  67. package/dest/proving_broker/fixtures.js +12 -0
  68. package/dest/proving_broker/index.d.ts +10 -0
  69. package/dest/proving_broker/index.d.ts.map +1 -0
  70. package/dest/proving_broker/index.js +9 -0
  71. package/dest/proving_broker/proof_store/factory.d.ts +6 -0
  72. package/dest/proving_broker/proof_store/factory.d.ts.map +1 -0
  73. package/dest/proving_broker/proof_store/factory.js +36 -0
  74. package/dest/proving_broker/proof_store/gcs_proof_store.d.ts +14 -0
  75. package/dest/proving_broker/proof_store/gcs_proof_store.d.ts.map +1 -0
  76. package/dest/proving_broker/proof_store/gcs_proof_store.js +51 -0
  77. package/dest/proving_broker/proof_store/index.d.ts +4 -0
  78. package/dest/proving_broker/proof_store/index.d.ts.map +1 -0
  79. package/dest/proving_broker/proof_store/index.js +3 -0
  80. package/dest/proving_broker/proof_store/inline_proof_store.d.ts +15 -0
  81. package/dest/proving_broker/proof_store/inline_proof_store.d.ts.map +1 -0
  82. package/dest/proving_broker/proof_store/inline_proof_store.js +41 -0
  83. package/dest/proving_broker/proof_store/proof_store.d.ts +36 -0
  84. package/dest/proving_broker/proof_store/proof_store.d.ts.map +1 -0
  85. package/dest/proving_broker/proof_store/proof_store.js +3 -0
  86. package/dest/proving_broker/proving_agent.d.ts +46 -0
  87. package/dest/proving_broker/proving_agent.d.ts.map +1 -0
  88. package/dest/proving_broker/proving_agent.js +134 -0
  89. package/dest/proving_broker/proving_agent_instrumentation.d.ts +8 -0
  90. package/dest/proving_broker/proving_agent_instrumentation.d.ts.map +1 -0
  91. package/dest/proving_broker/proving_agent_instrumentation.js +16 -0
  92. package/dest/proving_broker/proving_broker.d.ts +64 -0
  93. package/dest/proving_broker/proving_broker.d.ts.map +1 -0
  94. package/dest/proving_broker/proving_broker.js +570 -0
  95. package/dest/proving_broker/proving_broker_database/memory.d.ts +16 -0
  96. package/dest/proving_broker/proving_broker_database/memory.d.ts.map +1 -0
  97. package/dest/proving_broker/proving_broker_database/memory.js +54 -0
  98. package/dest/proving_broker/proving_broker_database/persisted.d.ts +25 -0
  99. package/dest/proving_broker/proving_broker_database/persisted.d.ts.map +1 -0
  100. package/dest/proving_broker/proving_broker_database/persisted.js +182 -0
  101. package/dest/proving_broker/proving_broker_database.d.ts +39 -0
  102. package/dest/proving_broker/proving_broker_database.d.ts.map +1 -0
  103. package/dest/proving_broker/proving_broker_database.js +3 -0
  104. package/dest/proving_broker/proving_broker_instrumentation.d.ts +29 -0
  105. package/dest/proving_broker/proving_broker_instrumentation.d.ts.map +1 -0
  106. package/dest/proving_broker/proving_broker_instrumentation.js +110 -0
  107. package/dest/proving_broker/proving_job_controller.d.ts +33 -0
  108. package/dest/proving_broker/proving_job_controller.d.ts.map +1 -0
  109. package/dest/proving_broker/proving_job_controller.js +166 -0
  110. package/dest/proving_broker/rpc.d.ts +27 -0
  111. package/dest/proving_broker/rpc.d.ts.map +1 -0
  112. package/dest/proving_broker/rpc.js +66 -0
  113. package/dest/test/mock_prover.d.ts +35 -0
  114. package/dest/test/mock_prover.d.ts.map +1 -0
  115. package/dest/test/mock_prover.js +82 -0
  116. package/package.json +112 -0
  117. package/src/bin/get-proof-inputs.ts +59 -0
  118. package/src/block_builder/index.ts +6 -0
  119. package/src/block_builder/light.ts +101 -0
  120. package/src/config.ts +55 -0
  121. package/src/index.ts +4 -0
  122. package/src/mocks/fixtures.ts +117 -0
  123. package/src/mocks/test_context.ts +257 -0
  124. package/src/orchestrator/block-building-helpers.ts +553 -0
  125. package/src/orchestrator/block-proving-state.ts +379 -0
  126. package/src/orchestrator/epoch-proving-state.ts +252 -0
  127. package/src/orchestrator/index.ts +1 -0
  128. package/src/orchestrator/orchestrator.ts +971 -0
  129. package/src/orchestrator/orchestrator_metrics.ts +22 -0
  130. package/src/orchestrator/tx-proving-state.ts +139 -0
  131. package/src/prover-client/factory.ts +14 -0
  132. package/src/prover-client/index.ts +2 -0
  133. package/src/prover-client/prover-client.ts +162 -0
  134. package/src/prover-client/server-epoch-prover.ts +51 -0
  135. package/src/proving_broker/broker_prover_facade.ts +585 -0
  136. package/src/proving_broker/config.ts +138 -0
  137. package/src/proving_broker/factory.ts +18 -0
  138. package/src/proving_broker/fixtures.ts +15 -0
  139. package/src/proving_broker/index.ts +9 -0
  140. package/src/proving_broker/proof_store/factory.ts +42 -0
  141. package/src/proving_broker/proof_store/gcs_proof_store.ts +72 -0
  142. package/src/proving_broker/proof_store/index.ts +3 -0
  143. package/src/proving_broker/proof_store/inline_proof_store.ts +63 -0
  144. package/src/proving_broker/proof_store/proof_store.ts +54 -0
  145. package/src/proving_broker/proving_agent.ts +181 -0
  146. package/src/proving_broker/proving_agent_instrumentation.ts +21 -0
  147. package/src/proving_broker/proving_broker.ts +687 -0
  148. package/src/proving_broker/proving_broker_database/memory.ts +63 -0
  149. package/src/proving_broker/proving_broker_database/persisted.ts +218 -0
  150. package/src/proving_broker/proving_broker_database.ts +44 -0
  151. package/src/proving_broker/proving_broker_instrumentation.ts +145 -0
  152. package/src/proving_broker/proving_job_controller.ts +194 -0
  153. package/src/proving_broker/rpc.ts +95 -0
  154. package/src/test/mock_prover.ts +253 -0
@@ -0,0 +1,14 @@
1
+ import { type ProofUri, type ProvingJobId, type ProvingJobInputs, type ProvingJobInputsMap, type ProvingJobResult, type ProvingJobResultsMap } from '@aztec/stdlib/interfaces/server';
2
+ import { ProvingRequestType } from '@aztec/stdlib/proofs';
3
+ import type { ProofStore } from './proof_store.js';
4
+ export declare class GoogleCloudStorageProofStore implements ProofStore {
5
+ private readonly bucketName;
6
+ private readonly path;
7
+ private readonly storage;
8
+ constructor(bucketName: string, path: string);
9
+ saveProofInput<T extends ProvingRequestType>(id: ProvingJobId, type: T, inputs: ProvingJobInputsMap[T]): Promise<ProofUri>;
10
+ saveProofOutput<T extends ProvingRequestType>(_id: ProvingJobId, _type: T, _result: ProvingJobResultsMap[T]): Promise<ProofUri>;
11
+ getProofInput(uri: ProofUri): Promise<ProvingJobInputs>;
12
+ getProofOutput(_uri: ProofUri): Promise<ProvingJobResult>;
13
+ }
14
+ //# sourceMappingURL=gcs_proof_store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gcs_proof_store.d.ts","sourceRoot":"","sources":["../../../src/proving_broker/proof_store/gcs_proof_store.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAE1B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAK1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD,qBAAa,4BAA6B,YAAW,UAAU;IAGjD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAAU,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFtE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;gBAEL,UAAU,EAAE,MAAM,EAAmB,IAAI,EAAE,MAAM;IAIjE,cAAc,CAAC,CAAC,SAAS,kBAAkB,EACtD,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAC7B,OAAO,CAAC,QAAQ,CAAC;IAOpB,eAAe,CAAC,CAAC,SAAS,kBAAkB,EAC1C,GAAG,EAAE,YAAY,EACjB,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAC/B,OAAO,CAAC,QAAQ,CAAC;IAIP,aAAa,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAwBpE,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAG1D"}
@@ -0,0 +1,51 @@
1
+ import { getProvingJobInputClassFor } from '@aztec/stdlib/interfaces/server';
2
+ import { ProvingRequestType } from '@aztec/stdlib/proofs';
3
+ import { Storage } from '@google-cloud/storage';
4
+ import { join } from 'path';
5
+ const INPUTS_PATH = 'inputs';
6
+ export class GoogleCloudStorageProofStore {
7
+ bucketName;
8
+ path;
9
+ storage;
10
+ constructor(bucketName, path){
11
+ this.bucketName = bucketName;
12
+ this.path = path;
13
+ this.storage = new Storage();
14
+ }
15
+ async saveProofInput(id, type, inputs) {
16
+ const path = join(this.path, INPUTS_PATH, ProvingRequestType[type], id);
17
+ const file = this.storage.bucket(this.bucketName).file(path);
18
+ await file.save(inputs.toBuffer());
19
+ return file.cloudStorageURI.toString();
20
+ }
21
+ saveProofOutput(_id, _type, _result) {
22
+ throw new Error('Not implemented');
23
+ }
24
+ async getProofInput(uri) {
25
+ try {
26
+ const url = new URL(uri);
27
+ const bucket = this.storage.bucket(url.host);
28
+ const path = url.pathname.replace(/^\/+/, '');
29
+ const file = bucket.file(path);
30
+ if (!await file.exists()) {
31
+ throw new Error(`File at ${uri} does not exist`);
32
+ }
33
+ const typeString = path.split('/').at(-2);
34
+ const type = typeString ? ProvingRequestType[typeString] : undefined;
35
+ if (type === undefined) {
36
+ throw new Error(`Unrecognized proof type ${type} in path ${path}`);
37
+ }
38
+ const contents = await file.download();
39
+ const inputs = getProvingJobInputClassFor(type).fromBuffer(contents[0]);
40
+ return {
41
+ inputs,
42
+ type
43
+ };
44
+ } catch (err) {
45
+ throw new Error(`Error getting proof input at ${uri}: ${err}`);
46
+ }
47
+ }
48
+ getProofOutput(_uri) {
49
+ throw new Error('Not implemented');
50
+ }
51
+ }
@@ -0,0 +1,4 @@
1
+ export * from './proof_store.js';
2
+ export * from './inline_proof_store.js';
3
+ export * from './factory.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/proving_broker/proof_store/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,yBAAyB,CAAC;AACxC,cAAc,cAAc,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './proof_store.js';
2
+ export * from './inline_proof_store.js';
3
+ export * from './factory.js';
@@ -0,0 +1,15 @@
1
+ import { type ProofUri, type ProvingJobId, ProvingJobInputs, type ProvingJobInputsMap, ProvingJobResult, type ProvingJobResultsMap } from '@aztec/stdlib/interfaces/server';
2
+ import type { ProvingRequestType } from '@aztec/stdlib/proofs';
3
+ import type { ProofStore } from './proof_store.js';
4
+ /**
5
+ * An implementation of a proof input/output database that stores data inline in the URI.
6
+ */
7
+ export declare class InlineProofStore implements ProofStore {
8
+ saveProofInput<T extends ProvingRequestType>(_id: ProvingJobId, type: T, inputs: ProvingJobInputsMap[T]): Promise<ProofUri>;
9
+ saveProofOutput<T extends ProvingRequestType>(_id: ProvingJobId, type: T, result: ProvingJobResultsMap[T]): Promise<ProofUri>;
10
+ getProofInput(uri: ProofUri): Promise<ProvingJobInputs>;
11
+ getProofOutput(uri: ProofUri): Promise<ProvingJobResult>;
12
+ private encode;
13
+ private decode;
14
+ }
15
+ //# sourceMappingURL=inline_proof_store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline_proof_store.d.ts","sourceRoot":"","sources":["../../../src/proving_broker/proof_store/inline_proof_store.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,gBAAgB,EAChB,KAAK,mBAAmB,EACxB,gBAAgB,EAChB,KAAK,oBAAoB,EAC1B,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAOnD;;GAEG;AACH,qBAAa,gBAAiB,YAAW,UAAU;IACjD,cAAc,CAAC,CAAC,SAAS,kBAAkB,EACzC,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAC7B,OAAO,CAAC,QAAQ,CAAC;IAKpB,eAAe,CAAC,CAAC,SAAS,kBAAkB,EAC1C,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAC9B,OAAO,CAAC,QAAQ,CAAC;IAKpB,aAAa,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIvD,cAAc,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIxD,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,MAAM;CAQf"}
@@ -0,0 +1,41 @@
1
+ import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
2
+ import { ProvingJobInputs, ProvingJobResult } from '@aztec/stdlib/interfaces/server';
3
+ // use an ASCII encoded data uri https://datatracker.ietf.org/doc/html/rfc2397#section-2
4
+ // we do this to avoid double encoding to base64 (since the inputs already serialize to a base64 string)
5
+ const PREFIX = 'data:application/json;charset=utf-8';
6
+ const SEPARATOR = ',';
7
+ /**
8
+ * An implementation of a proof input/output database that stores data inline in the URI.
9
+ */ export class InlineProofStore {
10
+ saveProofInput(_id, type, inputs) {
11
+ const jobInputs = {
12
+ type,
13
+ inputs
14
+ };
15
+ return Promise.resolve(this.encode(jobInputs));
16
+ }
17
+ saveProofOutput(_id, type, result) {
18
+ const jobResult = {
19
+ type,
20
+ result
21
+ };
22
+ return Promise.resolve(this.encode(jobResult));
23
+ }
24
+ getProofInput(uri) {
25
+ return Promise.resolve(this.decode(uri, ProvingJobInputs));
26
+ }
27
+ getProofOutput(uri) {
28
+ return Promise.resolve(this.decode(uri, ProvingJobResult));
29
+ }
30
+ encode(obj) {
31
+ const encoded = encodeURIComponent(jsonStringify(obj));
32
+ return PREFIX + SEPARATOR + encoded;
33
+ }
34
+ decode(uri, schema) {
35
+ const [prefix, data] = uri.split(SEPARATOR);
36
+ if (prefix !== PREFIX) {
37
+ throw new Error('Invalid proof input URI: ' + prefix);
38
+ }
39
+ return jsonParseWithSchema(decodeURIComponent(data), schema);
40
+ }
41
+ }
@@ -0,0 +1,36 @@
1
+ import type { ProofUri, ProvingJobId, ProvingJobInputs, ProvingJobInputsMap, ProvingJobResult, ProvingJobResultsMap } from '@aztec/stdlib/interfaces/server';
2
+ import type { ProvingRequestType } from '@aztec/stdlib/proofs';
3
+ /**
4
+ * A database for storing proof inputs and outputs.
5
+ */
6
+ export interface ProofStore {
7
+ /**
8
+ * Save a proof input to the database.
9
+ * @param jobId - The ID of the job the proof input is associated with.
10
+ * @param type - The type of the proving request.
11
+ * @param inputs - The proof input to save.
12
+ * @returns The URI of the saved proof input.
13
+ */
14
+ saveProofInput<T extends ProvingRequestType>(jobId: ProvingJobId, type: T, inputs: ProvingJobInputsMap[T]): Promise<ProofUri>;
15
+ /**
16
+ * Save a proof output to the database.
17
+ * @param jobId - The ID of the job the proof input is associated with.
18
+ * @param type - The type of the proving request.
19
+ * @param result - The proof output to save.
20
+ * @returns The URI of the saved proof output.
21
+ */
22
+ saveProofOutput<T extends ProvingRequestType>(id: ProvingJobId, type: T, result: ProvingJobResultsMap[T]): Promise<ProofUri>;
23
+ /**
24
+ * Retrieve a proof input from the database.
25
+ * @param uri - The URI of the proof input to retrieve.
26
+ * @returns The proof input.
27
+ */
28
+ getProofInput(uri: ProofUri): Promise<ProvingJobInputs>;
29
+ /**
30
+ * Retrieve a proof output from the database.
31
+ * @param uri - The URI of the proof output to retrieve.
32
+ * @returns The proof output.
33
+ */
34
+ getProofOutput(uri: ProofUri): Promise<ProvingJobResult>;
35
+ }
36
+ //# sourceMappingURL=proof_store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proof_store.d.ts","sourceRoot":"","sources":["../../../src/proving_broker/proof_store/proof_store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;;;;;OAMG;IACH,cAAc,CAAC,CAAC,SAAS,kBAAkB,EACzC,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAC7B,OAAO,CAAC,QAAQ,CAAC,CAAC;IAErB;;;;;;OAMG;IACH,eAAe,CAAC,CAAC,SAAS,kBAAkB,EAC1C,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAC9B,OAAO,CAAC,QAAQ,CAAC,CAAC;IAErB;;;;OAIG;IACH,aAAa,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAExD;;;;OAIG;IACH,cAAc,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC1D"}
@@ -0,0 +1,3 @@
1
+ /**
2
+ * A database for storing proof inputs and outputs.
3
+ */ export { };
@@ -0,0 +1,46 @@
1
+ import type { ProvingJobConsumer, ProvingJobId, ProvingJobResultsMap, ServerCircuitProver } from '@aztec/stdlib/interfaces/server';
2
+ import { ProvingRequestType } from '@aztec/stdlib/proofs';
3
+ import { type TelemetryClient, type Traceable, type Tracer } from '@aztec/telemetry-client';
4
+ import type { ProofStore } from './proof_store/index.js';
5
+ /**
6
+ * A helper class that encapsulates a circuit prover and connects it to a job source.
7
+ */
8
+ export declare class ProvingAgent implements Traceable {
9
+ /** The source of proving jobs */
10
+ private broker;
11
+ /** Database holding proof inputs and outputs */
12
+ private proofStore;
13
+ /** The prover implementation to defer jobs to */
14
+ private circuitProver;
15
+ /** Optional list of allowed proof types to build */
16
+ private proofAllowList;
17
+ /** How long to wait between jobs */
18
+ private pollIntervalMs;
19
+ private log;
20
+ private currentJobController?;
21
+ private runningPromise;
22
+ private instrumentation;
23
+ private idleTimer;
24
+ readonly tracer: Tracer;
25
+ constructor(
26
+ /** The source of proving jobs */
27
+ broker: ProvingJobConsumer,
28
+ /** Database holding proof inputs and outputs */
29
+ proofStore: ProofStore,
30
+ /** The prover implementation to defer jobs to */
31
+ circuitProver: ServerCircuitProver,
32
+ /** Optional list of allowed proof types to build */
33
+ proofAllowList?: Array<ProvingRequestType>,
34
+ /** How long to wait between jobs */
35
+ pollIntervalMs?: number,
36
+ /** A telemetry client through which to emit metrics */
37
+ client?: TelemetryClient, log?: import("@aztec/foundation/log").Logger);
38
+ setCircuitProver(circuitProver: ServerCircuitProver): void;
39
+ isRunning(): boolean;
40
+ start(): void;
41
+ stop(): Promise<void>;
42
+ private work;
43
+ private startJob;
44
+ handleJobResult: <T extends ProvingRequestType>(jobId: ProvingJobId, type: T, err: Error | undefined, result: ProvingJobResultsMap[T] | undefined) => Promise<void>;
45
+ }
46
+ //# sourceMappingURL=proving_agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proving_agent.d.ts","sourceRoot":"","sources":["../../src/proving_broker/proving_agent.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAEV,kBAAkB,EAClB,YAAY,EAEZ,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,MAAM,EAGZ,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAIzD;;GAEG;AACH,qBAAa,YAAa,YAAW,SAAS;IAS1C,iCAAiC;IACjC,OAAO,CAAC,MAAM;IACd,gDAAgD;IAChD,OAAO,CAAC,UAAU;IAClB,iDAAiD;IACjD,OAAO,CAAC,aAAa;IACrB,oDAAoD;IACpD,OAAO,CAAC,cAAc;IACtB,oCAAoC;IACpC,OAAO,CAAC,cAAc;IAGtB,OAAO,CAAC,GAAG;IApBb,OAAO,CAAC,oBAAoB,CAAC,CAAuB;IACpD,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,SAAS,CAAoB;IAErC,SAAgB,MAAM,EAAE,MAAM,CAAC;;IAG7B,iCAAiC;IACzB,MAAM,EAAE,kBAAkB;IAClC,gDAAgD;IACxC,UAAU,EAAE,UAAU;IAC9B,iDAAiD;IACzC,aAAa,EAAE,mBAAmB;IAC1C,oDAAoD;IAC5C,cAAc,GAAE,KAAK,CAAC,kBAAkB,CAAM;IACtD,oCAAoC;IAC5B,cAAc,SAAO;IAC7B,uDAAuD;IACvD,MAAM,GAAE,eAAsC,EACtC,GAAG,yCAA8C;IAOpD,gBAAgB,CAAC,aAAa,EAAE,mBAAmB,GAAG,IAAI;IAI1D,SAAS,IAAI,OAAO;IAIpB,KAAK,IAAI,IAAI;IAKP,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAMpB,IAAI;YA6BJ,QAAQ;IAmDtB,eAAe,wCACN,YAAY,QACb,CAAC,OACF,KAAK,GAAG,SAAS,UACd,oBAAoB,CAAC,CAAC,CAAC,GAAG,SAAS,mBAmB3C;CACH"}
@@ -0,0 +1,134 @@
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 { createLogger } from '@aztec/foundation/log';
8
+ import { RunningPromise } from '@aztec/foundation/running-promise';
9
+ import { truncate } from '@aztec/foundation/string';
10
+ import { Timer } from '@aztec/foundation/timer';
11
+ import { ProvingError } from '@aztec/stdlib/errors';
12
+ import { ProvingRequestType } from '@aztec/stdlib/proofs';
13
+ import { getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
14
+ import { ProvingAgentInstrumentation } from './proving_agent_instrumentation.js';
15
+ import { ProvingJobController, ProvingJobControllerStatus } from './proving_job_controller.js';
16
+ /**
17
+ * A helper class that encapsulates a circuit prover and connects it to a job source.
18
+ */ export class ProvingAgent {
19
+ broker;
20
+ proofStore;
21
+ circuitProver;
22
+ proofAllowList;
23
+ pollIntervalMs;
24
+ log;
25
+ currentJobController;
26
+ runningPromise;
27
+ instrumentation;
28
+ idleTimer;
29
+ tracer;
30
+ constructor(/** The source of proving jobs */ broker, /** Database holding proof inputs and outputs */ proofStore, /** The prover implementation to defer jobs to */ circuitProver, /** Optional list of allowed proof types to build */ proofAllowList = [], /** How long to wait between jobs */ pollIntervalMs = 1000, /** A telemetry client through which to emit metrics */ client = getTelemetryClient(), log = createLogger('prover-client:proving-agent')){
31
+ this.broker = broker;
32
+ this.proofStore = proofStore;
33
+ this.circuitProver = circuitProver;
34
+ this.proofAllowList = proofAllowList;
35
+ this.pollIntervalMs = pollIntervalMs;
36
+ this.log = log;
37
+ this.handleJobResult = async (jobId, type, err, result)=>{
38
+ let maybeJob;
39
+ if (err) {
40
+ const retry = err.name === ProvingError.NAME ? err.retry : false;
41
+ this.log.error(`Job id=${jobId} type=${ProvingRequestType[type]} failed err=${err.message} retry=${retry}`, err);
42
+ maybeJob = await this.broker.reportProvingJobError(jobId, err.message, retry, {
43
+ allowList: this.proofAllowList
44
+ });
45
+ } else if (result) {
46
+ const outputUri = await this.proofStore.saveProofOutput(jobId, type, result);
47
+ this.log.info(`Job id=${jobId} type=${ProvingRequestType[type]} completed outputUri=${truncate(outputUri)}`);
48
+ maybeJob = await this.broker.reportProvingJobSuccess(jobId, outputUri, {
49
+ allowList: this.proofAllowList
50
+ });
51
+ }
52
+ if (maybeJob) {
53
+ const { job, time } = maybeJob;
54
+ await this.startJob(job, time);
55
+ } else {
56
+ this.idleTimer = new Timer();
57
+ }
58
+ };
59
+ this.tracer = client.getTracer('ProvingAgent');
60
+ this.instrumentation = new ProvingAgentInstrumentation(client);
61
+ this.runningPromise = new RunningPromise(this.work.bind(this), this.log, this.pollIntervalMs);
62
+ }
63
+ setCircuitProver(circuitProver) {
64
+ this.circuitProver = circuitProver;
65
+ }
66
+ isRunning() {
67
+ return this.runningPromise?.isRunning() ?? false;
68
+ }
69
+ start() {
70
+ this.idleTimer = new Timer();
71
+ this.runningPromise.start();
72
+ }
73
+ async stop() {
74
+ this.currentJobController?.abort();
75
+ await this.runningPromise.stop();
76
+ }
77
+ async work() {
78
+ // every tick we need to
79
+ // (1) either do a heartbeat, telling the broker that we're working
80
+ // (2) get a new job
81
+ // If during (1) the broker returns a new job that means we can cancel the current job and start the new one
82
+ let maybeJob;
83
+ if (this.currentJobController?.getStatus() === ProvingJobControllerStatus.PROVING) {
84
+ maybeJob = await this.broker.reportProvingJobProgress(this.currentJobController.getJobId(), this.currentJobController.getStartedAt(), {
85
+ allowList: this.proofAllowList
86
+ });
87
+ } else {
88
+ maybeJob = await this.broker.getProvingJob({
89
+ allowList: this.proofAllowList
90
+ });
91
+ }
92
+ if (!maybeJob) {
93
+ return;
94
+ }
95
+ if (this.idleTimer) {
96
+ this.instrumentation.recordIdleTime(this.idleTimer);
97
+ }
98
+ this.idleTimer = undefined;
99
+ const { job, time } = maybeJob;
100
+ await this.startJob(job, time);
101
+ }
102
+ async startJob(job, startedAt) {
103
+ let abortedProofJobId;
104
+ let abortedProofName;
105
+ if (this.currentJobController?.getStatus() === ProvingJobControllerStatus.PROVING) {
106
+ abortedProofJobId = this.currentJobController.getJobId();
107
+ abortedProofName = this.currentJobController.getProofTypeName();
108
+ this.currentJobController?.abort();
109
+ }
110
+ let inputs;
111
+ try {
112
+ inputs = await this.proofStore.getProofInput(job.inputsUri);
113
+ } catch (err) {
114
+ const maybeJob = await this.broker.reportProvingJobError(job.id, 'Failed to load proof inputs', true, {
115
+ allowList: this.proofAllowList
116
+ });
117
+ if (maybeJob) {
118
+ return this.startJob(maybeJob.job, maybeJob.time);
119
+ }
120
+ return;
121
+ }
122
+ this.currentJobController = new ProvingJobController(job.id, inputs, job.epochNumber, startedAt, this.circuitProver, this.handleJobResult);
123
+ if (abortedProofJobId) {
124
+ this.log.info(`Aborting job id=${abortedProofJobId} type=${abortedProofName} to start new job id=${this.currentJobController.getJobId()} type=${this.currentJobController.getProofTypeName()} inputsUri=${truncate(job.inputsUri)}`);
125
+ } else {
126
+ this.log.info(`Starting job id=${this.currentJobController.getJobId()} type=${this.currentJobController.getProofTypeName()} inputsUri=${truncate(job.inputsUri)}`);
127
+ }
128
+ this.currentJobController.start();
129
+ }
130
+ handleJobResult;
131
+ }
132
+ _ts_decorate([
133
+ trackSpan('ProvingAgent.safeWork')
134
+ ], ProvingAgent.prototype, "work", null);
@@ -0,0 +1,8 @@
1
+ import type { Timer } from '@aztec/foundation/timer';
2
+ import { type TelemetryClient } from '@aztec/telemetry-client';
3
+ export declare class ProvingAgentInstrumentation {
4
+ private idleTime;
5
+ constructor(client: TelemetryClient, name?: string);
6
+ recordIdleTime(msOrTimer: Timer | number): void;
7
+ }
8
+ //# sourceMappingURL=proving_agent_instrumentation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proving_agent_instrumentation.d.ts","sourceRoot":"","sources":["../../src/proving_broker/proving_agent_instrumentation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAA2B,KAAK,eAAe,EAAa,MAAM,yBAAyB,CAAC;AAEnG,qBAAa,2BAA2B;IACtC,OAAO,CAAC,QAAQ,CAAY;gBAEhB,MAAM,EAAE,eAAe,EAAE,IAAI,SAAiB;IAU1D,cAAc,CAAC,SAAS,EAAE,KAAK,GAAG,MAAM;CAIzC"}
@@ -0,0 +1,16 @@
1
+ import { Metrics, ValueType } from '@aztec/telemetry-client';
2
+ export class ProvingAgentInstrumentation {
3
+ idleTime;
4
+ constructor(client, name = 'ProvingAgent'){
5
+ const meter = client.getMeter(name);
6
+ this.idleTime = meter.createHistogram(Metrics.PROVING_AGENT_IDLE, {
7
+ description: 'Records how long an agent was idle',
8
+ unit: 's',
9
+ valueType: ValueType.DOUBLE
10
+ });
11
+ }
12
+ recordIdleTime(msOrTimer) {
13
+ const duration = typeof msOrTimer === 'number' ? msOrTimer : msOrTimer.ms();
14
+ this.idleTime.record(duration / 1000);
15
+ }
16
+ }
@@ -0,0 +1,64 @@
1
+ import type { GetProvingJobResponse, ProofUri, ProvingJob, ProvingJobConsumer, ProvingJobFilter, ProvingJobId, ProvingJobProducer, ProvingJobStatus } from '@aztec/stdlib/interfaces/server';
2
+ import { type TelemetryClient, type Traceable, type Tracer } from '@aztec/telemetry-client';
3
+ import { type ProverBrokerConfig } from './config.js';
4
+ import type { ProvingBrokerDatabase } from './proving_broker_database.js';
5
+ /**
6
+ * A broker that manages proof requests and distributes them to workers based on their priority.
7
+ * It takes a backend that is responsible for storing and retrieving proof requests and results.
8
+ */
9
+ export declare class ProvingBroker implements ProvingJobProducer, ProvingJobConsumer, Traceable {
10
+ #private;
11
+ private database;
12
+ private logger;
13
+ private queues;
14
+ private jobsCache;
15
+ private resultsCache;
16
+ private enqueuedAt;
17
+ private inProgress;
18
+ private retries;
19
+ private promises;
20
+ private cleanupPromise;
21
+ private msTimeSource;
22
+ private jobTimeoutMs;
23
+ private maxRetries;
24
+ private instrumentation;
25
+ readonly tracer: Tracer;
26
+ private completedJobNotifications;
27
+ /**
28
+ * The broker keeps track of the highest epoch its seen.
29
+ * This information is used for garbage collection: once it reaches the next epoch, it can start pruning the database of old state.
30
+ * It is important that this value is initialised to zero. This ensures that we don't delete any old jobs until the current
31
+ * process instance receives a job request informing it of the actual current highest epoch
32
+ * Example:
33
+ * proving epoch 11 - the broker will wipe all jobs for epochs 9 and lower
34
+ * finished proving epoch 11 and got first job for epoch 12 -> the broker will wipe all settled jobs for epochs 10 and lower
35
+ * reorged back to end of epoch 10 -> epoch 11 is skipped and epoch 12 starts -> the broker will wipe all settled jobs for epochs 10 and lower
36
+ */
37
+ private epochHeight;
38
+ private maxEpochsToKeepResultsFor;
39
+ private started;
40
+ constructor(database: ProvingBrokerDatabase, { proverBrokerJobTimeoutMs, proverBrokerPollIntervalMs, proverBrokerJobMaxRetries, proverBrokerMaxEpochsToKeepResultsFor, }?: Required<Pick<ProverBrokerConfig, 'proverBrokerJobTimeoutMs' | 'proverBrokerPollIntervalMs' | 'proverBrokerJobMaxRetries' | 'proverBrokerMaxEpochsToKeepResultsFor'>>, client?: TelemetryClient, logger?: import("@aztec/foundation/log").Logger);
41
+ private measureQueueDepth;
42
+ private countActiveJobs;
43
+ start(): Promise<void>;
44
+ stop(): Promise<void>;
45
+ enqueueProvingJob(job: ProvingJob): Promise<ProvingJobStatus>;
46
+ cancelProvingJob(id: ProvingJobId): Promise<void>;
47
+ getProvingJobStatus(id: ProvingJobId): Promise<ProvingJobStatus>;
48
+ getCompletedJobs(ids: ProvingJobId[]): Promise<ProvingJobId[]>;
49
+ getProvingJob(filter?: ProvingJobFilter): Promise<GetProvingJobResponse | undefined>;
50
+ reportProvingJobSuccess(id: ProvingJobId, value: ProofUri, filter?: ProvingJobFilter): Promise<GetProvingJobResponse | undefined>;
51
+ reportProvingJobError(id: ProvingJobId, err: string, retry?: boolean, filter?: ProvingJobFilter): Promise<GetProvingJobResponse | undefined>;
52
+ reportProvingJobProgress(id: ProvingJobId, startedAt: number, filter?: ProvingJobFilter): Promise<{
53
+ job: ProvingJob;
54
+ time: number;
55
+ } | undefined>;
56
+ private cleanUpProvingJobState;
57
+ private cleanupPass;
58
+ private cleanupStaleJobs;
59
+ private reEnqueueExpiredJobs;
60
+ private enqueueJobInternal;
61
+ private isJobStale;
62
+ private oldestEpochToKeep;
63
+ }
64
+ //# sourceMappingURL=proving_broker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proving_broker.d.ts","sourceRoot":"","sources":["../../src/proving_broker/proving_broker.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,qBAAqB,EACrB,QAAQ,EACR,UAAU,EACV,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAElB,gBAAgB,EACjB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,MAAM,EAGZ,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EAAE,KAAK,kBAAkB,EAA6B,MAAM,aAAa,CAAC;AACjF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAW1E;;;GAGG;AACH,qBAAa,aAAc,YAAW,kBAAkB,EAAE,kBAAkB,EAAE,SAAS;;IAkEnF,OAAO,CAAC,QAAQ;IAgBhB,OAAO,CAAC,MAAM;IAjFhB,OAAO,CAAC,MAAM,CAgBZ;IAIF,OAAO,CAAC,SAAS,CAAuC;IAExD,OAAO,CAAC,YAAY,CAAoD;IAGxE,OAAO,CAAC,UAAU,CAAkC;IAMpD,OAAO,CAAC,UAAU,CAA+C;IAGjE,OAAO,CAAC,OAAO,CAAmC;IAGlD,OAAO,CAAC,QAAQ,CAA0E;IAE1F,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO,CAAC,eAAe,CAA+B;IACtD,SAAgB,MAAM,EAAE,MAAM,CAAC;IAE/B,OAAO,CAAC,yBAAyB,CAAsB;IAEvD;;;;;;;;;OASG;IACH,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,yBAAyB,CAAK;IAEtC,OAAO,CAAC,OAAO,CAAS;gBAGd,QAAQ,EAAE,qBAAqB,EACvC,EACE,wBAAwB,EACxB,0BAA0B,EAC1B,yBAAyB,EACzB,qCAAqC,GACtC,GAAE,QAAQ,CACT,IAAI,CACF,kBAAkB,EAChB,0BAA0B,GAC1B,4BAA4B,GAC5B,2BAA2B,GAC3B,uCAAuC,CAC1C,CAC0B,EAC7B,MAAM,GAAE,eAAsC,EACtC,MAAM,yCAA+C;IAU/D,OAAO,CAAC,iBAAiB,CAEvB;IAEF,OAAO,CAAC,eAAe,CAUrB;IAEW,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA+BtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,iBAAiB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAI7D,gBAAgB,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjD,mBAAmB,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIhE,gBAAgB,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAI9D,aAAa,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAIpF,uBAAuB,CAC5B,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,QAAQ,EACf,MAAM,CAAC,EAAE,gBAAgB,GACxB,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAItC,qBAAqB,CAC1B,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,MAAM,EACX,KAAK,UAAQ,EACb,MAAM,CAAC,EAAE,gBAAgB,GACxB,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAItC,wBAAwB,CAC7B,EAAE,EAAE,YAAY,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,gBAAgB,GACxB,OAAO,CAAC;QAAE,GAAG,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IAoDzD,OAAO,CAAC,sBAAsB;YA6QhB,WAAW;IAUzB,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,oBAAoB;IAqB5B,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,iBAAiB;CAG1B"}