@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.
- package/dest/contract/interfaces/contract_instance_update.js +1 -1
- package/dest/contract/interfaces/node-info.js +2 -2
- package/dest/database-version/index.d.ts +2 -0
- package/dest/database-version/index.d.ts.map +1 -0
- package/dest/database-version/index.js +1 -0
- package/dest/database-version/version_manager.d.ts +99 -0
- package/dest/database-version/version_manager.d.ts.map +1 -0
- package/dest/database-version/version_manager.js +188 -0
- package/dest/errors/simulation_error.js +2 -2
- package/dest/hash/hash.d.ts +0 -2
- package/dest/hash/hash.d.ts.map +1 -1
- package/dest/hash/hash.js +0 -11
- package/dest/interfaces/world_state.js +3 -3
- package/dest/logs/contract_class_log.d.ts +4 -0
- package/dest/logs/contract_class_log.d.ts.map +1 -1
- package/dest/logs/contract_class_log.js +27 -1
- package/dest/messaging/l2_to_l1_message.js +1 -1
- package/dest/tx/tx.d.ts.map +1 -1
- package/dest/tx/tx.js +2 -3
- package/dest/tx/tx_receipt.js +1 -1
- package/package.json +8 -7
- package/src/contract/interfaces/contract_instance_update.ts +1 -1
- package/src/contract/interfaces/node-info.ts +2 -2
- package/src/database-version/README.md +63 -0
- package/src/database-version/index.ts +1 -0
- package/src/database-version/version_manager.ts +207 -0
- package/src/errors/simulation_error.ts +2 -2
- package/src/hash/hash.ts +0 -10
- package/src/interfaces/world_state.ts +3 -3
- package/src/logs/contract_class_log.ts +25 -1
- package/src/messaging/l2_to_l1_message.ts +1 -1
- package/src/tx/tx.ts +4 -3
- 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 @@
|
|
|
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
|
});
|
package/dest/hash/hash.d.ts
CHANGED
|
@@ -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
|
package/dest/hash/hash.d.ts.map
CHANGED
|
@@ -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,
|
|
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;
|
|
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.
|
|
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
|
/**
|
package/dest/tx/tx.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tx.d.ts","sourceRoot":"","sources":["../../src/tx/tx.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAGpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAyD,MAAM,6BAA6B,CAAC;AAClH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAIxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;
|
|
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
|
|
139
|
+
contractClassLogs.push(silo ? await log.silo() : log);
|
|
141
140
|
}
|
|
142
141
|
}
|
|
143
142
|
return contractClassLogs;
|
package/dest/tx/tx_receipt.js
CHANGED
|
@@ -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
|
|
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
|
|
69
|
-
"@aztec/blob-lib": "0.77.0
|
|
70
|
-
"@aztec/constants": "0.77.0
|
|
71
|
-
"@aztec/ethereum": "0.77.0
|
|
72
|
-
"@aztec/foundation": "0.77.0
|
|
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.
|
|
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(
|
|
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
|
|
203
|
+
contractClassLogs.push(silo ? await log.silo() : log);
|
|
203
204
|
}
|
|
204
205
|
}
|
|
205
206
|
return contractClassLogs;
|
package/src/tx/tx_receipt.ts
CHANGED
|
@@ -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
|
})
|