@aztec/stdlib 0.82.2 → 0.82.3-nightly.20250403

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 (206) hide show
  1. package/dest/avm/avm.d.ts +4648 -1474
  2. package/dest/avm/avm.d.ts.map +1 -1
  3. package/dest/avm/avm.js +182 -109
  4. package/dest/avm/avm_proving_request.d.ts +1867 -498
  5. package/dest/avm/avm_proving_request.d.ts.map +1 -1
  6. package/dest/block/l2_block_downloader/l2_block_stream.d.ts +10 -12
  7. package/dest/block/l2_block_downloader/l2_block_stream.d.ts.map +1 -1
  8. package/dest/block/l2_block_downloader/l2_block_stream.js +45 -11
  9. package/dest/config/config.d.ts +2 -2
  10. package/dest/config/config.d.ts.map +1 -1
  11. package/dest/config/config.js +4 -5
  12. package/dest/contract/interfaces/node-info.d.ts +2 -2
  13. package/dest/contract/interfaces/node-info.d.ts.map +1 -1
  14. package/dest/contract/interfaces/node-info.js +1 -1
  15. package/dest/database-version/version_manager.d.ts +4 -2
  16. package/dest/database-version/version_manager.d.ts.map +1 -1
  17. package/dest/database-version/version_manager.js +13 -9
  18. package/dest/epoch-helpers/index.d.ts +2 -0
  19. package/dest/epoch-helpers/index.d.ts.map +1 -1
  20. package/dest/epoch-helpers/index.js +3 -0
  21. package/dest/file-store/factory.d.ts +7 -0
  22. package/dest/file-store/factory.d.ts.map +1 -0
  23. package/dest/file-store/factory.js +46 -0
  24. package/dest/file-store/gcs.d.ts +22 -0
  25. package/dest/file-store/gcs.d.ts.map +1 -0
  26. package/dest/file-store/gcs.js +115 -0
  27. package/dest/file-store/http.d.ts +15 -0
  28. package/dest/file-store/http.d.ts.map +1 -0
  29. package/dest/file-store/http.js +53 -0
  30. package/dest/file-store/index.d.ts +3 -0
  31. package/dest/file-store/index.d.ts.map +1 -0
  32. package/dest/file-store/index.js +2 -0
  33. package/dest/file-store/interface.d.ts +24 -0
  34. package/dest/file-store/interface.d.ts.map +1 -0
  35. package/dest/file-store/interface.js +1 -0
  36. package/dest/file-store/local.d.ts +16 -0
  37. package/dest/file-store/local.d.ts.map +1 -0
  38. package/dest/file-store/local.js +40 -0
  39. package/dest/interfaces/aztec-node-admin.d.ts +9 -1
  40. package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
  41. package/dest/interfaces/aztec-node-admin.js +2 -1
  42. package/dest/interfaces/aztec-node.d.ts +3 -0
  43. package/dest/interfaces/aztec-node.d.ts.map +1 -1
  44. package/dest/interfaces/aztec-node.js +2 -0
  45. package/dest/interfaces/p2p.d.ts +2 -0
  46. package/dest/interfaces/p2p.d.ts.map +1 -1
  47. package/dest/interfaces/p2p.js +2 -1
  48. package/dest/interfaces/prover-client.d.ts +3 -3
  49. package/dest/interfaces/prover-client.d.ts.map +1 -1
  50. package/dest/interfaces/prover-client.js +6 -4
  51. package/dest/interfaces/prover-node.d.ts +4 -0
  52. package/dest/interfaces/prover-node.d.ts.map +1 -1
  53. package/dest/interfaces/prover-node.js +5 -1
  54. package/dest/interfaces/proving-job.d.ts +1866 -497
  55. package/dest/interfaces/proving-job.d.ts.map +1 -1
  56. package/dest/interfaces/pxe.d.ts +7 -6
  57. package/dest/interfaces/pxe.d.ts.map +1 -1
  58. package/dest/interfaces/pxe.js +1 -1
  59. package/dest/interfaces/service.d.ts +3 -0
  60. package/dest/interfaces/service.d.ts.map +1 -1
  61. package/dest/interfaces/service.js +7 -0
  62. package/dest/interfaces/world_state.d.ts +13 -15
  63. package/dest/interfaces/world_state.d.ts.map +1 -1
  64. package/dest/keys/derivation.d.ts +1 -1
  65. package/dest/keys/derivation.d.ts.map +1 -1
  66. package/dest/keys/derivation.js +10 -2
  67. package/dest/logs/index.d.ts +2 -1
  68. package/dest/logs/index.d.ts.map +1 -1
  69. package/dest/logs/index.js +2 -1
  70. package/dest/logs/pending_tagged_log.d.ts +17 -0
  71. package/dest/logs/pending_tagged_log.d.ts.map +1 -0
  72. package/dest/logs/pending_tagged_log.js +45 -0
  73. package/dest/logs/{l1_payload/shared_secret_derivation.d.ts → shared_secret_derivation.d.ts} +4 -3
  74. package/dest/logs/shared_secret_derivation.d.ts.map +1 -0
  75. package/dest/logs/{l1_payload/shared_secret_derivation.js → shared_secret_derivation.js} +3 -5
  76. package/dest/logs/tx_scoped_l2_log.d.ts +6 -1
  77. package/dest/logs/tx_scoped_l2_log.d.ts.map +1 -1
  78. package/dest/logs/tx_scoped_l2_log.js +12 -4
  79. package/dest/note/note.d.ts +45 -4
  80. package/dest/note/note.d.ts.map +1 -1
  81. package/dest/note/note.js +51 -4
  82. package/dest/proofs/proof.d.ts.map +1 -1
  83. package/dest/proofs/proof.js +33 -7
  84. package/dest/snapshots/download.d.ts +9 -0
  85. package/dest/snapshots/download.d.ts.map +1 -0
  86. package/dest/snapshots/download.js +37 -0
  87. package/dest/snapshots/index.d.ts +4 -0
  88. package/dest/snapshots/index.d.ts.map +1 -0
  89. package/dest/snapshots/index.js +3 -0
  90. package/dest/snapshots/types.d.ts +97 -0
  91. package/dest/snapshots/types.d.ts.map +1 -0
  92. package/dest/snapshots/types.js +27 -0
  93. package/dest/snapshots/upload.d.ts +5 -0
  94. package/dest/snapshots/upload.d.ts.map +1 -0
  95. package/dest/snapshots/upload.js +37 -0
  96. package/dest/tests/factories.d.ts +21 -7
  97. package/dest/tests/factories.d.ts.map +1 -1
  98. package/dest/tests/factories.js +78 -30
  99. package/dest/tests/mocks.d.ts +2 -1
  100. package/dest/tests/mocks.d.ts.map +1 -1
  101. package/dest/tests/mocks.js +5 -1
  102. package/dest/trees/merkle_tree_id.d.ts +8 -0
  103. package/dest/trees/merkle_tree_id.d.ts.map +1 -1
  104. package/dest/trees/merkle_tree_id.js +10 -0
  105. package/dest/trees/nullifier_leaf.d.ts +49 -15
  106. package/dest/trees/nullifier_leaf.d.ts.map +1 -1
  107. package/dest/trees/nullifier_leaf.js +45 -22
  108. package/dest/trees/nullifier_membership_witness.d.ts +34 -18
  109. package/dest/trees/nullifier_membership_witness.d.ts.map +1 -1
  110. package/dest/trees/protocol_contract_leaf.d.ts +0 -1
  111. package/dest/trees/protocol_contract_leaf.d.ts.map +1 -1
  112. package/dest/trees/protocol_contract_leaf.js +0 -3
  113. package/dest/trees/public_data_leaf.d.ts +59 -25
  114. package/dest/trees/public_data_leaf.d.ts.map +1 -1
  115. package/dest/trees/public_data_leaf.js +41 -30
  116. package/dest/trees/public_data_witness.d.ts +42 -24
  117. package/dest/trees/public_data_witness.d.ts.map +1 -1
  118. package/dest/trees/public_data_witness.js +6 -6
  119. package/dest/validators/index.d.ts +3 -0
  120. package/dest/validators/index.d.ts.map +1 -0
  121. package/dest/validators/index.js +1 -0
  122. package/dest/validators/schemas.d.ts +342 -0
  123. package/dest/validators/schemas.d.ts.map +1 -0
  124. package/dest/validators/schemas.js +40 -0
  125. package/dest/validators/types.d.ts +39 -0
  126. package/dest/validators/types.d.ts.map +1 -0
  127. package/dest/validators/types.js +1 -0
  128. package/dest/versioning/versioning.d.ts +1 -1
  129. package/dest/versioning/versioning.d.ts.map +1 -1
  130. package/dest/versioning/versioning.js +6 -6
  131. package/package.json +11 -8
  132. package/src/avm/avm.ts +183 -104
  133. package/src/block/l2_block_downloader/l2_block_stream.ts +64 -29
  134. package/src/config/config.ts +6 -6
  135. package/src/contract/interfaces/node-info.ts +3 -3
  136. package/src/database-version/version_manager.ts +12 -8
  137. package/src/epoch-helpers/index.ts +8 -0
  138. package/src/file-store/factory.ts +61 -0
  139. package/src/file-store/gcs.ts +121 -0
  140. package/src/file-store/http.ts +58 -0
  141. package/src/file-store/index.ts +2 -0
  142. package/src/file-store/interface.ts +19 -0
  143. package/src/file-store/local.ts +46 -0
  144. package/src/interfaces/aztec-node-admin.ts +11 -1
  145. package/src/interfaces/aztec-node.ts +7 -0
  146. package/src/interfaces/p2p.ts +4 -0
  147. package/src/interfaces/prover-client.ts +9 -7
  148. package/src/interfaces/prover-node.ts +10 -0
  149. package/src/interfaces/pxe.ts +14 -7
  150. package/src/interfaces/service.ts +13 -0
  151. package/src/interfaces/world_state.ts +17 -15
  152. package/src/keys/derivation.ts +12 -6
  153. package/src/logs/index.ts +2 -1
  154. package/src/logs/pending_tagged_log.ts +43 -0
  155. package/src/logs/{l1_payload/shared_secret_derivation.ts → shared_secret_derivation.ts} +4 -11
  156. package/src/logs/tx_scoped_l2_log.ts +13 -4
  157. package/src/note/note.ts +61 -5
  158. package/src/proofs/proof.ts +39 -5
  159. package/src/snapshots/download.ts +60 -0
  160. package/src/snapshots/index.ts +3 -0
  161. package/src/snapshots/types.ts +58 -0
  162. package/src/snapshots/upload.ts +55 -0
  163. package/src/tests/factories.ts +137 -53
  164. package/src/tests/mocks.ts +7 -0
  165. package/src/trees/merkle_tree_id.ts +12 -0
  166. package/src/trees/nullifier_leaf.ts +48 -21
  167. package/src/trees/protocol_contract_leaf.ts +0 -4
  168. package/src/trees/public_data_leaf.ts +40 -29
  169. package/src/trees/public_data_witness.ts +6 -6
  170. package/src/validators/index.ts +3 -0
  171. package/src/validators/schemas.ts +53 -0
  172. package/src/validators/types.ts +37 -0
  173. package/src/versioning/versioning.ts +8 -14
  174. package/dest/event/event.d.ts +0 -24
  175. package/dest/event/event.d.ts.map +0 -1
  176. package/dest/event/event.js +0 -13
  177. package/dest/event/event_metadata.d.ts +0 -38
  178. package/dest/event/event_metadata.d.ts.map +0 -1
  179. package/dest/event/event_metadata.js +0 -45
  180. package/dest/event/index.d.ts +0 -4
  181. package/dest/event/index.d.ts.map +0 -1
  182. package/dest/event/index.js +0 -3
  183. package/dest/event/l1_event_payload.d.ts +0 -52
  184. package/dest/event/l1_event_payload.d.ts.map +0 -1
  185. package/dest/event/l1_event_payload.js +0 -64
  186. package/dest/logs/l1_payload/encrypted_log_payload.d.ts +0 -50
  187. package/dest/logs/l1_payload/encrypted_log_payload.d.ts.map +0 -1
  188. package/dest/logs/l1_payload/encrypted_log_payload.js +0 -140
  189. package/dest/logs/l1_payload/encryption_util.d.ts +0 -24
  190. package/dest/logs/l1_payload/encryption_util.d.ts.map +0 -1
  191. package/dest/logs/l1_payload/encryption_util.js +0 -46
  192. package/dest/logs/l1_payload/index.d.ts +0 -3
  193. package/dest/logs/l1_payload/index.d.ts.map +0 -1
  194. package/dest/logs/l1_payload/index.js +0 -2
  195. package/dest/logs/l1_payload/payload.d.ts +0 -60
  196. package/dest/logs/l1_payload/payload.d.ts.map +0 -1
  197. package/dest/logs/l1_payload/payload.js +0 -61
  198. package/dest/logs/l1_payload/shared_secret_derivation.d.ts.map +0 -1
  199. package/src/event/event.ts +0 -16
  200. package/src/event/event_metadata.ts +0 -56
  201. package/src/event/index.ts +0 -3
  202. package/src/event/l1_event_payload.ts +0 -87
  203. package/src/logs/l1_payload/encrypted_log_payload.ts +0 -202
  204. package/src/logs/l1_payload/encryption_util.ts +0 -54
  205. package/src/logs/l1_payload/index.ts +0 -2
  206. package/src/logs/l1_payload/payload.ts +0 -73
