@aztec/stdlib 0.77.0-testnet-ignition.30 → 0.77.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 (33) hide show
  1. package/dest/contract/interfaces/contract_instance_update.js +1 -1
  2. package/dest/contract/interfaces/node-info.js +2 -2
  3. package/dest/database-version/index.d.ts +2 -0
  4. package/dest/database-version/index.d.ts.map +1 -0
  5. package/dest/database-version/index.js +1 -0
  6. package/dest/database-version/version_manager.d.ts +99 -0
  7. package/dest/database-version/version_manager.d.ts.map +1 -0
  8. package/dest/database-version/version_manager.js +188 -0
  9. package/dest/errors/simulation_error.js +2 -2
  10. package/dest/hash/hash.d.ts +0 -2
  11. package/dest/hash/hash.d.ts.map +1 -1
  12. package/dest/hash/hash.js +0 -11
  13. package/dest/interfaces/world_state.js +3 -3
  14. package/dest/logs/contract_class_log.d.ts +4 -0
  15. package/dest/logs/contract_class_log.d.ts.map +1 -1
  16. package/dest/logs/contract_class_log.js +27 -1
  17. package/dest/messaging/l2_to_l1_message.js +1 -1
  18. package/dest/tx/tx.d.ts.map +1 -1
  19. package/dest/tx/tx.js +2 -3
  20. package/dest/tx/tx_receipt.js +1 -1
  21. package/package.json +8 -7
  22. package/src/contract/interfaces/contract_instance_update.ts +1 -1
  23. package/src/contract/interfaces/node-info.ts +2 -2
  24. package/src/database-version/README.md +63 -0
  25. package/src/database-version/index.ts +1 -0
  26. package/src/database-version/version_manager.ts +207 -0
  27. package/src/errors/simulation_error.ts +2 -2
  28. package/src/hash/hash.ts +0 -10
  29. package/src/interfaces/world_state.ts +3 -3
  30. package/src/logs/contract_class_log.ts +25 -1
  31. package/src/messaging/l2_to_l1_message.ts +1 -1
  32. package/src/tx/tx.ts +4 -3
  33. package/src/tx/tx_receipt.ts +1 -1
@@ -3,7 +3,7 @@ import { schemas } from '../../schemas/index.js';
3
3
  export const ContractInstanceUpdateSchema = z.object({
4
4
  prevContractClassId: schemas.Fr,
5
5
  newContractClassId: schemas.Fr,
6
- blockOfChange: z.number()
6
+ blockOfChange: z.number().int().nonnegative()
7
7
  });
