@aztec/stdlib 0.82.2 → 0.82.3
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/avm/avm.d.ts +919 -1252
- package/dest/avm/avm.d.ts.map +1 -1
- package/dest/avm/avm.js +138 -111
- package/dest/avm/avm_proving_request.d.ts +400 -575
- package/dest/avm/avm_proving_request.d.ts.map +1 -1
- package/dest/block/l2_block_downloader/l2_block_stream.d.ts +1 -0
- package/dest/block/l2_block_downloader/l2_block_stream.d.ts.map +1 -1
- package/dest/block/l2_block_downloader/l2_block_stream.js +6 -0
- package/dest/database-version/version_manager.d.ts +4 -2
- package/dest/database-version/version_manager.d.ts.map +1 -1
- package/dest/database-version/version_manager.js +13 -9
- package/dest/epoch-helpers/index.d.ts +2 -0
- package/dest/epoch-helpers/index.d.ts.map +1 -1
- package/dest/epoch-helpers/index.js +3 -0
- package/dest/file-store/factory.d.ts +7 -0
- package/dest/file-store/factory.d.ts.map +1 -0
- package/dest/file-store/factory.js +46 -0
- package/dest/file-store/gcs.d.ts +22 -0
- package/dest/file-store/gcs.d.ts.map +1 -0
- package/dest/file-store/gcs.js +115 -0
- package/dest/file-store/http.d.ts +15 -0
- package/dest/file-store/http.d.ts.map +1 -0
- package/dest/file-store/http.js +53 -0
- package/dest/file-store/index.d.ts +3 -0
- package/dest/file-store/index.d.ts.map +1 -0
- package/dest/file-store/index.js +2 -0
- package/dest/file-store/interface.d.ts +24 -0
- package/dest/file-store/interface.d.ts.map +1 -0
- package/dest/file-store/interface.js +1 -0
- package/dest/file-store/local.d.ts +16 -0
- package/dest/file-store/local.d.ts.map +1 -0
- package/dest/file-store/local.js +40 -0
- package/dest/interfaces/aztec-node-admin.d.ts +9 -1
- package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
- package/dest/interfaces/aztec-node-admin.js +2 -1
- package/dest/interfaces/aztec-node.d.ts +3 -0
- package/dest/interfaces/aztec-node.d.ts.map +1 -1
- package/dest/interfaces/aztec-node.js +2 -0
- package/dest/interfaces/p2p.d.ts +2 -0
- package/dest/interfaces/p2p.d.ts.map +1 -1
- package/dest/interfaces/p2p.js +2 -1
- package/dest/interfaces/prover-node.d.ts +4 -0
- package/dest/interfaces/prover-node.d.ts.map +1 -1
- package/dest/interfaces/prover-node.js +5 -1
- package/dest/interfaces/proving-job.d.ts +400 -575
- package/dest/interfaces/proving-job.d.ts.map +1 -1
- package/dest/interfaces/service.d.ts +3 -0
- package/dest/interfaces/service.d.ts.map +1 -1
- package/dest/interfaces/service.js +7 -0
- package/dest/interfaces/world_state.d.ts +13 -15
- package/dest/interfaces/world_state.d.ts.map +1 -1
- package/dest/snapshots/download.d.ts +9 -0
- package/dest/snapshots/download.d.ts.map +1 -0
- package/dest/snapshots/download.js +37 -0
- package/dest/snapshots/index.d.ts +4 -0
- package/dest/snapshots/index.d.ts.map +1 -0
- package/dest/snapshots/index.js +3 -0
- package/dest/snapshots/types.d.ts +97 -0
- package/dest/snapshots/types.d.ts.map +1 -0
- package/dest/snapshots/types.js +27 -0
- package/dest/snapshots/upload.d.ts +5 -0
- package/dest/snapshots/upload.d.ts.map +1 -0
- package/dest/snapshots/upload.js +37 -0
- package/dest/tests/factories.d.ts +13 -7
- package/dest/tests/factories.d.ts.map +1 -1
- package/dest/tests/factories.js +37 -25
- package/dest/trees/merkle_tree_id.d.ts +8 -0
- package/dest/trees/merkle_tree_id.d.ts.map +1 -1
- package/dest/trees/merkle_tree_id.js +10 -0
- package/dest/trees/nullifier_leaf.d.ts +11 -2
- package/dest/trees/nullifier_leaf.d.ts.map +1 -1
- package/dest/trees/nullifier_leaf.js +12 -7
- package/dest/trees/nullifier_membership_witness.d.ts +7 -7
- package/dest/trees/public_data_leaf.d.ts +13 -0
- package/dest/trees/public_data_leaf.d.ts.map +1 -1
- package/dest/trees/public_data_leaf.js +6 -0
- package/dest/trees/public_data_witness.d.ts +7 -7
- package/dest/validators/index.d.ts +3 -0
- package/dest/validators/index.d.ts.map +1 -0
- package/dest/validators/index.js +1 -0
- package/dest/validators/schemas.d.ts +342 -0
- package/dest/validators/schemas.d.ts.map +1 -0
- package/dest/validators/schemas.js +40 -0
- package/dest/validators/types.d.ts +39 -0
- package/dest/validators/types.d.ts.map +1 -0
- package/dest/validators/types.js +1 -0
- package/package.json +11 -7
- package/src/avm/avm.ts +131 -106
- package/src/block/l2_block_downloader/l2_block_stream.ts +6 -0
- package/src/database-version/version_manager.ts +12 -8
- package/src/epoch-helpers/index.ts +8 -0
- package/src/file-store/factory.ts +61 -0
- package/src/file-store/gcs.ts +121 -0
- package/src/file-store/http.ts +58 -0
- package/src/file-store/index.ts +2 -0
- package/src/file-store/interface.ts +19 -0
- package/src/file-store/local.ts +46 -0
- package/src/interfaces/aztec-node-admin.ts +11 -1
- package/src/interfaces/aztec-node.ts +7 -0
- package/src/interfaces/p2p.ts +4 -0
- package/src/interfaces/prover-node.ts +10 -0
- package/src/interfaces/service.ts +13 -0
- package/src/interfaces/world_state.ts +17 -15
- package/src/snapshots/download.ts +60 -0
- package/src/snapshots/index.ts +3 -0
- package/src/snapshots/types.ts +58 -0
- package/src/snapshots/upload.ts +53 -0
- package/src/tests/factories.ts +74 -54
- package/src/trees/merkle_tree_id.ts +12 -0
- package/src/trees/nullifier_leaf.ts +9 -5
- package/src/trees/public_data_leaf.ts +9 -0
- package/src/validators/index.ts +3 -0
- package/src/validators/schemas.ts +53 -0
- package/src/validators/types.ts +37 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/stdlib",
|
|
3
|
-
"version": "0.82.
|
|
3
|
+
"version": "0.82.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"inherits": [
|
|
6
6
|
"../package.common.json",
|
|
@@ -46,7 +46,10 @@
|
|
|
46
46
|
"./epoch-helpers": "./dest/epoch-helpers/index.js",
|
|
47
47
|
"./config": "./dest/config/index.js",
|
|
48
48
|
"./testing/jest": "./dest/tests/jest.js",
|
|
49
|
-
"./database-version": "./dest/database-version/index.js"
|
|
49
|
+
"./database-version": "./dest/database-version/index.js",
|
|
50
|
+
"./validators": "./dest/validators/index.js",
|
|
51
|
+
"./file-store": "./dest/file-store/index.js",
|
|
52
|
+
"./snapshots": "./dest/snapshots/index.js"
|
|
50
53
|
},
|
|
51
54
|
"typedocOptions": {
|
|
52
55
|
"entryPoints": [
|
|
@@ -65,11 +68,12 @@
|
|
|
65
68
|
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
|
|
66
69
|
},
|
|
67
70
|
"dependencies": {
|
|
68
|
-
"@aztec/bb.js": "0.82.
|
|
69
|
-
"@aztec/blob-lib": "0.82.
|
|
70
|
-
"@aztec/constants": "0.82.
|
|
71
|
-
"@aztec/ethereum": "0.82.
|
|
72
|
-
"@aztec/foundation": "0.82.
|
|
71
|
+
"@aztec/bb.js": "0.82.3",
|
|
72
|
+
"@aztec/blob-lib": "0.82.3",
|
|
73
|
+
"@aztec/constants": "0.82.3",
|
|
74
|
+
"@aztec/ethereum": "0.82.3",
|
|
75
|
+
"@aztec/foundation": "0.82.3",
|
|
76
|
+
"@google-cloud/storage": "^7.15.0",
|
|
73
77
|
"lodash.chunk": "^4.2.0",
|
|
74
78
|
"lodash.isequal": "^4.5.0",
|
|
75
79
|
"lodash.omit": "^4.5.0",
|
package/src/avm/avm.ts
CHANGED
|
@@ -1,39 +1,22 @@
|
|
|
1
1
|
import { Fr } from '@aztec/foundation/fields';
|
|
2
2
|
import { jsonParseWithSchema, jsonStringify } from '@aztec/foundation/json-rpc';
|
|
3
3
|
import { schemas } from '@aztec/foundation/schemas';
|
|
4
|
+
import type { IndexedTreeLeaf } from '@aztec/foundation/trees';
|
|
4
5
|
|
|
5
6
|
import { z } from 'zod';
|
|
6
7
|
|
|
7
8
|
import { AztecAddress } from '../aztec-address/index.js';
|
|
8
9
|
import { PublicKeys } from '../keys/public_keys.js';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
10
|
+
import { AppendOnlyTreeSnapshot } from '../trees/append_only_tree_snapshot.js';
|
|
11
|
+
import type { MerkleTreeId } from '../trees/merkle_tree_id.js';
|
|
12
|
+
import { NullifierLeaf } from '../trees/nullifier_leaf.js';
|
|
13
|
+
import { PublicDataTreeLeaf } from '../trees/public_data_leaf.js';
|
|
11
14
|
import { AvmCircuitPublicInputs } from './avm_circuit_public_inputs.js';
|
|
12
15
|
import { serializeWithMessagePack } from './message_pack.js';
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
public readonly contractAddress: AztecAddress,
|
|
18
|
-
public readonly calldata: Fr[],
|
|
19
|
-
public isStaticCall: boolean,
|
|
20
|
-
) {}
|
|
21
|
-
|
|
22
|
-
static get schema() {
|
|
23
|
-
return z
|
|
24
|
-
.object({
|
|
25
|
-
msgSender: AztecAddress.schema,
|
|
26
|
-
contractAddress: AztecAddress.schema,
|
|
27
|
-
calldata: schemas.Fr.array(),
|
|
28
|
-
isStaticCall: z.boolean(),
|
|
29
|
-
})
|
|
30
|
-
.transform(
|
|
31
|
-
({ msgSender, contractAddress, calldata, isStaticCall }) =>
|
|
32
|
-
new AvmEnqueuedCallHint(msgSender, contractAddress, calldata, isStaticCall),
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
17
|
+
////////////////////////////////////////////////////////////////////////////
|
|
18
|
+
// Hints (contracts)
|
|
19
|
+
////////////////////////////////////////////////////////////////////////////
|
|
37
20
|
export class AvmContractClassHint {
|
|
38
21
|
constructor(
|
|
39
22
|
public readonly classId: Fr,
|
|
@@ -115,97 +98,145 @@ export class AvmContractInstanceHint {
|
|
|
115
98
|
}
|
|
116
99
|
}
|
|
117
100
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export class AvmNullifierWriteTreeHint {
|
|
133
|
-
constructor(public lowLeafRead: AvmNullifierReadTreeHint, public readonly insertionPath: Fr[]) {}
|
|
101
|
+
////////////////////////////////////////////////////////////////////////////
|
|
102
|
+
// Hints (merkle db)
|
|
103
|
+
////////////////////////////////////////////////////////////////////////////
|
|
104
|
+
// Hint for MerkleTreeDB.getSiblingPath.
|
|
105
|
+
export class AvmGetSiblingPathHint {
|
|
106
|
+
constructor(
|
|
107
|
+
public readonly hintKey: AppendOnlyTreeSnapshot,
|
|
108
|
+
// params
|
|
109
|
+
public readonly treeId: MerkleTreeId,
|
|
110
|
+
public readonly index: bigint,
|
|
111
|
+
// return
|
|
112
|
+
public readonly path: Fr[],
|
|
113
|
+
) {}
|
|
134
114
|
|
|
135
115
|
static get schema() {
|
|
136
116
|
return z
|
|
137
117
|
.object({
|
|
138
|
-
|
|
139
|
-
|
|
118
|
+
hintKey: AppendOnlyTreeSnapshot.schema,
|
|
119
|
+
treeId: z.number().int().nonnegative(),
|
|
120
|
+
index: schemas.BigInt,
|
|
121
|
+
path: schemas.Fr.array(),
|
|
140
122
|
})
|
|
141
|
-
.transform(({
|
|
123
|
+
.transform(({ hintKey, treeId, index, path }) => new AvmGetSiblingPathHint(hintKey, treeId, index, path));
|
|
142
124
|
}
|
|
143
125
|
}
|
|
144
126
|
|
|
145
|
-
|
|
127
|
+
// Hint for MerkleTreeDB.getPreviousValueIndex.
|
|
128
|
+
export class AvmGetPreviousValueIndexHint {
|
|
146
129
|
constructor(
|
|
147
|
-
public readonly
|
|
148
|
-
|
|
149
|
-
public readonly
|
|
130
|
+
public readonly hintKey: AppendOnlyTreeSnapshot,
|
|
131
|
+
// params
|
|
132
|
+
public readonly treeId: MerkleTreeId,
|
|
133
|
+
public readonly value: Fr,
|
|
134
|
+
// return
|
|
135
|
+
public readonly index: bigint,
|
|
136
|
+
public readonly alreadyPresent: boolean,
|
|
150
137
|
) {}
|
|
151
138
|
|
|
152
139
|
static get schema() {
|
|
153
140
|
return z
|
|
154
141
|
.object({
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
142
|
+
hintKey: AppendOnlyTreeSnapshot.schema,
|
|
143
|
+
treeId: z.number().int().nonnegative(),
|
|
144
|
+
value: schemas.Fr,
|
|
145
|
+
index: schemas.BigInt,
|
|
146
|
+
alreadyPresent: z.boolean(),
|
|
158
147
|
})
|
|
159
148
|
.transform(
|
|
160
|
-
({
|
|
161
|
-
new
|
|
149
|
+
({ hintKey, treeId, value, index, alreadyPresent }) =>
|
|
150
|
+
new AvmGetPreviousValueIndexHint(hintKey, treeId, value, index, alreadyPresent),
|
|
162
151
|
);
|
|
163
152
|
}
|
|
164
153
|
}
|
|
165
154
|
|
|
166
|
-
|
|
155
|
+
// Hint for MerkleTreeDB.getLeafPreimage.
|
|
156
|
+
// NOTE: I need this factory because in order to get hold of the schema, I need an actual instance of the class,
|
|
157
|
+
// having the type doesn't suffice since TS does type erasure in the end.
|
|
158
|
+
function AvmGetLeafPreimageHintFactory<T extends IndexedTreeLeaf>(klass: {
|
|
159
|
+
schema: z.ZodSchema;
|
|
160
|
+
new (...args: any[]): T;
|
|
161
|
+
}) {
|
|
162
|
+
return class AvmGetLeafPreimageHint {
|
|
163
|
+
constructor(
|
|
164
|
+
public readonly hintKey: AppendOnlyTreeSnapshot,
|
|
165
|
+
// params (tree id will be implicit)
|
|
166
|
+
public readonly index: bigint,
|
|
167
|
+
// return
|
|
168
|
+
public readonly leaf: T,
|
|
169
|
+
public readonly nextIndex: bigint,
|
|
170
|
+
public readonly nextValue: Fr,
|
|
171
|
+
) {}
|
|
172
|
+
|
|
173
|
+
static get schema() {
|
|
174
|
+
return z
|
|
175
|
+
.object({
|
|
176
|
+
hintKey: AppendOnlyTreeSnapshot.schema,
|
|
177
|
+
index: schemas.BigInt,
|
|
178
|
+
leaf: klass.schema,
|
|
179
|
+
nextIndex: schemas.BigInt,
|
|
180
|
+
nextValue: schemas.Fr,
|
|
181
|
+
})
|
|
182
|
+
.transform(
|
|
183
|
+
({ hintKey, index, leaf, nextIndex, nextValue }) =>
|
|
184
|
+
new AvmGetLeafPreimageHint(hintKey, index, leaf, nextIndex, nextValue),
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Note: only supported for PUBLIC_DATA_TREE and NULLIFIER_TREE.
|
|
191
|
+
export class AvmGetLeafPreimageHintPublicDataTree extends AvmGetLeafPreimageHintFactory(PublicDataTreeLeaf) {}
|
|
192
|
+
export class AvmGetLeafPreimageHintNullifierTree extends AvmGetLeafPreimageHintFactory(NullifierLeaf) {}
|
|
193
|
+
|
|
194
|
+
// Hint for MerkleTreeDB.getLeafValue.
|
|
195
|
+
// Note: only supported for NOTE_HASH_TREE and L1_TO_L2_MESSAGE_TREE.
|
|
196
|
+
export class AvmGetLeafValueHint {
|
|
167
197
|
constructor(
|
|
168
|
-
public readonly
|
|
169
|
-
|
|
170
|
-
public readonly
|
|
198
|
+
public readonly hintKey: AppendOnlyTreeSnapshot,
|
|
199
|
+
// params
|
|
200
|
+
public readonly treeId: MerkleTreeId,
|
|
201
|
+
public readonly index: bigint,
|
|
202
|
+
// return
|
|
203
|
+
public readonly value: Fr,
|
|
171
204
|
) {}
|
|
172
205
|
|
|
173
|
-
static empty() {
|
|
174
|
-
return new AvmPublicDataReadTreeHint(PublicDataTreeLeafPreimage.empty(), Fr.ZERO, []);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
206
|
static get schema() {
|
|
178
207
|
return z
|
|
179
208
|
.object({
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
209
|
+
hintKey: AppendOnlyTreeSnapshot.schema,
|
|
210
|
+
treeId: z.number().int().nonnegative(),
|
|
211
|
+
index: schemas.BigInt,
|
|
212
|
+
value: schemas.Fr,
|
|
183
213
|
})
|
|
184
|
-
.transform(
|
|
185
|
-
({ leafPreimage, leafIndex, siblingPath }) =>
|
|
186
|
-
new AvmPublicDataReadTreeHint(leafPreimage, leafIndex, siblingPath),
|
|
187
|
-
);
|
|
214
|
+
.transform(({ hintKey, treeId, index, value }) => new AvmGetLeafValueHint(hintKey, treeId, index, value));
|
|
188
215
|
}
|
|
189
216
|
}
|
|
190
217
|
|
|
191
|
-
|
|
218
|
+
////////////////////////////////////////////////////////////////////////////
|
|
219
|
+
// Hints (other)
|
|
220
|
+
////////////////////////////////////////////////////////////////////////////
|
|
221
|
+
export class AvmEnqueuedCallHint {
|
|
192
222
|
constructor(
|
|
193
|
-
|
|
194
|
-
public readonly
|
|
195
|
-
public readonly
|
|
196
|
-
public
|
|
223
|
+
public readonly msgSender: AztecAddress,
|
|
224
|
+
public readonly contractAddress: AztecAddress,
|
|
225
|
+
public readonly calldata: Fr[],
|
|
226
|
+
public isStaticCall: boolean,
|
|
197
227
|
) {}
|
|
198
228
|
|
|
199
229
|
static get schema() {
|
|
200
230
|
return z
|
|
201
231
|
.object({
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
232
|
+
msgSender: AztecAddress.schema,
|
|
233
|
+
contractAddress: AztecAddress.schema,
|
|
234
|
+
calldata: schemas.Fr.array(),
|
|
235
|
+
isStaticCall: z.boolean(),
|
|
205
236
|
})
|
|
206
237
|
.transform(
|
|
207
|
-
({
|
|
208
|
-
new
|
|
238
|
+
({ msgSender, contractAddress, calldata, isStaticCall }) =>
|
|
239
|
+
new AvmEnqueuedCallHint(msgSender, contractAddress, calldata, isStaticCall),
|
|
209
240
|
);
|
|
210
241
|
}
|
|
211
242
|
}
|
|
@@ -213,16 +244,16 @@ export class AvmPublicDataWriteTreeHint {
|
|
|
213
244
|
export class AvmExecutionHints {
|
|
214
245
|
constructor(
|
|
215
246
|
public readonly enqueuedCalls: AvmEnqueuedCallHint[] = [],
|
|
247
|
+
// Contract hints.
|
|
216
248
|
public readonly contractInstances: AvmContractInstanceHint[] = [],
|
|
217
249
|
public readonly contractClasses: AvmContractClassHint[] = [],
|
|
218
250
|
public readonly bytecodeCommitments: AvmBytecodeCommitmentHint[] = [],
|
|
219
|
-
|
|
220
|
-
public readonly
|
|
221
|
-
public readonly
|
|
222
|
-
public readonly
|
|
223
|
-
public readonly
|
|
224
|
-
public readonly
|
|
225
|
-
public readonly l1ToL2MessageReads: AvmAppendTreeHint[] = [],
|
|
251
|
+
// Merkle DB hints.
|
|
252
|
+
public readonly getSiblingPathHints: AvmGetSiblingPathHint[] = [],
|
|
253
|
+
public readonly getPreviousValueIndexHints: AvmGetPreviousValueIndexHint[] = [],
|
|
254
|
+
public readonly getLeafPreimageHintsPublicDataTree: AvmGetLeafPreimageHintPublicDataTree[] = [],
|
|
255
|
+
public readonly getLeafPreimageHintsNullifierTree: AvmGetLeafPreimageHintNullifierTree[] = [],
|
|
256
|
+
public readonly getLeafValueHints: AvmGetLeafValueHint[] = [],
|
|
226
257
|
) {}
|
|
227
258
|
|
|
228
259
|
static empty() {
|
|
@@ -236,13 +267,11 @@ export class AvmExecutionHints {
|
|
|
236
267
|
contractInstances: AvmContractInstanceHint.schema.array(),
|
|
237
268
|
contractClasses: AvmContractClassHint.schema.array(),
|
|
238
269
|
bytecodeCommitments: AvmBytecodeCommitmentHint.schema.array(),
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
noteHashWrites: AvmAppendTreeHint.schema.array(),
|
|
245
|
-
l1ToL2MessageReads: AvmAppendTreeHint.schema.array(),
|
|
270
|
+
getSiblingPathHints: AvmGetSiblingPathHint.schema.array(),
|
|
271
|
+
getPreviousValueIndexHints: AvmGetPreviousValueIndexHint.schema.array(),
|
|
272
|
+
getLeafPreimageHintsPublicDataTree: AvmGetLeafPreimageHintPublicDataTree.schema.array(),
|
|
273
|
+
getLeafPreimageHintsNullifierTree: AvmGetLeafPreimageHintNullifierTree.schema.array(),
|
|
274
|
+
getLeafValueHints: AvmGetLeafValueHint.schema.array(),
|
|
246
275
|
})
|
|
247
276
|
.transform(
|
|
248
277
|
({
|
|
@@ -250,26 +279,22 @@ export class AvmExecutionHints {
|
|
|
250
279
|
contractInstances,
|
|
251
280
|
contractClasses,
|
|
252
281
|
bytecodeCommitments,
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
noteHashWrites,
|
|
259
|
-
l1ToL2MessageReads,
|
|
282
|
+
getSiblingPathHints,
|
|
283
|
+
getPreviousValueIndexHints,
|
|
284
|
+
getLeafPreimageHintsPublicDataTree,
|
|
285
|
+
getLeafPreimageHintsNullifierTree,
|
|
286
|
+
getLeafValueHints,
|
|
260
287
|
}) =>
|
|
261
288
|
new AvmExecutionHints(
|
|
262
289
|
enqueuedCalls,
|
|
263
290
|
contractInstances,
|
|
264
291
|
contractClasses,
|
|
265
292
|
bytecodeCommitments,
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
noteHashWrites,
|
|
272
|
-
l1ToL2MessageReads,
|
|
293
|
+
getSiblingPathHints,
|
|
294
|
+
getPreviousValueIndexHints,
|
|
295
|
+
getLeafPreimageHintsPublicDataTree,
|
|
296
|
+
getLeafPreimageHintsNullifierTree,
|
|
297
|
+
getLeafValueHints,
|
|
273
298
|
),
|
|
274
299
|
);
|
|
275
300
|
}
|
|
@@ -9,6 +9,7 @@ import type { PublishedL2Block } from '../published_l2_block.js';
|
|
|
9
9
|
export class L2BlockStream {
|
|
10
10
|
private readonly runningPromise: RunningPromise;
|
|
11
11
|
private isSyncing = false;
|
|
12
|
+
private hasStarted = false;
|
|
12
13
|
|
|
13
14
|
constructor(
|
|
14
15
|
private l2BlockSource: Pick<L2BlockSource, 'getPublishedBlocks' | 'getBlockHeader' | 'getL2Tips'>,
|
|
@@ -76,7 +77,12 @@ export class L2BlockStream {
|
|
|
76
77
|
// If we are just starting, use the starting block number from the options.
|
|
77
78
|
if (latestBlockNumber === 0 && this.opts.startingBlock !== undefined) {
|
|
78
79
|
latestBlockNumber = Math.max(this.opts.startingBlock - 1, 0);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Only log this entry once (for sanity)
|
|
83
|
+
if (!this.hasStarted) {
|
|
79
84
|
this.log.verbose(`Starting sync from block number ${latestBlockNumber}`);
|
|
85
|
+
this.hasStarted = true;
|
|
80
86
|
}
|
|
81
87
|
|
|
82
88
|
// Request new blocks from the source.
|
|
@@ -79,13 +79,15 @@ export class DatabaseVersion {
|
|
|
79
79
|
|
|
80
80
|
export type DatabaseVersionManagerFs = Pick<typeof fs, 'readFile' | 'writeFile' | 'rm' | 'mkdir'>;
|
|
81
81
|
|
|
82
|
+
export const DATABASE_VERSION_FILE_NAME = 'db_version';
|
|
83
|
+
|
|
82
84
|
/**
|
|
83
85
|
* A manager for handling database versioning and migrations.
|
|
84
86
|
* This class will check the version of data in a directory and either
|
|
85
87
|
* reset or upgrade based on version compatibility.
|
|
86
88
|
*/
|
|
87
89
|
export class DatabaseVersionManager<T> {
|
|
88
|
-
public static readonly VERSION_FILE =
|
|
90
|
+
public static readonly VERSION_FILE = DATABASE_VERSION_FILE_NAME;
|
|
89
91
|
|
|
90
92
|
private readonly versionFile: string;
|
|
91
93
|
private readonly currentVersion: DatabaseVersion;
|
|
@@ -119,6 +121,11 @@ export class DatabaseVersionManager<T> {
|
|
|
119
121
|
this.currentVersion = new DatabaseVersion(schemaVersion, rollupAddress);
|
|
120
122
|
}
|
|
121
123
|
|
|
124
|
+
static async writeVersion(version: DatabaseVersion, dataDir: string, fileSystem: DatabaseVersionManagerFs = fs) {
|
|
125
|
+
await fileSystem.mkdir(dataDir, { recursive: true });
|
|
126
|
+
return fileSystem.writeFile(join(dataDir, DatabaseVersionManager.VERSION_FILE), version.toBuffer());
|
|
127
|
+
}
|
|
128
|
+
|
|
122
129
|
/**
|
|
123
130
|
* Checks the stored version against the current version and handles the outcome
|
|
124
131
|
* by either resetting the data directory or calling an upgrade function
|
|
@@ -163,7 +170,7 @@ export class DatabaseVersionManager<T> {
|
|
|
163
170
|
needsReset = true;
|
|
164
171
|
}
|
|
165
172
|
} else {
|
|
166
|
-
this.log.warn('Rollup address changed, resetting data directory');
|
|
173
|
+
this.log.warn('Rollup address changed, resetting data directory', { versionFile: this.versionFile });
|
|
167
174
|
needsReset = true;
|
|
168
175
|
}
|
|
169
176
|
|
|
@@ -181,17 +188,14 @@ export class DatabaseVersionManager<T> {
|
|
|
181
188
|
/**
|
|
182
189
|
* Writes the current version to the version file
|
|
183
190
|
*/
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
await this.fileSystem.mkdir(this.dataDirectory, { recursive: true });
|
|
187
|
-
// Write the version file
|
|
188
|
-
await this.fileSystem.writeFile(this.versionFile, this.currentVersion.toBuffer());
|
|
191
|
+
public writeVersion(dir?: string): Promise<void> {
|
|
192
|
+
return DatabaseVersionManager.writeVersion(this.currentVersion, dir ?? this.dataDirectory, this.fileSystem);
|
|
189
193
|
}
|
|
190
194
|
|
|
191
195
|
/**
|
|
192
196
|
* Resets the data directory by deleting it and recreating it
|
|
193
197
|
*/
|
|
194
|
-
|
|
198
|
+
public async resetDataDirectory(): Promise<void> {
|
|
195
199
|
try {
|
|
196
200
|
await this.fileSystem.rm(this.dataDirectory, { recursive: true, force: true, maxRetries: 3 });
|
|
197
201
|
await this.fileSystem.mkdir(this.dataDirectory, { recursive: true });
|
|
@@ -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
|
+
}
|