@@ -26,6 +26,14 @@ export const L1RollupConstantsSchema = z.object({
26
26
  ethereumSlotDuration: z.number(),
27
27
  }) satisfies ZodFor<L1RollupConstants>;
28
28
 
29
+ /** Returns the timestamp for a given L2 slot. */
30
+ export function getTimestampForSlot(
31
+ slot: bigint,
32
+ constants: Pick<L1RollupConstants, 'l1GenesisTime' | 'slotDuration'>,
33
+ ) {
34
+ return constants.l1GenesisTime + slot * BigInt(constants.slotDuration);
35
+ }
36
+
29
37
  /** Returns the slot number for a given timestamp. */
30
38
  export function getSlotAtTimestamp(ts: bigint, constants: Pick<L1RollupConstants, 'l1GenesisTime' | 'slotDuration'>) {
31
39
  return ts < constants.l1GenesisTime ? 0n : (ts - constants.l1GenesisTime) / BigInt(constants.slotDuration);
@@ -0,0 +1,61 @@
1
+ import { type Logger, createLogger } from '@aztec/foundation/log';
2
+
3
+ import { GoogleCloudFileStore } from './gcs.js';
4
+ import { HttpFileStore } from './http.js';
5
+ import type { FileStore, ReadOnlyFileStore } from './interface.js';
6
+ import { LocalFileStore } from './local.js';
7
+
8
+ const supportedExamples = [
9
+ `gs://bucket-name/path/to/store`,
10
+ `file:///absolute/local/path/to/store`,
11
+ `https://host/path`,
12
+ ];
13
+
14
+ export async function createFileStore(config: string, logger?: Logger): Promise<FileStore>;
15
+ export async function createFileStore(config: undefined, logger?: Logger): Promise<undefined>;
16
+ export async function createFileStore(
17
+ config: string | undefined,
18
+ logger = createLogger('stdlib:file-store'),
19
+ ): Promise<FileStore | undefined> {
20
+ if (config === undefined) {
21
+ return undefined;
22
+ } else if (config.startsWith('file://')) {
23
+ const url = new URL(config);
24
+ if (url.host) {
25
+ throw new Error(`File store URL only supports local paths (got host ${url.host} from ${config})`);
26
+ }
27
+ const path = url.pathname;
28
+ logger.info(`Creating local file file store at ${path}`);
29
+ return new LocalFileStore(path);
30
+ } else if (config.startsWith('gs://')) {
31
+ try {
32
+ const url = new URL(config);
33
+ const bucket = url.host;
34
+ const path = url.pathname.replace(/^\/+/, '');
35
+ logger.info(`Creating google cloud file store at ${bucket} ${path}`);
36
+ const store = new GoogleCloudFileStore(bucket, path);
37
+ await store.checkCredentials();
38
+ return store;
39
+ } catch (err) {
40
+ throw new Error(`Invalid google cloud store definition: '${config}'.`);
41
+ }
42
+ } else {
43
+ throw new Error(`Unknown file store config: '${config}'. Supported values are ${supportedExamples.join(', ')}.`);
44
+ }
45
+ }
46
+
47
+ export async function createReadOnlyFileStore(config: string, logger?: Logger): Promise<ReadOnlyFileStore>;
48
+ export async function createReadOnlyFileStore(config: undefined, logger?: Logger): Promise<undefined>;
49
+ export async function createReadOnlyFileStore(
50
+ config: string | undefined,
51
+ logger = createLogger('stdlib:file-store'),
52
+ ): Promise<ReadOnlyFileStore | undefined> {
53
+ if (config === undefined) {
54
+ return undefined;
55
+ } else if (config.startsWith('http://') || config.startsWith('https://')) {
56
+ logger.info(`Creating read-only HTTP file store at ${config}`);
57
+ return new HttpFileStore(config, logger);
58
+ } else {
59
+ return await createFileStore(config, logger);
60
+ }
61
+ }
@@ -0,0 +1,121 @@
1
+ import { type Logger, createLogger } from '@aztec/foundation/log';
2
+
3
+ import { File, Storage, type UploadOptions } from '@google-cloud/storage';
4
+ import { join } from 'path';
5
+
6
+ import type { FileStore, FileStoreSaveOptions } from './interface.js';
7
+
8
+ export class GoogleCloudFileStore implements FileStore {
9
+ private readonly storage: Storage;
10
+
11
+ constructor(
12
+ private readonly bucketName: string,
13
+ private readonly basePath: string,
14
+ private readonly log: Logger = createLogger('stdlib:gcs-file-store'),
15
+ ) {
16
+ this.storage = new Storage();
17
+ }
18
+
19
+ public async checkCredentials() {
20
+ await this.storage.getServiceAccount();
21
+ }
22
+
23
+ public async save(
24
+ path: string,
25
+ data: Buffer,
26
+ opts: FileStoreSaveOptions = { public: false, metadata: {}, compress: false },
27
+ ): Promise<string> {
28
+ const fullPath = this.getFullPath(path);
29
+ try {
30
+ const bucket = this.storage.bucket(this.bucketName);
31
+ const file = bucket.file(fullPath);
32
+ await file.save(data, { metadata: opts.metadata, gzip: opts.compress });
33
+ return this.handleUploadedFile(file, opts);
34
+ } catch (err: any) {
35
+ throw new Error(`Error saving file to google cloud storage at ${fullPath}: ${err.message ?? err}`);
36
+ }
37
+ }
38
+
39
+ public async upload(
40
+ destPath: string,
41
+ srcPath: string,
42
+ opts: FileStoreSaveOptions = { compress: true, public: false, metadata: {} },
43
+ ): Promise<string> {
44
+ const fullPath = this.getFullPath(destPath);
45
+ try {
46
+ const bucket = this.storage.bucket(this.bucketName);
47
+ const file = bucket.file(fullPath);
48
+ const uploadOpts: UploadOptions = {
49
+ destination: file,
50
+ gzip: opts.compress,
51
+ metadata: opts.metadata,
52
+ };
53
+ await bucket.upload(srcPath, uploadOpts);
54
+ return this.handleUploadedFile(file, opts);
55
+ } catch (err: any) {
56
+ throw new Error(`Error saving file to google cloud storage at ${fullPath}: ${err.message ?? err}`);
57
+ }
58
+ }
59
+
60
+ private async handleUploadedFile(file: File, opts: { public?: boolean }): Promise<string> {
61
+ if (opts.public) {
62
+ try {
63
+ if (!(await file.isPublic())) {
64
+ await file.makePublic();
65
+ }
66
+ } catch (err: any) {
67
+ this.log.warn(
68
+ `Error making file ${file.name} public: ${
69
+ err.message ?? err
70
+ }. This is expected if we handle public access at the bucket level.`,
71
+ );
72
+ }
73
+ return file.publicUrl().replaceAll('%2F', '/');
74
+ } else {
75
+ return file.cloudStorageURI.toString();
76
+ }
77
+ }
78
+
79
+ public async read(pathOrUrlStr: string): Promise<Buffer> {
80
+ const file = await this.getFileObject(pathOrUrlStr);
81
+ const contents = await file.download();
82
+ return contents[0];
83
+ }
84
+
85
+ public async download(pathOrUrlStr: string, destPath: string): Promise<void> {
86
+ const file = await this.getFileObject(pathOrUrlStr);
87
+ await file.download({ destination: destPath });
88
+ }
89
+
90
+ public async exists(pathOrUrlStr: string): Promise<boolean> {
91
+ const { bucketName, fullPath } = this.getBucketAndFullPath(pathOrUrlStr);
92
+ const bucket = this.storage.bucket(bucketName);
93
+ const file = bucket.file(fullPath);
94
+ const [exists] = await file.exists();
95
+ return exists;
96
+ }
97
+
98
+ private async getFileObject(pathOrUrlStr: string): Promise<File> {
99
+ const { bucketName, fullPath } = this.getBucketAndFullPath(pathOrUrlStr);
100
+ const bucket = this.storage.bucket(bucketName);
101
+ const file = bucket.file(fullPath);
102
+ if (!(await file.exists())) {
103
+ throw new Error(`File at ${fullPath} in gcs bucket ${bucketName} does not exist`);
104
+ }
105
+ return file;
106
+ }
107
+
108
+ private getBucketAndFullPath(pathOrUrlStr: string): { bucketName: string; fullPath: string } {
109
+ if (URL.canParse(pathOrUrlStr)) {
110
+ const url = new URL(pathOrUrlStr);
111
+ // Note that we accept reading from anywhere, not just our bucket
112
+ return { fullPath: url.pathname.replace(/^\/+/, ''), bucketName: url.host };
113
+ } else {
114
+ return { fullPath: this.getFullPath(pathOrUrlStr), bucketName: this.bucketName };
115
+ }
116
+ }
117
+
118
+ private getFullPath(path: string): string {
119
+ return this.basePath && this.basePath.length > 0 ? join(this.basePath, path) : path;
120
+ }
121
+ }
@@ -0,0 +1,58 @@
1
+ import { type Logger, createLogger } from '@aztec/foundation/log';
2
+ import { makeBackoff, retry } from '@aztec/foundation/retry';
3
+
4
+ import { createWriteStream } from 'fs';
5
+ import { mkdir } from 'fs/promises';
6
+ import { dirname } from 'path';
7
+ import { Readable } from 'stream';
8
+ import { finished } from 'stream/promises';
9
+
10
+ import type { ReadOnlyFileStore } from './interface.js';
11
+
12
+ export class HttpFileStore implements ReadOnlyFileStore {
13
+ private readonly fetch: typeof fetch;
14
+
15
+ constructor(private readonly baseUrl: string, private readonly log: Logger = createLogger('stdlib:http-file-store')) {
16
+ this.fetch = async (...args: Parameters<typeof fetch>): Promise<Response> => {
17
+ return await retry(
18
+ () => fetch(...args),
19
+ `Fetching ${args[0]}`,
20
+ makeBackoff([1, 1, 3]),
21
+ this.log,
22
+ /*failSilently=*/ true,
23
+ );
24
+ };
25
+ }
26
+
27
+ public async read(pathOrUrl: string): Promise<Buffer> {
28
+ const url = this.getUrl(pathOrUrl);
29
+ const response = await this.fetch(url);
30
+ if (response.ok) {
31
+ return Buffer.from(await response.arrayBuffer());
32
+ } else {
33
+ throw new Error(`Error fetching file from ${url}: ${response.statusText}`);
34
+ }
35
+ }
36
+
37
+ public async download(pathOrUrl: string, destPath: string): Promise<void> {
38
+ const url = this.getUrl(pathOrUrl);
39
+ const response = await this.fetch(url);
40
+ if (response.ok) {
41
+ await mkdir(dirname(destPath), { recursive: true });
42
+ // Typescript complains about Readable.fromWeb, hence the cast
43
+ await finished(Readable.fromWeb(response.body! as any).pipe(createWriteStream(destPath)));
44
+ } else {
45
+ throw new Error(`Error fetching file from ${url}: ${response.statusText}`);
46
+ }
47
+ }
48
+
49
+ public async exists(pathOrUrl: string): Promise<boolean> {
50
+ const url = this.getUrl(pathOrUrl);
51
+ const response = await this.fetch(url);
52
+ return response.ok;
53
+ }
54
+
55
+ private getUrl(path: string): string {
56
+ return URL.canParse(path) ? path : `${this.baseUrl.replace(/\/$/, '')}/${path}`;
57
+ }
58
+ }
@@ -0,0 +1,2 @@
1
+ export * from './interface.js';
2
+ export * from './factory.js';
@@ -0,0 +1,19 @@
1
+ /** Simple read-only file store. */
2
+ export interface ReadOnlyFileStore {
3
+ /** Reads a file given a path, or an URI as returned by calling `save`. Returns file contents. */
4
+ read(pathOrUrl: string): Promise<Buffer>;
5
+ /** Downloads a file given a path, or an URI as returned by calling `save`. Saves file to local path. */
6
+ download(pathOrUrlStr: string, destPath: string): Promise<void>;
7
+ /** Returns whether a file at the given path or URI exists. */
8
+ exists(pathOrUrl: string): Promise<boolean>;
9
+ }
10
+
11
+ export type FileStoreSaveOptions = { public?: boolean; metadata?: Record<string, string>; compress?: boolean };
12
+
13
+ /** Simple file store. */
14
+ export interface FileStore extends ReadOnlyFileStore {
15
+ /** Saves contents to the given path. Returns an URI that can be used later to `read` the file. */
16
+ save(path: string, data: Buffer, opts?: FileStoreSaveOptions): Promise<string>;
17
+ /** Uploads contents from a local file. Returns an URI that can be used later to `read` the file. */
18
+ upload(destPath: string, srcPath: string, opts?: FileStoreSaveOptions): Promise<string>;
19
+ }
@@ -0,0 +1,46 @@
1
+ import { access, mkdir, readFile, writeFile } from 'fs/promises';
2
+ import { dirname, resolve } from 'path';
3
+
4
+ import type { FileStore } from './interface.js';
5
+
6
+ export class LocalFileStore implements FileStore {
7
+ constructor(private readonly basePath: string) {}
8
+
9
+ public async save(path: string, data: Buffer): Promise<string> {
10
+ const fullPath = this.getFullPath(path);
11
+ await mkdir(dirname(fullPath), { recursive: true });
12
+ await writeFile(fullPath, data);
13
+ return `file://${fullPath}`;
14
+ }
15
+
16
+ public async upload(destPath: string, srcPath: string, _opts: { compress: boolean }): Promise<string> {
17
+ const data = await readFile(srcPath);
18
+ return this.save(destPath, data);
19
+ }
20
+
21
+ public read(pathOrUrlStr: string): Promise<Buffer> {
22
+ const fullPath = this.getFullPath(pathOrUrlStr);
23
+ return readFile(fullPath);
24
+ }
25
+
26
+ public async download(pathOrUrlStr: string, destPath: string): Promise<void> {
27
+ const data = await this.read(pathOrUrlStr);
28
+ const fullPath = this.getFullPath(destPath);
29
+ await writeFile(fullPath, data);
30
+ }
31
+
32
+ public exists(pathOrUrlStr: string): Promise<boolean> {
33
+ const fullPath = this.getFullPath(pathOrUrlStr);
34
+ return access(fullPath)
35
+ .then(() => true)
36
+ .catch(() => false);
37
+ }
38
+
39
+ private getFullPath(pathOrUrl: string): string {
40
+ if (URL.canParse(pathOrUrl)) {
41
+ return new URL(pathOrUrl).pathname;
42
+ } else {
43
+ return resolve(this.basePath, pathOrUrl);
44
+ }
45
+ }
46
+ }
@@ -17,13 +17,23 @@ export interface AztecNodeAdmin {
17
17
  */
18
18
  setConfig(config: Partial<SequencerConfig & ProverConfig>): Promise<void>;
19
19
 
20
- /** Forces the next block to be built bypassing all time and pending checks. Useful for testing. */
20
+ /**
21
+ * Forces the next block to be built bypassing all time and pending checks.
22
+ * Useful for testing.
23
+ */
21
24
  flushTxs(): Promise<void>;
25
+
26
+ /**
27
+ * Pauses syncing, creates a backup of archiver and world-state databases, and uploads them. Returns immediately.
28
+ * @param location - The location to upload the snapshot to.
29
+ */
30
+ startSnapshotUpload(location: string): Promise<void>;
22
31
  }
23
32
 
24
33
  export const AztecNodeAdminApiSchema: ApiSchemaFor<AztecNodeAdmin> = {
25
34
  setConfig: z.function().args(SequencerConfigSchema.merge(ProverConfigSchema).partial()).returns(z.void()),
26
35
  flushTxs: z.function().returns(z.void()),
36
+ startSnapshotUpload: z.function().args(z.string()).returns(z.void()),
27
37
  };
28
38
 
29
39
  export function createAztecNodeAdminClient(
@@ -46,6 +46,8 @@ import {
46
46
  TxValidationResultSchema,
47
47
  } from '../tx/index.js';
48
48
  import { TxEffect } from '../tx/tx_effect.js';
49
+ import { ValidatorsStatsSchema } from '../validators/schemas.js';
50
+ import type { ValidatorsStats } from '../validators/types.js';
49
51
  import { type ComponentsVersions, getVersioningResponseHandler } from '../versioning/index.js';
50
52
  import {
51
53
  type GetContractClassLogsResponse,
@@ -379,6 +381,9 @@ export interface AztecNode
379
381
  */
380
382
  getBlockHeader(blockNumber?: L2BlockNumber): Promise<BlockHeader | undefined>;
381
383
 
384
+ /** Returns stats for validators if enabled. */
385
+ getValidatorsStats(): Promise<ValidatorsStats>;
386
+
382
387
  /**
383
388
  * Simulates the public part of a transaction with the current state.
384
389
  * This currently just checks that the transaction execution succeeds.
@@ -525,6 +530,8 @@ export const AztecNodeApiSchema: ApiSchemaFor<AztecNode> = {
525
530
 
526
531
  getBlockHeader: z.function().args(optional(L2BlockNumberSchema)).returns(BlockHeader.schema.optional()),
527
532
 
533
+ getValidatorsStats: z.function().returns(ValidatorsStatsSchema),
534
+
528
535
  simulatePublicCalls: z.function().args(Tx.schema, optional(z.boolean())).returns(PublicSimulationOutput.schema),
529
536
 
530
537
  isValidTx: z
@@ -50,6 +50,9 @@ export interface P2PClient extends P2PApiWithoutAttestations {
50
50
  * @returns BlockAttestations
51
51
  */
52
52
  getAttestationsForSlot(slot: bigint, proposalId?: string): Promise<BlockAttestation[]>;
53
+
54
+ /** Manually adds an attestation to the p2p client attestation pool. */
55
+ addAttestation(attestation: BlockAttestation): Promise<void>;
53
56
  }
54
57
 
55
58
  export type P2PApi<T extends P2PClientType = P2PClientType.Full> = T extends P2PClientType.Full
@@ -64,4 +67,5 @@ export const P2PApiSchema: ApiSchemaFor<P2PApi> = {
64
67
  getPendingTxs: z.function().returns(z.array(Tx.schema)),
65
68
  getEncodedEnr: z.function().returns(z.string().optional()),
66
69
  getPeers: z.function().args(optional(z.boolean())).returns(z.array(PeerInfoSchema)),
70
+ addAttestation: z.function().args(BlockAttestation.schema).returns(z.void()),
67
71
  };
@@ -26,7 +26,7 @@ export type ProverConfig = ActualProverConfig & {
26
26
  /** The URL to the Aztec node to take proving jobs from */
27
27
  nodeUrl?: string;
28
28
  /** Identifier of the prover */
29
- proverId: Fr;
29
+ proverId?: Fr;
30
30
  /** Number of proving agents to start within the prover. */
31
31
  proverAgentCount: number;
32
32
  /** Store for failed proof inputs. */
@@ -36,7 +36,7 @@ export type ProverConfig = ActualProverConfig & {
36
36
  export const ProverConfigSchema = z.object({
37
37
  nodeUrl: z.string().optional(),
38
38
  realProofs: z.boolean(),
39
- proverId: schemas.Fr,
39
+ proverId: schemas.Fr.optional(),
40
40
  proverTestDelayType: z.enum(['fixed', 'realistic']),
41
41
  proverTestDelayMs: z.number(),
42
42
  proverTestDelayFactor: z.number(),
@@ -55,9 +55,8 @@ export const proverConfigMappings: ConfigMappingsType<ProverConfig> = {
55
55
  },
56
56
  proverId: {
57
57
  env: 'PROVER_ID',
58
- parseEnv: (val: string) => parseProverId(val),
59
- description: 'Identifier of the prover',
60
- defaultValue: Fr.ZERO,
58
+ parseEnv: (val?: string) => parseProverId(val),
59
+ description: 'Hex value that identifies the prover. Defaults to the address used for submitting proofs if not set.',
61
60
  },
62
61
  proverTestDelayType: {
63
62
  env: 'PROVER_TEST_DELAY_TYPE',
@@ -85,8 +84,11 @@ export const proverConfigMappings: ConfigMappingsType<ProverConfig> = {
85
84
  },
86
85
  };
87
86
 
88
- function parseProverId(str: string) {
89
- return Fr.fromHexString(str.startsWith('0x') ? str : Buffer.from(str, 'utf8').toString('hex'));
87
+ function parseProverId(str?: string) {
88
+ if (!str) {
89
+ return undefined;
90
+ }
91
+ return Fr.fromHexString(str);
90
92
  }
91
93
 
92
94
  /**
@@ -1,6 +1,8 @@
1
1
  import { z } from 'zod';
2
2
 
3
+ import { type L2Tips, L2TipsSchema } from '../block/l2_block_source.js';
3
4
  import { type ApiSchemaFor, schemas } from '../schemas/index.js';
5
+ import { type WorldStateSyncStatus, WorldStateSyncStatusSchema } from './world_state.js';
4
6
 
5
7
  const EpochProvingJobState = [
6
8
  'initialized',
@@ -31,6 +33,10 @@ export interface ProverNodeApi {
31
33
  getJobs(): Promise<{ uuid: string; status: EpochProvingJobState; epochNumber: number }[]>;
32
34
 
33
35
  startProof(epochNumber: number): Promise<void>;
36
+
37
+ getL2Tips(): Promise<L2Tips>;
38
+
39
+ getWorldStateSyncStatus(): Promise<WorldStateSyncStatus>;
34
40
  }
35
41
 
36
42
  /** Schemas for prover node API functions. */
@@ -41,4 +47,8 @@ export const ProverNodeApiSchema: ApiSchemaFor<ProverNodeApi> = {
41
47
  .returns(z.array(z.object({ uuid: z.string(), status: z.enum(EpochProvingJobState), epochNumber: z.number() }))),
42
48
 
43
49
  startProof: z.function().args(schemas.Integer).returns(z.void()),
50
+
51
+ getL2Tips: z.function().args().returns(L2TipsSchema),
52
+
53
+ getWorldStateSyncStatus: z.function().args().returns(WorldStateSyncStatusSchema),
44
54
  };
@@ -1,5 +1,5 @@
1
1
  import { L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/constants';
2
- import type { Fr, Point } from '@aztec/foundation/fields';
2
+ import type { Fr } from '@aztec/foundation/fields';
3
3
  import type { ApiSchemaFor, ZodFor } from '@aztec/foundation/schemas';
4
4
  import { SiblingPath } from '@aztec/foundation/trees';
5
5
 
@@ -129,7 +129,7 @@ export interface PXE {
129
129
 
130
130
  /**
131
131
  * Proves the private portion of a simulated transaction, ready to send to the network
132
- * (where valiators prove the public portion).
132
+ * (where validators prove the public portion).
133
133
  *
134
134
  * @param txRequest - An authenticated tx request ready for proving
135
135
  * @param privateExecutionResult - The result of the private execution of the transaction
@@ -313,7 +313,7 @@ export interface PXE {
313
313
 
314
314
  /**
315
315
  * Returns the information about the server's node. Includes current Node version, compatible Noir version,
316
- * L1 chain identifier, protocol version, and L1 address of the rollup contract.
316
+ * L1 chain identifier, rollup version, and L1 address of the rollup contract.
317
317
  * @returns - The node information.
318
318
  */
319
319
  getNodeInfo(): Promise<NodeInfo>;
@@ -354,13 +354,20 @@ export interface PXE {
354
354
 
355
355
  /**
356
356
  * Returns the private events given search parameters.
357
+ * @param contractAddress - The address of the contract to get events from.
357
358
  * @param eventMetadata - Metadata of the event. This should be the class generated from the contract. e.g. Contract.events.Event
358
359
  * @param from - The block number to search from.
359
- * @param limit - The amount of blocks to search.
360
- * @param vpks - The incoming viewing public keys that can decrypt the log.
360
+ * @param numBlocks - The amount of blocks to search.
361
+ * @param recipients - The addresses that decrypted the logs.
361
362
  * @returns - The deserialized events.
362
363
  */
363
- getPrivateEvents<T>(eventMetadata: EventMetadataDefinition, from: number, limit: number, vpks: Point[]): Promise<T[]>;
364
+ getPrivateEvents<T>(
365
+ contractAddress: AztecAddress,
366
+ eventMetadata: EventMetadataDefinition,
367
+ from: number,
368
+ numBlocks: number,
369
+ recipients: AztecAddress[],
370
+ ): Promise<T[]>;
364
371
 
365
372
  /**
366
373
  * Returns the public events given search parameters.
@@ -505,7 +512,7 @@ export const PXESchema: ApiSchemaFor<PXE> = {
505
512
  getContractClassMetadata: z.function().args(schemas.Fr, optional(z.boolean())).returns(ContractClassMetadataSchema),
506
513
  getPrivateEvents: z
507
514
  .function()
508
- .args(EventMetadataDefinitionSchema, z.number(), z.number(), z.array(schemas.Point))
515
+ .args(schemas.AztecAddress, EventMetadataDefinitionSchema, z.number(), z.number(), z.array(schemas.AztecAddress))
509
516
  .returns(z.array(AbiDecodedSchema)),
510
517
  getPublicEvents: z
511
518
  .function()
@@ -11,6 +11,9 @@ export interface Service {
11
11
 
12
12
  /** Stops the service. */
13
13
  stop(): Promise<void>;
14
+
15
+ /** Resumes the service after it was stopped */
16
+ resume(): void;
14
17
  }
15
18
 
16
19
  /** Tries to call stop on a given object and awaits it. Logs any errors and does not rethrow. */
@@ -23,3 +26,13 @@ export async function tryStop(service: Maybe<Service>, logger?: Logger): Promise
23
26
  logger?.error(`Error stopping service ${(service as object).constructor?.name}: ${err}`);
24
27
  }
25
28
  }
29
+
30
+ export function tryRestart(service: Maybe<Service>, logger?: Logger) {
31
+ try {
32
+ return typeof service === 'object' && service && 'restart' in service && typeof service.restart === 'function'
33
+ ? service.restart()
34
+ : Promise.resolve();
35
+ } catch (err) {
36
+ logger?.error(`Error restarting service ${(service as object).constructor?.name}: ${err}`);
37
+ }
38
+ }
@@ -1,7 +1,10 @@
1
1
  import { z } from 'zod';
2
2
 
3
+ import type { SnapshotDataKeys } from '../snapshots/types.js';
3
4
  import type { MerkleTreeReadOperations, MerkleTreeWriteOperations } from './merkle_tree_operations.js';
4
5
 
6
+ export type { SnapshotDataKeys };
7
+
5
8
  /**
6
9
  * Defines the possible states of the world state synchronizer.
7
10
  */
@@ -41,37 +44,36 @@ export interface ForkMerkleTreeOperations {
41
44
 
42
45
  /** Gets a handle that allows reading the state as it was at the given block number. */
43
46
  getSnapshot(blockNumber: number): MerkleTreeReadOperations;
47
+
48
+ /** Backups the db to the target path. */
49
+ backupTo(dstPath: string, compact?: boolean): Promise<Record<Exclude<SnapshotDataKeys, 'archiver'>, string>>;
44
50
  }
45
51
 
46
52
  /** Defines the interface for a world state synchronizer. */
47
53
  export interface WorldStateSynchronizer extends ForkMerkleTreeOperations {
48
- /**
49
- * Starts the synchronizer.
50
- * @returns A promise that resolves once the initial sync is completed.
51
- */
54
+ /** Starts the synchronizer. */
52
55
  start(): void;
53
56
 
54
- /**
55
- * Returns the current status of the synchronizer.
56
- * @returns The current status of the synchronizer.
57
- */
57
+ /** Returns the current status of the synchronizer. */
58
58
  status(): Promise<WorldStateSynchronizerStatus>;
59
59
 
60
- /**
61
- * Stops the synchronizer.
62
- */
60
+ /** Stops the synchronizer and its database. */
63
61
  stop(): Promise<void>;
64
62
 
63
+ /** Stops the synchronizer from syncing, but keeps the database online. */
64
+ stopSync(): Promise<void>;
65
+
66
+ /** Resumes synching after a stopSync call. */
67
+ resumeSync(): void;
68
+
65
69
  /**
66
70
  * Forces an immediate sync to an optionally provided minimum block number
67
- * @param minBlockNumber - The minimum block number that we must sync to
71
+ * @param minBlockNumber - The minimum block number that we must sync to (may sync further)
68
72
  * @returns A promise that resolves with the block number the world state was synced to
69
73
  */
70
74
  syncImmediate(minBlockNumber?: number): Promise<number>;
71
75
 
72
- /**
73
- * Returns an instance of MerkleTreeAdminOperations that will not include uncommitted data.
74
- */
76
+ /** Returns an instance of MerkleTreeAdminOperations that will not include uncommitted data. */
75
77
  getCommitted(): MerkleTreeReadOperations;
76
78
  }
77
79
 
@@ -1,5 +1,5 @@
1
1
  import { GeneratorIndex } from '@aztec/constants';
2
- import { Grumpkin, poseidon2HashWithSeparator, sha512ToGrumpkinScalar } from '@aztec/foundation/crypto';
2
+ import { Grumpkin, poseidon2Hash, poseidon2HashWithSeparator, sha512ToGrumpkinScalar } from '@aztec/foundation/crypto';
3
3
  import { Fq, Fr, GrumpkinScalar } from '@aztec/foundation/fields';
4
4
 
5
5
  import { AztecAddress } from '../aztec-address/index.js';
@@ -123,11 +123,7 @@ export async function deriveKeys(secretKey: Fr) {
123
123
  }
124
124
 
125
125
  // Returns shared tagging secret computed with Diffie-Hellman key exchange.
126
- export async function computeTaggingSecretPoint(
127
- knownAddress: CompleteAddress,
128
- ivsk: Fq,
129
- externalAddress: AztecAddress,
130
- ) {
126
+ async function computeTaggingSecretPoint(knownAddress: CompleteAddress, ivsk: Fq, externalAddress: AztecAddress) {
131
127
  const knownPreaddress = await computePreaddress(await knownAddress.publicKeys.hash(), knownAddress.partialAddress);
132
128
  // TODO: #8970 - Computation of address point from x coordinate might fail
133
129
  const externalAddressPoint = await externalAddress.toAddressPoint();
@@ -139,3 +135,13 @@ export async function computeTaggingSecretPoint(
139
135
  // computeAddressSecret takes care of selecting the one that leads to a positive y-coordinate, which is the only valid address point
140
136
  return curve.mul(externalAddressPoint, await computeAddressSecret(knownPreaddress, ivsk));
141
137
  }
138
+
139
+ export async function computeAppTaggingSecret(
140
+ knownAddress: CompleteAddress,
141
+ ivsk: Fq,
142
+ externalAddress: AztecAddress,
143
+ app: AztecAddress,
144
+ ) {
145
+ const taggingSecretPoint = await computeTaggingSecretPoint(knownAddress, ivsk, externalAddress);
146
+ return poseidon2Hash([taggingSecretPoint.x, taggingSecretPoint.y, app]);
147
+ }
package/src/logs/index.ts CHANGED
@@ -3,9 +3,10 @@ export * from './indexed_tagging_secret.js';
3
3
  export * from './contract_class_log.js';
4
4
  export * from './public_log.js';
5
5
  export * from './private_log.js';
6
+ export * from './pending_tagged_log.js';
6
7
  export * from './log_id.js';
7
8
  export * from './log_filter.js';
8
9
  export * from './extended_public_log.js';
9
10
  export * from './extended_contract_class_log.js';
10
- export * from './l1_payload/index.js';
11
+ export * from './shared_secret_derivation.js';
11
12
  export * from './tx_scoped_l2_log.js';