8
8
  export const ContractInstanceUpdateWithAddressSchema = ContractInstanceUpdateSchema.and(z.object({
9
9
  address: schemas.AztecAddress
@@ -3,8 +3,8 @@ import { z } from 'zod';
3
3
  import { ProtocolContractAddressesSchema } from './protocol_contract_addresses.js';
4
4
  export const NodeInfoSchema = z.object({
5
5
  nodeVersion: z.string(),
6
- l1ChainId: z.number(),
7
- protocolVersion: z.number(),
6
+ l1ChainId: z.number().int().nonnegative(),
7
+ protocolVersion: z.number().int().nonnegative(),
8
8
  enr: z.string().optional(),
9
9
  l1ContractAddresses: L1ContractAddressesSchema,
10
10
  protocolContractAddresses: ProtocolContractAddressesSchema
@@ -0,0 +1,2 @@
1
+ export * from './version_manager.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/database-version/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1 @@
1
+ export * from './version_manager.js';
@@ -0,0 +1,99 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ /// <reference types="node" resolution-mode="require"/>
3
+ /// <reference types="node" resolution-mode="require"/>
4
+ import { EthAddress } from '@aztec/foundation/eth-address';
5
+ import fs from 'fs/promises';
6
+ import { z } from 'zod';
7
+ /**
8
+ * Represents a version record for storing in a version file.
9
+ */
10
+ export declare class DatabaseVersion {
11
+ readonly schemaVersion: number;
12
+ readonly rollupAddress: EthAddress;
13
+ constructor(schemaVersion: number, rollupAddress: EthAddress);
14
+ toBuffer(): Buffer;
15
+ static fromBuffer(buf: Buffer): DatabaseVersion;
16
+ /**
17
+ * Compares two versions. If the rollups addresses are different then it returns undefined
18
+ */
19
+ cmp(other: DatabaseVersion): undefined | -1 | 0 | 1;
20
+ /**
21
+ * Checks if two versions exactly match
22
+ */
23
+ equals(other: DatabaseVersion): boolean;
24
+ /**
25
+ * Returns the schema for this class
26
+ */
27
+ static get schema(): z.ZodEffects<z.ZodObject<{
28
+ schemaVersion: z.ZodNumber;
29
+ rollupAddress: z.ZodType<EthAddress, any, string>;
30
+ }, "strip", z.ZodTypeAny, {
31
+ rollupAddress: EthAddress;
32
+ schemaVersion: number;
33
+ }, {
34
+ rollupAddress: string;
35
+ schemaVersion: number;
36
+ }>, DatabaseVersion, {
37
+ rollupAddress: string;
38
+ schemaVersion: number;
39
+ }>;
40
+ /**
41
+ * Returns an empty instance
42
+ */
43
+ static empty(): DatabaseVersion;
44
+ }
45
+ export type DatabaseVersionManagerFs = Pick<typeof fs, 'readFile' | 'writeFile' | 'rm' | 'mkdir'>;
46
+ /**
47
+ * A manager for handling database versioning and migrations.
48
+ * This class will check the version of data in a directory and either
49
+ * reset or upgrade based on version compatibility.
50
+ */
51
+ export declare class DatabaseVersionManager<T> {
52
+ private dataDirectory;
53
+ private onOpen;
54
+ private onUpgrade?;
55
+ private fileSystem;
56
+ private log;
57
+ static readonly VERSION_FILE = "db_version";
58
+ private readonly versionFile;
59
+ private readonly currentVersion;
60
+ /**
61
+ * Create a new version manager
62
+ *
63
+ * @param schemaVersion - The current version of the application
64
+ * @param rollupAddress - The rollup contract address
65
+ * @param dataDirectory - The directory where version information will be stored
66
+ * @param onOpen - A callback to the open the database at the given location
67
+ * @param onUpgrade - An optional callback to upgrade the database before opening. If not provided it will reset the database
68
+ * @param fileSystem - An interface to access the filesystem
69
+ * @param log - Optional custom logger
70
+ * @param options - Configuration options
71
+ */
72
+ constructor(schemaVersion: number, rollupAddress: EthAddress, dataDirectory: string, onOpen: (dataDir: string) => Promise<T>, onUpgrade?: ((dataDir: string, currentVersion: number, latestVersion: number) => Promise<void>) | undefined, fileSystem?: DatabaseVersionManagerFs, log?: import("@aztec/foundation/log").Logger);
73
+ /**
74
+ * Checks the stored version against the current version and handles the outcome
75
+ * by either resetting the data directory or calling an upgrade function
76
+ *
77
+ * @param onReset - Function to call when a full reset is needed
78
+ * @param onUpgrade - Function to call when an upgrade is needed
79
+ * @returns True if data was reset, false if upgraded or no change needed
80
+ */
81
+ open(): Promise<[T, boolean]>;
82
+ /**
83
+ * Writes the current version to the version file
84
+ */
85
+ private writeVersion;
86
+ /**
87
+ * Resets the data directory by deleting it and recreating it
88
+ */
89
+ private resetDataDirectory;
90
+ /**
91
+ * Get the data directory path
92
+ */
93
+ getDataDirectory(): string;
94
+ /**
95
+ * Get the current version number
96
+ */
97
+ getSchemaVersion(): number;
98
+ }
99
+ //# sourceMappingURL=version_manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version_manager.d.ts","sourceRoot":"","sources":["../../src/database-version/version_manager.ts"],"names":[],"mappings":";;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAI3D,OAAO,EAAE,MAAM,aAAa,CAAC;AAE7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,qBAAa,eAAe;aACE,aAAa,EAAE,MAAM;aAAkB,aAAa,EAAE,UAAU;gBAAhE,aAAa,EAAE,MAAM,EAAkB,aAAa,EAAE,UAAU;IAErF,QAAQ,IAAI,MAAM;WAIX,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe;IAQtD;;OAEG;IACI,GAAG,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IAa1D;;OAEG;IACI,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO;IAI9C;;OAEG;IACH,MAAM,KAAK,MAAM;;;;;;;;;;;;OAOhB;IAED;;OAEG;IACH,MAAM,CAAC,KAAK;CAGb;AAED,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI,GAAG,OAAO,CAAC,CAAC;AAElG;;;;GAIG;AACH,qBAAa,sBAAsB,CAAC,CAAC;IAqBjC,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,SAAS,CAAC;IAClB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,GAAG;IAxBb,gBAAuB,YAAY,gBAAgB;IAEnD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkB;IAEjD;;;;;;;;;;;OAWG;gBAED,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,UAAU,EACjB,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EACvC,SAAS,CAAC,aAAY,MAAM,kBAAkB,MAAM,iBAAiB,MAAM,KAAK,QAAQ,IAAI,CAAC,aAAA,EAC7F,UAAU,GAAE,wBAA6B,EACzC,GAAG,yCAA6C;IAU1D;;;;;;;OAOG;IACU,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAmD1C;;OAEG;YACW,YAAY;IAO1B;;OAEG;YACW,kBAAkB;IAUhC;;OAEG;IACI,gBAAgB,IAAI,MAAM;IAIjC;;OAEG;IACI,gBAAgB,IAAI,MAAM;CAGlC"}
@@ -0,0 +1,188 @@
1
+ import { EthAddress } from '@aztec/foundation/eth-address';
2
+ import { jsonParseWithSchemaSync, jsonStringify } from '@aztec/foundation/json-rpc';
3
+ import { createLogger } from '@aztec/foundation/log';
4
+ import fs from 'fs/promises';
5
+ import { join } from 'path';
6
+ import { z } from 'zod';
7
+ /**
8
+ * Represents a version record for storing in a version file.
9
+ */ export class DatabaseVersion {
10
+ schemaVersion;
11
+ rollupAddress;
12
+ constructor(schemaVersion, rollupAddress){
13
+ this.schemaVersion = schemaVersion;
14
+ this.rollupAddress = rollupAddress;
15
+ }
16
+ toBuffer() {
17
+ return Buffer.from(jsonStringify(this));
18
+ }
19
+ static fromBuffer(buf) {
20
+ try {
21
+ return jsonParseWithSchemaSync(buf.toString('utf-8'), DatabaseVersion.schema);
22
+ } catch (err) {
23
+ throw new Error(`Failed to deserialize version information: ${err}`, {
24
+ cause: err
25
+ });
26
+ }
27
+ }
28
+ /**
29
+ * Compares two versions. If the rollups addresses are different then it returns undefined
30
+ */ cmp(other) {
31
+ if (this.rollupAddress.equals(other.rollupAddress)) {
32
+ if (this.schemaVersion < other.schemaVersion) {
33
+ return -1;
34
+ } else if (this.schemaVersion > other.schemaVersion) {
35
+ return 1;
36
+ } else {
37
+ return 0;
38
+ }
39
+ }
40
+ return undefined;
41
+ }
42
+ /**
43
+ * Checks if two versions exactly match
44
+ */ equals(other) {
45
+ return this.cmp(other) === 0;
46
+ }
47
+ /**
48
+ * Returns the schema for this class
49
+ */ static get schema() {
50
+ return z.object({
51
+ schemaVersion: z.number(),
52
+ rollupAddress: EthAddress.schema
53
+ }).transform(({ schemaVersion, rollupAddress })=>new DatabaseVersion(schemaVersion, rollupAddress));
54
+ }
55
+ /**
56
+ * Returns an empty instance
57
+ */ static empty() {
58
+ return new DatabaseVersion(0, EthAddress.ZERO);
59
+ }
60
+ }
61
+ /**
62
+ * A manager for handling database versioning and migrations.
63
+ * This class will check the version of data in a directory and either
64
+ * reset or upgrade based on version compatibility.
65
+ */ export class DatabaseVersionManager {
66
+ dataDirectory;
67
+ onOpen;
68
+ onUpgrade;
69
+ fileSystem;
70
+ log;
71
+ static VERSION_FILE = 'db_version';
72
+ versionFile;
73
+ currentVersion;
74
+ /**
75
+ * Create a new version manager
76
+ *
77
+ * @param schemaVersion - The current version of the application
78
+ * @param rollupAddress - The rollup contract address
79
+ * @param dataDirectory - The directory where version information will be stored
80
+ * @param onOpen - A callback to the open the database at the given location
81
+ * @param onUpgrade - An optional callback to upgrade the database before opening. If not provided it will reset the database
82
+ * @param fileSystem - An interface to access the filesystem
83
+ * @param log - Optional custom logger
84
+ * @param options - Configuration options
85
+ */ constructor(schemaVersion, rollupAddress, dataDirectory, onOpen, onUpgrade, fileSystem = fs, log = createLogger(`foundation:version-manager`)){
86
+ this.dataDirectory = dataDirectory;
87
+ this.onOpen = onOpen;
88
+ this.onUpgrade = onUpgrade;
89
+ this.fileSystem = fileSystem;
90
+ this.log = log;
91
+ if (schemaVersion < 1) {
92
+ throw new TypeError(`Invalid schema version received: ${schemaVersion}`);
93
+ }
94
+ this.versionFile = join(this.dataDirectory, DatabaseVersionManager.VERSION_FILE);
95
+ this.currentVersion = new DatabaseVersion(schemaVersion, rollupAddress);
96
+ }
97
+ /**
98
+ * Checks the stored version against the current version and handles the outcome
99
+ * by either resetting the data directory or calling an upgrade function
100
+ *
101
+ * @param onReset - Function to call when a full reset is needed
102
+ * @param onUpgrade - Function to call when an upgrade is needed
103
+ * @returns True if data was reset, false if upgraded or no change needed
104
+ */ async open() {
105
+ // const storedVersion = await DatabaseVersion.readVersion(this.versionFile);
106
+ let storedVersion;
107
+ try {
108
+ const versionBuf = await this.fileSystem.readFile(this.versionFile);
109
+ storedVersion = DatabaseVersion.fromBuffer(versionBuf);
110
+ } catch (err) {
111
+ if (err && err.code === 'ENOENT') {
112
+ storedVersion = DatabaseVersion.empty();
113
+ } else {
114
+ this.log.warn(`Failed to read stored version information: ${err}. Defaulting to empty version`);
115
+ storedVersion = DatabaseVersion.empty();
116
+ }
117
+ }
118
+ const cmp = storedVersion.cmp(this.currentVersion);
119
+ let needsReset = false;
120
+ if (typeof cmp === 'number') {
121
+ // only allow forward upgrades
122
+ if (cmp === -1 && this.onUpgrade) {
123
+ this.log.info(`Upgrading from version ${storedVersion.schemaVersion} to ${this.currentVersion.schemaVersion}`);
124
+ try {
125
+ await this.onUpgrade(this.dataDirectory, storedVersion.schemaVersion, this.currentVersion.schemaVersion);
126
+ } catch (error) {
127
+ this.log.error(`Failed to upgrade: ${error}. Falling back to reset.`);
128
+ needsReset = true;
129
+ }
130
+ } else if (cmp !== 0) {
131
+ this.log.info(`Can't upgrade from version ${storedVersion.schemaVersion} to ${this.currentVersion}. Resetting database at ${this.dataDirectory}`);
132
+ needsReset = true;
133
+ }
134
+ } else {
135
+ this.log.warn('Rollup address changed, resetting data directory');
136
+ needsReset = true;
137
+ }
138
+ // Handle reset if needed
139
+ if (needsReset) {
140
+ await this.resetDataDirectory();
141
+ }
142
+ // Write the current version to disk
143
+ await this.writeVersion();
144
+ return [
145
+ await this.onOpen(this.dataDirectory),
146
+ needsReset
147
+ ];
148
+ }
149
+ /**
150
+ * Writes the current version to the version file
151
+ */ async writeVersion() {
152
+ // Ensure the directory exists
153
+ await this.fileSystem.mkdir(this.dataDirectory, {
154
+ recursive: true
155
+ });
156
+ // Write the version file
157
+ await this.fileSystem.writeFile(this.versionFile, this.currentVersion.toBuffer());
158
+ }
159
+ /**
160
+ * Resets the data directory by deleting it and recreating it
161
+ */ async resetDataDirectory() {
162
+ try {
163
+ await this.fileSystem.rm(this.dataDirectory, {
164
+ recursive: true,
165
+ force: true,
166
+ maxRetries: 3
167
+ });
168
+ await this.fileSystem.mkdir(this.dataDirectory, {
169
+ recursive: true
170
+ });
171
+ } catch (err) {
172
+ this.log.error(`Failed to reset data directory: ${err}`);
173
+ throw new Error(`Failed to reset data directory: ${err}`, {
174
+ cause: err
175
+ });
176
+ }
177
+ }
178
+ /**
179
+ * Get the data directory path
180
+ */ getDataDirectory() {
181
+ return this.dataDirectory;
182
+ }
183
+ /**
184
+ * Get the current version number
185
+ */ getSchemaVersion() {
186
+ return this.currentVersion.schemaVersion;
187
+ }
188
+ }
@@ -4,8 +4,8 @@ import { AztecAddress } from '../aztec-address/index.js';
4
4
  import { schemas } from '../schemas/index.js';
5
5
  const SourceCodeLocationSchema = z.object({
6
6
  filePath: z.string(),
7
- line: z.number(),
8
- column: z.number(),
7
+ line: z.number().int().nonnegative(),
8
+ column: z.number().int().nonnegative(),
9
9
  fileSource: z.string(),
10
10
  locationText: z.string()
11
11
  });
@@ -1,6 +1,5 @@
1
1
  import { Fr } from '@aztec/foundation/fields';
2
2
  import type { AztecAddress } from '../aztec-address/index.js';
3
- import type { ContractClassLog } from '../logs/index.js';
4
3
  import type { ScopedL2ToL1Message } from '../messaging/l2_to_l1_message.js';
5
4
  /**
6
5
  * Computes a hash of a given verification key.
@@ -73,5 +72,4 @@ export declare function computeL1ToL2MessageNullifier(contract: AztecAddress, me
73
72
  * @returns Fr containing 248 bits of information of sha256 hash.
74
73
  */
75
74
  export declare function siloL2ToL1Message(l2ToL1Message: ScopedL2ToL1Message, version: Fr, chainId: Fr): Fr;
76
- export declare function siloContractClassLog(log: ContractClassLog, contract: AztecAddress): Promise<ContractClassLog>;
77
75
  //# sourceMappingURL=hash.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/hash/hash.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAE5E;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,WAAW,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAErD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC,CAE1F;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAE9E;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAEhF;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAErF;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,CAExD;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAAC,eAAe,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAEzG;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAM1D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAEzD;AAED,wBAAsB,6BAA6B,CAAC,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,eAMtG;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,mBAAmB,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,CAiBlG;AAED,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,gBAAgB,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAOnH"}
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/hash/hash.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAE5E;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,WAAW,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAErD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC,CAE1F;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAE9E;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAEhF;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAErF;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,CAExD;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAAC,eAAe,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAEzG;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAM1D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAEzD;AAED,wBAAsB,6BAA6B,CAAC,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,eAMtG;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,mBAAmB,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,CAiBlG"}
package/dest/hash/hash.js CHANGED
@@ -122,14 +122,3 @@ export async function computeL1ToL2MessageNullifier(contract, messageHash, secre
122
122
  ]);
123
123
  return Fr.fromBuffer(sha256Trunc(preimage));
124
124
  }
125
- export async function siloContractClassLog(log, contract) {
126
- const innerLog = log.clone();
127
- if (contract.isZero()) {
128
- return innerLog;
129
- }
130
- innerLog.fields[0] = await poseidon2Hash([
131
- contract,
132
- innerLog.fields[0]
133
- ]);
134
- return innerLog;
135
- }
@@ -9,9 +9,9 @@ import { z } from 'zod';
9
9
  return WorldStateRunningState;
10
10
  }({});
11
11
  export const WorldStateSyncStatusSchema = z.object({
12
- finalisedBlockNumber: z.number(),
13
- latestBlockNumber: z.number(),
12
+ finalisedBlockNumber: z.number().int().nonnegative(),
13
+ latestBlockNumber: z.number().int().nonnegative(),
14
14
  latestBlockHash: z.string(),
15
- oldestHistoricBlockNumber: z.number(),
15
+ oldestHistoricBlockNumber: z.number().int().nonnegative(),
16
16
  treesAreSynched: z.boolean()
17
17
  });
@@ -10,6 +10,7 @@ export declare class ContractClassLog {
10
10
  contractAddress: AztecAddress;
11
11
  fields: Fr[];
12
12
  static SIZE_IN_BYTES: number;
13
+ unsiloedFirstField?: Fr | undefined;
13
14
  constructor(contractAddress: AztecAddress, fields: Fr[]);
14
15
  toFields(): Fr[];
15
16
  static fromFields(fields: Fr[] | FieldReader): ContractClassLog;
@@ -21,6 +22,9 @@ export declare class ContractClassLog {
21
22
  static random(): Promise<ContractClassLog>;
22
23
  getEmittedLength(): number;
23
24
  getEmittedFields(): Fr[];
25
+ setUnsiloedFirstField(field: Fr): void;
26
+ toUnsiloed(): ContractClassLog;
27
+ silo(): Promise<ContractClassLog>;
24
28
  hash(): Promise<Fr>;
25
29
  static get schema(): z.ZodEffects<z.ZodObject<{
26
30
  contractAddress: import("@aztec/foundation/schemas").ZodFor<AztecAddress>;
@@ -1 +1 @@
1
- {"version":3,"file":"contract_class_log.d.ts","sourceRoot":"","sources":["../../src/logs/contract_class_log.ts"],"names":[],"mappings":";;;AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAqB,MAAM,6BAA6B,CAAC;AAE3F,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,qBAAa,gBAAgB;IAKR,eAAe,EAAE,YAAY;IAAS,MAAM,EAAE,EAAE,EAAE;IAJrE,MAAM,CAAC,aAAa,SAAwD;gBAIzD,eAAe,EAAE,YAAY,EAAS,MAAM,EAAE,EAAE,EAAE;IAQrE,QAAQ,IAAI,EAAE,EAAE;IAIhB,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,WAAW;IAU5C,OAAO;IAIP,MAAM,CAAC,KAAK;IAIZ,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IAW/C,KAAK;WAIQ,MAAM;IAWnB,gBAAgB;IAMhB,gBAAgB;IAWV,IAAI;IAIV,MAAM,KAAK,MAAM;;;;;;;;;;;;OAOhB;IAED,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM;CAK3B"}
1
+ {"version":3,"file":"contract_class_log.d.ts","sourceRoot":"","sources":["../../src/logs/contract_class_log.ts"],"names":[],"mappings":";;;AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAqB,MAAM,6BAA6B,CAAC;AAE3F,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,qBAAa,gBAAgB;IAOR,eAAe,EAAE,YAAY;IAAS,MAAM,EAAE,EAAE,EAAE;IANrE,MAAM,CAAC,aAAa,SAAwD;IAErE,kBAAkB,CAAC,EAAE,EAAE,GAAG,SAAS,CAAC;gBAIxB,eAAe,EAAE,YAAY,EAAS,MAAM,EAAE,EAAE,EAAE;IAQrE,QAAQ,IAAI,EAAE,EAAE;IAIhB,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,WAAW;IAU5C,OAAO;IAIP,MAAM,CAAC,KAAK;IAIZ,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IAW/C,KAAK;WAIQ,MAAM;IAWnB,gBAAgB;IAMhB,gBAAgB;IAWhB,qBAAqB,CAAC,KAAK,EAAE,EAAE;IAI/B,UAAU;IAQJ,IAAI;IAUJ,IAAI;IAIV,MAAM,KAAK,MAAM;;;;;;;;;;;;OAOhB;IAED,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM;CAK3B"}
@@ -10,6 +10,8 @@ export class ContractClassLog {
10
10
  contractAddress;
11
11
  fields;
12
12
  static SIZE_IN_BYTES = Fr.SIZE_IN_BYTES * CONTRACT_CLASS_LOG_SIZE_IN_FIELDS;
13
+ // Keeps original first field pre-siloing. Only set by silo().
14
+ unsiloedFirstField;
13
15
  // Below line gives error 'Type instantiation is excessively deep and possibly infinite. ts(2589)'
14
16
  // public fields: Tuple<Fr, typeof CONTRACT_CLASS_LOG_DATA_SIZE_IN_FIELDS>
15
17
  constructor(contractAddress, fields){
@@ -84,8 +86,32 @@ export class ContractClassLog {
84
86
  }
85
87
  return this.fields.slice(0, lastZeroIndex);
86
88
  }
89
+ setUnsiloedFirstField(field) {
90
+ this.unsiloedFirstField = field;
91
+ }
92
+ toUnsiloed() {
93
+ if (this.unsiloedFirstField) {
94
+ return new ContractClassLog(this.contractAddress, [
95
+ this.unsiloedFirstField
96
+ ].concat(this.fields.slice(1)));
97
+ } else {
98
+ return this;
99
+ }
100
+ }
101
+ async silo() {
102
+ const innerLog = this.clone();
103
+ if (innerLog.contractAddress.isZero()) {
104
+ return innerLog;
105
+ }
106
+ innerLog.setUnsiloedFirstField(innerLog.fields[0]);
107
+ innerLog.fields[0] = await poseidon2Hash([
108
+ innerLog.contractAddress,
109
+ innerLog.fields[0]
110
+ ]);
111
+ return innerLog;
112
+ }
87
113
  async hash() {
88
- return await poseidon2Hash(this.getEmittedFields());
114
+ return await poseidon2Hash(this.fields);
89
115
  }
90
116
  static get schema() {
91
117
  return z.object({
@@ -18,7 +18,7 @@ export class L2ToL1Message {
18
18
  return z.object({
19
19
  recipient: schemas.EthAddress,
20
20
  content: schemas.Fr,
21
- counter: z.number()
21
+ counter: z.number().int().nonnegative()
22
22
  }).transform(({ recipient, content, counter })=>new L2ToL1Message(recipient, content, counter));
23
23
  }
24
24
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tx.d.ts","sourceRoot":"","sources":["../../src/tx/tx.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tx.d.ts","sourceRoot":"","sources":["../../src/tx/tx.ts"],"names":[],"mappings":"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"}
package/dest/tx/tx.js CHANGED
@@ -3,7 +3,6 @@ import { arraySerializedSizeOfNonEmpty } from '@aztec/foundation/collection';
3
3
  import { Fr } from '@aztec/foundation/fields';
4
4
  import { BufferReader, serializeArrayOfBufferableToVector, serializeToBuffer } from '@aztec/foundation/serialize';
5
5
  import { z } from 'zod';
6
- import { siloContractClassLog } from '../hash/hash.js';
7
6
  import { PrivateKernelTailCircuitPublicInputs } from '../kernel/private_kernel_tail_circuit_public_inputs.js';
8
7
  import { ContractClassLog } from '../logs/contract_class_log.js';
9
8
  import { PrivateLog } from '../logs/private_log.js';
@@ -135,9 +134,9 @@ import { TxHash } from './tx_hash.js';
135
134
  const contractClassLogs = [];
136
135
  for (const log of this.contractClassLogs){
137
136
  const hashedLog = await log.hash();
138
- const logHash = logHashes.find((hash)=>hash.value.equals(hashedLog));
137
+ const logHash = logHashes.find((hash)=>hash.value.equals(hashedLog) && hash.contractAddress.equals(log.contractAddress));
139
138
  if (logHash) {
140
- contractClassLogs.push(silo ? await siloContractClassLog(log, logHash.contractAddress) : log);
139
+ contractClassLogs.push(silo ? await log.silo() : log);
141
140
  }
142
141
  }
143
142
  return contractClassLogs;
@@ -46,7 +46,7 @@ import { TxHash } from './tx_hash.js';
46
46
  status: z.nativeEnum(TxStatus),
47
47
  error: z.string(),
48
48
  blockHash: L2BlockHash.schema.optional(),
49
- blockNumber: z.number().optional(),
49
+ blockNumber: z.number().int().nonnegative().optional(),
50
50
  transactionFee: schemas.BigInt.optional(),
51
51
  debugInfo: DebugInfoSchema.optional()
52
52
  }).transform(TxReceipt.from);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/stdlib",
3
- "version": "0.77.0-testnet-ignition.30",
3
+ "version": "0.77.0",
4
4
  "type": "module",
5
5
  "inherits": [
6
6
  "../package.common.json",
@@ -46,7 +46,8 @@
46
46
  "./interfaces/server": "./dest/interfaces/server.js",
47
47
  "./epoch-helpers": "./dest/epoch-helpers/index.js",
48
48
  "./config": "./dest/config/index.js",
49
- "./testing/jest": "./dest/tests/jest.js"
49
+ "./testing/jest": "./dest/tests/jest.js",
50
+ "./database-version": "./dest/database-version/index.js"
50
51
  },
51
52
  "typedocOptions": {
52
53
  "entryPoints": [
@@ -65,11 +66,11 @@
65
66
  "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
66
67
  },
67
68
  "dependencies": {
68
- "@aztec/bb.js": "0.77.0-testnet-ignition.30",
69
- "@aztec/blob-lib": "0.77.0-testnet-ignition.30",
70
- "@aztec/constants": "0.77.0-testnet-ignition.30",
71
- "@aztec/ethereum": "0.77.0-testnet-ignition.30",
72
- "@aztec/foundation": "0.77.0-testnet-ignition.30",
69
+ "@aztec/bb.js": "0.77.0",
70
+ "@aztec/blob-lib": "0.77.0",
71
+ "@aztec/constants": "0.77.0",
72
+ "@aztec/ethereum": "0.77.0",
73
+ "@aztec/foundation": "0.77.0",
73
74
  "lodash.chunk": "^4.2.0",
74
75
  "lodash.isequal": "^4.5.0",
75
76
  "lodash.omit": "^4.5.0",
@@ -22,7 +22,7 @@ export type ContractInstanceUpdateWithAddress = ContractInstanceUpdate & { addre
22
22
  export const ContractInstanceUpdateSchema = z.object({
23
23
  prevContractClassId: schemas.Fr,
24
24
  newContractClassId: schemas.Fr,
25
- blockOfChange: z.number(),
25
+ blockOfChange: z.number().int().nonnegative(),
26
26
  }) satisfies ZodFor<ContractInstanceUpdate>;
27
27
 
28
28
  export const ContractInstanceUpdateWithAddressSchema = ContractInstanceUpdateSchema.and(
@@ -24,8 +24,8 @@ export interface NodeInfo {
24
24
  export const NodeInfoSchema: ZodFor<NodeInfo> = z
25
25
  .object({
26
26
  nodeVersion: z.string(),
27
- l1ChainId: z.number(),
28
- protocolVersion: z.number(),
27
+ l1ChainId: z.number().int().nonnegative(),
28
+ protocolVersion: z.number().int().nonnegative(),
29
29
  enr: z.string().optional(),
30
30
  l1ContractAddresses: L1ContractAddressesSchema,
31
31
  protocolContractAddresses: ProtocolContractAddressesSchema,
@@ -0,0 +1,63 @@
1
+ # Version Manager
2
+
3
+ The Version Manager helps manage database migrations and version compatibility across different versions of the software.
4
+
5
+ ## Features
6
+
7
+ - Track database schema versions
8
+ - Handle migrations between versions
9
+ - Reset database when necessary (incompatible versions, rollup address change)
10
+ - Simple, clean API for version management
11
+
12
+ ## Usage
13
+
14
+ ```typescript
15
+ import { EthAddress } from '@aztec/foundation/eth-address';
16
+ import { version } from '@aztec/foundation';
17
+
18
+ // Define your current database version
19
+ const DB_VERSION = 3;
20
+ const rollupAddress = EthAddress.fromString('0x1234567890123456789012345678901234567890');
21
+
22
+ // Create version manager for your service
23
+ const versionManager = new version.VersionManager(DB_VERSION, rollupAddress, {
24
+ dataDir: '/path/to/data',
25
+ serviceName: 'my-database',
26
+ });
27
+
28
+ // When initializing your database
29
+ await versionManager.checkVersionAndHandle(
30
+ // Called when a reset is needed
31
+ async () => {
32
+ // Initialize a fresh database
33
+ await initializeFreshDatabase();
34
+ },
35
+ // Called when an upgrade is needed (optional)
36
+ async (oldVersion, newVersion) => {
37
+ if (oldVersion === 1 && newVersion === 2) {
38
+ // Migrate from version 1 to 2
39
+ await migrateV1ToV2();
40
+ } else if (oldVersion === 2 && newVersion === 3) {
41
+ // Migrate from version 2 to 3
42
+ await migrateV2ToV3();
43
+ } else {
44
+ // Unsupported migration path, will fall back to reset
45
+ throw new Error(`Cannot upgrade from ${oldVersion} to ${newVersion}`);
46
+ }
47
+ }
48
+ );
49
+
50
+ // Get the data directory for your service
51
+ const dataDir = versionManager.getDataDirectory();
52
+ ```
53
+
54
+ ## Automatic Reset Conditions
55
+
56
+ The database will be reset in the following conditions:
57
+
58
+ 1. No version information exists (first run)
59
+ 2. Rollup address has changed
60
+ 3. Version has changed and no upgrade callback is provided
61
+ 4. Upgrade callback throws an error
62
+
63
+ When a reset occurs, the data directory is deleted and recreated, and the reset callback is called to initialize a fresh database.
@@ -0,0 +1 @@
1
+ export * from './version_manager.js';
@@ -0,0 +1,207 @@
1
+ import { EthAddress } from '@aztec/foundation/eth-address';
2
+ import { jsonParseWithSchemaSync, jsonStringify } from '@aztec/foundation/json-rpc';
3
+ import { createLogger } from '@aztec/foundation/log';
4
+
5
+ import fs from 'fs/promises';
6
+ import { join } from 'path';
7
+ import { z } from 'zod';
8
+
9
+ /**
10
+ * Represents a version record for storing in a version file.
11
+ */
12
+ export class DatabaseVersion {
13
+ constructor(public readonly schemaVersion: number, public readonly rollupAddress: EthAddress) {}
14
+
15
+ public toBuffer(): Buffer {
16
+ return Buffer.from(jsonStringify(this));
17
+ }
18
+
19
+ public static fromBuffer(buf: Buffer): DatabaseVersion {
20
+ try {
21
+ return jsonParseWithSchemaSync(buf.toString('utf-8'), DatabaseVersion.schema);
22
+ } catch (err) {
23
+ throw new Error(`Failed to deserialize version information: ${err}`, { cause: err });
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Compares two versions. If the rollups addresses are different then it returns undefined
29
+ */
30
+ public cmp(other: DatabaseVersion): undefined | -1 | 0 | 1 {
31
+ if (this.rollupAddress.equals(other.rollupAddress)) {
32
+ if (this.schemaVersion < other.schemaVersion) {
33
+ return -1;
34
+ } else if (this.schemaVersion > other.schemaVersion) {
35
+ return 1;
36
+ } else {
37
+ return 0;
38
+ }
39
+ }
40
+ return undefined;
41
+ }
42
+
43
+ /**
44
+ * Checks if two versions exactly match
45
+ */
46
+ public equals(other: DatabaseVersion): boolean {
47
+ return this.cmp(other) === 0;
48
+ }
49
+
50
+ /**
51
+ * Returns the schema for this class
52
+ */
53
+ static get schema() {
54
+ return z
55
+ .object({
56
+ schemaVersion: z.number(),
57
+ rollupAddress: EthAddress.schema,
58
+ })
59
+ .transform(({ schemaVersion, rollupAddress }) => new DatabaseVersion(schemaVersion, rollupAddress));
60
+ }
61
+
62
+ /**
63
+ * Returns an empty instance
64
+ */
65
+ static empty() {
66
+ return new DatabaseVersion(0, EthAddress.ZERO);
67
+ }
68
+ }
69
+
70
+ export type DatabaseVersionManagerFs = Pick<typeof fs, 'readFile' | 'writeFile' | 'rm' | 'mkdir'>;
71
+
72
+ /**
73
+ * A manager for handling database versioning and migrations.
74
+ * This class will check the version of data in a directory and either
75
+ * reset or upgrade based on version compatibility.
76
+ */
77
+ export class DatabaseVersionManager<T> {
78
+ public static readonly VERSION_FILE = 'db_version';
79
+
80
+ private readonly versionFile: string;
81
+ private readonly currentVersion: DatabaseVersion;
82
+
83
+ /**
84
+ * Create a new version manager
85
+ *
86
+ * @param schemaVersion - The current version of the application
87
+ * @param rollupAddress - The rollup contract address
88
+ * @param dataDirectory - The directory where version information will be stored
89
+ * @param onOpen - A callback to the open the database at the given location
90
+ * @param onUpgrade - An optional callback to upgrade the database before opening. If not provided it will reset the database
91
+ * @param fileSystem - An interface to access the filesystem
92
+ * @param log - Optional custom logger
93
+ * @param options - Configuration options
94
+ */
95
+ constructor(
96
+ schemaVersion: number,
97
+ rollupAddress: EthAddress,
98
+ private dataDirectory: string,
99
+ private onOpen: (dataDir: string) => Promise<T>,
100
+ private onUpgrade?: (dataDir: string, currentVersion: number, latestVersion: number) => Promise<void>,
101
+ private fileSystem: DatabaseVersionManagerFs = fs,
102
+ private log = createLogger(`foundation:version-manager`),
103
+ ) {
104
+ if (schemaVersion < 1) {
105
+ throw new TypeError(`Invalid schema version received: ${schemaVersion}`);
106
+ }
107
+
108
+ this.versionFile = join(this.dataDirectory, DatabaseVersionManager.VERSION_FILE);
109
+ this.currentVersion = new DatabaseVersion(schemaVersion, rollupAddress);
110
+ }
111
+
112
+ /**
113
+ * Checks the stored version against the current version and handles the outcome
114
+ * by either resetting the data directory or calling an upgrade function
115
+ *
116
+ * @param onReset - Function to call when a full reset is needed
117
+ * @param onUpgrade - Function to call when an upgrade is needed
118
+ * @returns True if data was reset, false if upgraded or no change needed
119
+ */
120
+ public async open(): Promise<[T, boolean]> {
121
+ // const storedVersion = await DatabaseVersion.readVersion(this.versionFile);
122
+ let storedVersion: DatabaseVersion;
123
+
124
+ try {
125
+ const versionBuf = await this.fileSystem.readFile(this.versionFile);
126
+ storedVersion = DatabaseVersion.fromBuffer(versionBuf);
127
+ } catch (err) {
128
+ if (err && (err as Error & { code: string }).code === 'ENOENT') {
129
+ storedVersion = DatabaseVersion.empty();
130
+ } else {
131
+ this.log.warn(`Failed to read stored version information: ${err}. Defaulting to empty version`);
132
+ storedVersion = DatabaseVersion.empty();
133
+ }
134
+ }
135
+
136
+ const cmp = storedVersion.cmp(this.currentVersion);
137
+ let needsReset = false;
138
+
139
+ if (typeof cmp === 'number') {
140
+ // only allow forward upgrades
141
+ if (cmp === -1 && this.onUpgrade) {
142
+ this.log.info(`Upgrading from version ${storedVersion.schemaVersion} to ${this.currentVersion.schemaVersion}`);
143
+ try {
144
+ await this.onUpgrade(this.dataDirectory, storedVersion.schemaVersion, this.currentVersion.schemaVersion);
145
+ } catch (error) {
146
+ this.log.error(`Failed to upgrade: ${error}. Falling back to reset.`);
147
+ needsReset = true;
148
+ }
149
+ } else if (cmp !== 0) {
150
+ this.log.info(
151
+ `Can't upgrade from version ${storedVersion.schemaVersion} to ${this.currentVersion}. Resetting database at ${this.dataDirectory}`,
152
+ );
153
+ needsReset = true;
154
+ }
155
+ } else {
156
+ this.log.warn('Rollup address changed, resetting data directory');
157
+ needsReset = true;
158
+ }
159
+
160
+ // Handle reset if needed
161
+ if (needsReset) {
162
+ await this.resetDataDirectory();
163
+ }
164
+
165
+ // Write the current version to disk
166
+ await this.writeVersion();
167
+
168
+ return [await this.onOpen(this.dataDirectory), needsReset];
169
+ }
170
+
171
+ /**
172
+ * Writes the current version to the version file
173
+ */
174
+ private async writeVersion(): Promise<void> {
175
+ // Ensure the directory exists
176
+ await this.fileSystem.mkdir(this.dataDirectory, { recursive: true });
177
+ // Write the version file
178
+ await this.fileSystem.writeFile(this.versionFile, this.currentVersion.toBuffer());
179
+ }
180
+
181
+ /**
182
+ * Resets the data directory by deleting it and recreating it
183
+ */
184
+ private async resetDataDirectory(): Promise<void> {
185
+ try {
186
+ await this.fileSystem.rm(this.dataDirectory, { recursive: true, force: true, maxRetries: 3 });
187
+ await this.fileSystem.mkdir(this.dataDirectory, { recursive: true });
188
+ } catch (err) {
189
+ this.log.error(`Failed to reset data directory: ${err}`);
190
+ throw new Error(`Failed to reset data directory: ${err}`, { cause: err });
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Get the data directory path
196
+ */
197
+ public getDataDirectory(): string {
198
+ return this.dataDirectory;
199
+ }
200
+
201
+ /**
202
+ * Get the current version number
203
+ */
204
+ public getSchemaVersion(): number {
205
+ return this.currentVersion.schemaVersion;
206
+ }
207
+ }
@@ -57,8 +57,8 @@ export interface SourceCodeLocation {
57
57
 
58
58
  const SourceCodeLocationSchema = z.object({
59
59
  filePath: z.string(),
60
- line: z.number(),
61
- column: z.number(),
60
+ line: z.number().int().nonnegative(),
61
+ column: z.number().int().nonnegative(),
62
62
  fileSource: z.string(),
63
63
  locationText: z.string(),
64
64
  });
package/src/hash/hash.ts CHANGED
@@ -3,7 +3,6 @@ import { poseidon2Hash, poseidon2HashWithSeparator, sha256Trunc } from '@aztec/f
3
3
  import { Fr } from '@aztec/foundation/fields';
4
4
 
5
5
  import type { AztecAddress } from '../aztec-address/index.js';
6
- import type { ContractClassLog } from '../logs/index.js';
7
6
  import type { ScopedL2ToL1Message } from '../messaging/l2_to_l1_message.js';
8
7
 
9
8
  /**
@@ -132,12 +131,3 @@ export function siloL2ToL1Message(l2ToL1Message: ScopedL2ToL1Message, version: F
132
131
  ]);
133
132
  return Fr.fromBuffer(sha256Trunc(preimage));
134
133
  }
135
-
136
- export async function siloContractClassLog(log: ContractClassLog, contract: AztecAddress): Promise<ContractClassLog> {
137
- const innerLog = log.clone();
138
- if (contract.isZero()) {
139
- return innerLog;
140
- }
141
- innerLog.fields[0] = await poseidon2Hash([contract, innerLog.fields[0]]);
142
- return innerLog;
143
- }
@@ -76,9 +76,9 @@ export interface WorldStateSynchronizer extends ForkMerkleTreeOperations {
76
76
  }
77
77
 
78
78
  export const WorldStateSyncStatusSchema = z.object({
79
- finalisedBlockNumber: z.number(),
80
- latestBlockNumber: z.number(),
79
+ finalisedBlockNumber: z.number().int().nonnegative(),
80
+ latestBlockNumber: z.number().int().nonnegative(),
81
81
  latestBlockHash: z.string(),
82
- oldestHistoricBlockNumber: z.number(),
82
+ oldestHistoricBlockNumber: z.number().int().nonnegative(),
83
83
  treesAreSynched: z.boolean(),
84
84
  }) satisfies z.ZodType<WorldStateSyncStatus>;
@@ -11,6 +11,8 @@ import { AztecAddress } from '../aztec-address/index.js';
11
11
 
12
12
  export class ContractClassLog {
13
13
  static SIZE_IN_BYTES = Fr.SIZE_IN_BYTES * CONTRACT_CLASS_LOG_SIZE_IN_FIELDS;
14
+ // Keeps original first field pre-siloing. Only set by silo().
15
+ public unsiloedFirstField?: Fr | undefined;
14
16
 
15
17
  // Below line gives error 'Type instantiation is excessively deep and possibly infinite. ts(2589)'
16
18
  // public fields: Tuple<Fr, typeof CONTRACT_CLASS_LOG_DATA_SIZE_IN_FIELDS>
@@ -91,8 +93,30 @@ export class ContractClassLog {
91
93
  return this.fields.slice(0, lastZeroIndex);
92
94
  }
93
95
 
96
+ setUnsiloedFirstField(field: Fr) {
97
+ this.unsiloedFirstField = field;
98
+ }
99
+
100
+ toUnsiloed() {
101
+ if (this.unsiloedFirstField) {
102
+ return new ContractClassLog(this.contractAddress, [this.unsiloedFirstField].concat(this.fields.slice(1)));
103
+ } else {
104
+ return this;
105
+ }
106
+ }
107
+
108
+ async silo() {
109
+ const innerLog = this.clone();
110
+ if (innerLog.contractAddress.isZero()) {
111
+ return innerLog;
112
+ }
113
+ innerLog.setUnsiloedFirstField(innerLog.fields[0]);
114
+ innerLog.fields[0] = await poseidon2Hash([innerLog.contractAddress, innerLog.fields[0]]);
115
+ return innerLog;
116
+ }
117
+
94
118
  async hash() {
95
- return await poseidon2Hash(this.getEmittedFields());
119
+ return await poseidon2Hash(this.fields);
96
120
  }
97
121
 
98
122
  static get schema() {
@@ -17,7 +17,7 @@ export class L2ToL1Message {
17
17
  .object({
18
18
  recipient: schemas.EthAddress,
19
19
  content: schemas.Fr,
20
- counter: z.number(),
20
+ counter: z.number().int().nonnegative(),
21
21
  })
22
22
  .transform(({ recipient, content, counter }) => new L2ToL1Message(recipient, content, counter));
23
23
  }
package/src/tx/tx.ts CHANGED
@@ -8,7 +8,6 @@ import type { FieldsOf } from '@aztec/foundation/types';
8
8
  import { z } from 'zod';
9
9
 
10
10
  import type { GasSettings } from '../gas/gas_settings.js';
11
- import { siloContractClassLog } from '../hash/hash.js';
12
11
  import type { GetPublicLogsResponse } from '../interfaces/get_logs_response.js';
13
12
  import type { L2LogsSource } from '../interfaces/l2_logs_source.js';
14
13
  import type { ScopedLogHash } from '../kernel/log_hash.js';
@@ -197,9 +196,11 @@ export class Tx extends Gossipable {
197
196
  const contractClassLogs = [];
198
197
  for (const log of this.contractClassLogs) {
199
198
  const hashedLog = await log.hash();
200
- const logHash = logHashes.find(hash => hash.value.equals(hashedLog));
199
+ const logHash = logHashes.find(
200
+ hash => hash.value.equals(hashedLog) && hash.contractAddress.equals(log.contractAddress),
201
+ );
201
202
  if (logHash) {
202
- contractClassLogs.push(silo ? await siloContractClassLog(log, logHash.contractAddress) : log);
203
+ contractClassLogs.push(silo ? await log.silo() : log);
203
204
  }
204
205
  }
205
206
  return contractClassLogs;
@@ -56,7 +56,7 @@ export class TxReceipt {
56
56
  status: z.nativeEnum(TxStatus),
57
57
  error: z.string(),
58
58
  blockHash: L2BlockHash.schema.optional(),
59
- blockNumber: z.number().optional(),
59
+ blockNumber: z.number().int().nonnegative().optional(),
60
60
  transactionFee: schemas.BigInt.optional(),
61
61
  debugInfo: DebugInfoSchema.optional(),
62
62
  })