@aztec/stdlib 3.0.0-nightly.20251005 → 3.0.0-nightly.20251008
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 +62 -78
- package/dest/avm/avm.d.ts.map +1 -1
- package/dest/avm/avm.js +8 -22
- package/dest/avm/avm_circuit_public_inputs.d.ts +19 -6
- package/dest/avm/avm_circuit_public_inputs.d.ts.map +1 -1
- package/dest/avm/avm_circuit_public_inputs.js +12 -11
- package/dest/avm/avm_proving_request.d.ts +49 -40
- package/dest/avm/avm_proving_request.d.ts.map +1 -1
- package/dest/file-store/interface.d.ts +8 -2
- package/dest/file-store/interface.d.ts.map +1 -1
- package/dest/file-store/s3.d.ts +1 -0
- package/dest/file-store/s3.d.ts.map +1 -1
- package/dest/file-store/s3.js +81 -16
- package/dest/interfaces/aztec-node-admin.d.ts +3 -0
- package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
- package/dest/interfaces/configs.d.ts +5 -0
- package/dest/interfaces/configs.d.ts.map +1 -1
- package/dest/interfaces/configs.js +2 -1
- package/dest/interfaces/proving-job.d.ts +49 -40
- package/dest/interfaces/proving-job.d.ts.map +1 -1
- package/dest/interfaces/validator.d.ts +1 -1
- package/dest/interfaces/validator.d.ts.map +1 -1
- package/dest/kernel/hints/build_nullifier_read_request_hints.d.ts +3 -2
- package/dest/kernel/hints/build_nullifier_read_request_hints.d.ts.map +1 -1
- package/dest/kernel/hints/nullifier_read_request_hints.d.ts +4 -3
- package/dest/kernel/hints/nullifier_read_request_hints.d.ts.map +1 -1
- package/dest/kernel/private_call_data.d.ts +4 -24
- package/dest/kernel/private_call_data.d.ts.map +1 -1
- package/dest/kernel/private_call_data.js +4 -16
- package/dest/kernel/private_kernel_circuit_public_inputs.d.ts +3 -3
- package/dest/kernel/private_kernel_circuit_public_inputs.d.ts.map +1 -1
- package/dest/kernel/private_kernel_circuit_public_inputs.js +3 -3
- package/dest/kernel/private_kernel_init_circuit_private_inputs.d.ts +5 -4
- package/dest/kernel/private_kernel_init_circuit_private_inputs.d.ts.map +1 -1
- package/dest/kernel/private_kernel_init_circuit_private_inputs.js +7 -6
- package/dest/kernel/private_kernel_tail_circuit_public_inputs.js +1 -1
- package/dest/p2p/block_proposal.d.ts +2 -0
- package/dest/p2p/block_proposal.d.ts.map +1 -1
- package/dest/rollup/block_constant_data.d.ts +4 -4
- package/dest/rollup/block_constant_data.d.ts.map +1 -1
- package/dest/rollup/block_constant_data.js +4 -4
- package/dest/rollup/checkpoint_constant_data.d.ts +4 -4
- package/dest/rollup/checkpoint_constant_data.d.ts.map +1 -1
- package/dest/rollup/checkpoint_constant_data.js +4 -4
- package/dest/rollup/epoch_constant_data.d.ts +4 -4
- package/dest/rollup/epoch_constant_data.d.ts.map +1 -1
- package/dest/rollup/epoch_constant_data.js +5 -5
- package/dest/snapshots/download.d.ts.map +1 -1
- package/dest/snapshots/download.js +58 -2
- package/dest/snapshots/upload.d.ts.map +1 -1
- package/dest/snapshots/upload.js +1 -0
- package/dest/tests/factories.d.ts +5 -4
- package/dest/tests/factories.d.ts.map +1 -1
- package/dest/tests/factories.js +11 -10
- package/dest/tests/mocks.d.ts +2 -2
- package/dest/tests/mocks.d.ts.map +1 -1
- package/dest/tests/mocks.js +2 -2
- package/dest/trees/index.d.ts +0 -1
- package/dest/trees/index.d.ts.map +1 -1
- package/dest/trees/index.js +0 -1
- package/dest/tx/index.d.ts +2 -0
- package/dest/tx/index.d.ts.map +1 -1
- package/dest/tx/index.js +2 -0
- package/dest/tx/private_tx_constant_data.d.ts +60 -0
- package/dest/tx/private_tx_constant_data.d.ts.map +1 -0
- package/dest/tx/private_tx_constant_data.js +69 -0
- package/dest/tx/protocol_contracts.d.ts +29 -0
- package/dest/tx/protocol_contracts.d.ts.map +1 -0
- package/dest/tx/protocol_contracts.js +49 -0
- package/dest/tx/tx_constant_data.d.ts +5 -37
- package/dest/tx/tx_constant_data.d.ts.map +1 -1
- package/dest/tx/tx_constant_data.js +8 -17
- package/dest/tx/validator/error_texts.d.ts +1 -1
- package/dest/tx/validator/error_texts.d.ts.map +1 -1
- package/dest/tx/validator/error_texts.js +1 -1
- package/dest/versioning/versioning.d.ts +2 -2
- package/dest/versioning/versioning.d.ts.map +1 -1
- package/dest/versioning/versioning.js +8 -8
- package/package.json +8 -8
- package/src/avm/avm.ts +13 -24
- package/src/avm/avm_circuit_public_inputs.ts +11 -10
- package/src/file-store/interface.ts +8 -2
- package/src/file-store/s3.ts +83 -15
- package/src/interfaces/configs.ts +3 -0
- package/src/interfaces/validator.ts +1 -1
- package/src/kernel/hints/build_nullifier_read_request_hints.ts +3 -2
- package/src/kernel/hints/nullifier_read_request_hints.ts +3 -3
- package/src/kernel/private_call_data.ts +2 -21
- package/src/kernel/private_kernel_circuit_public_inputs.ts +4 -4
- package/src/kernel/private_kernel_init_circuit_private_inputs.ts +5 -4
- package/src/kernel/private_kernel_tail_circuit_public_inputs.ts +1 -1
- package/src/p2p/block_proposal.ts +2 -0
- package/src/rollup/block_constant_data.ts +3 -3
- package/src/rollup/checkpoint_constant_data.ts +3 -3
- package/src/rollup/epoch_constant_data.ts +3 -9
- package/src/snapshots/download.ts +66 -2
- package/src/snapshots/upload.ts +1 -0
- package/src/tests/factories.ts +12 -19
- package/src/tests/mocks.ts +3 -3
- package/src/trees/index.ts +0 -1
- package/src/tx/index.ts +2 -0
- package/src/tx/private_tx_constant_data.ts +94 -0
- package/src/tx/protocol_contracts.ts +70 -0
- package/src/tx/tx_constant_data.ts +6 -19
- package/src/tx/validator/error_texts.ts +1 -1
- package/src/versioning/versioning.ts +10 -10
- package/dest/trees/protocol_contract_leaf.d.ts +0 -84
- package/dest/trees/protocol_contract_leaf.d.ts.map +0 -1
- package/dest/trees/protocol_contract_leaf.js +0 -100
- package/src/trees/protocol_contract_leaf.ts +0 -128
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
} from '../kernel/private_to_avm_accumulated_data.js';
|
|
17
17
|
import { PublicCallRequest, PublicCallRequestArrayLengths } from '../kernel/public_call_request.js';
|
|
18
18
|
import { GlobalVariables } from '../tx/global_variables.js';
|
|
19
|
+
import { ProtocolContracts } from '../tx/protocol_contracts.js';
|
|
19
20
|
import { TreeSnapshots } from '../tx/tree_snapshots.js';
|
|
20
21
|
import { AvmAccumulatedData, AvmAccumulatedDataArrayLengths } from './avm_accumulated_data.js';
|
|
21
22
|
import { serializeWithMessagePack } from './message_pack.js';
|
|
@@ -27,7 +28,7 @@ export class AvmCircuitPublicInputs {
|
|
|
27
28
|
///////////////////////////////////
|
|
28
29
|
// Inputs.
|
|
29
30
|
public globalVariables: GlobalVariables,
|
|
30
|
-
public
|
|
31
|
+
public protocolContracts: ProtocolContracts,
|
|
31
32
|
public startTreeSnapshots: TreeSnapshots,
|
|
32
33
|
public startGasUsed: Gas,
|
|
33
34
|
public gasSettings: GasSettings,
|
|
@@ -56,7 +57,7 @@ export class AvmCircuitPublicInputs {
|
|
|
56
57
|
return z
|
|
57
58
|
.object({
|
|
58
59
|
globalVariables: GlobalVariables.schema,
|
|
59
|
-
|
|
60
|
+
protocolContracts: ProtocolContracts.schema,
|
|
60
61
|
startTreeSnapshots: TreeSnapshots.schema,
|
|
61
62
|
startGasUsed: Gas.schema,
|
|
62
63
|
gasSettings: GasSettings.schema,
|
|
@@ -81,7 +82,7 @@ export class AvmCircuitPublicInputs {
|
|
|
81
82
|
.transform(
|
|
82
83
|
({
|
|
83
84
|
globalVariables,
|
|
84
|
-
|
|
85
|
+
protocolContracts,
|
|
85
86
|
startTreeSnapshots,
|
|
86
87
|
startGasUsed,
|
|
87
88
|
gasSettings,
|
|
@@ -105,7 +106,7 @@ export class AvmCircuitPublicInputs {
|
|
|
105
106
|
}) =>
|
|
106
107
|
new AvmCircuitPublicInputs(
|
|
107
108
|
globalVariables,
|
|
108
|
-
|
|
109
|
+
protocolContracts,
|
|
109
110
|
startTreeSnapshots,
|
|
110
111
|
startGasUsed,
|
|
111
112
|
gasSettings,
|
|
@@ -134,7 +135,7 @@ export class AvmCircuitPublicInputs {
|
|
|
134
135
|
const reader = BufferReader.asReader(buffer);
|
|
135
136
|
return new AvmCircuitPublicInputs(
|
|
136
137
|
reader.readObject(GlobalVariables),
|
|
137
|
-
reader.readObject(
|
|
138
|
+
reader.readObject(ProtocolContracts),
|
|
138
139
|
reader.readObject(TreeSnapshots),
|
|
139
140
|
reader.readObject(Gas),
|
|
140
141
|
reader.readObject(GasSettings),
|
|
@@ -161,7 +162,7 @@ export class AvmCircuitPublicInputs {
|
|
|
161
162
|
toBuffer() {
|
|
162
163
|
return serializeToBuffer(
|
|
163
164
|
this.globalVariables,
|
|
164
|
-
this.
|
|
165
|
+
this.protocolContracts,
|
|
165
166
|
this.startTreeSnapshots,
|
|
166
167
|
this.startGasUsed,
|
|
167
168
|
this.gasSettings,
|
|
@@ -197,7 +198,7 @@ export class AvmCircuitPublicInputs {
|
|
|
197
198
|
const reader = FieldReader.asReader(fields);
|
|
198
199
|
return new AvmCircuitPublicInputs(
|
|
199
200
|
GlobalVariables.fromFields(reader),
|
|
200
|
-
|
|
201
|
+
ProtocolContracts.fromFields(reader),
|
|
201
202
|
TreeSnapshots.fromFields(reader),
|
|
202
203
|
Gas.fromFields(reader),
|
|
203
204
|
GasSettings.fromFields(reader),
|
|
@@ -224,7 +225,7 @@ export class AvmCircuitPublicInputs {
|
|
|
224
225
|
toFields() {
|
|
225
226
|
return [
|
|
226
227
|
...this.globalVariables.toFields(),
|
|
227
|
-
this.
|
|
228
|
+
...this.protocolContracts.toFields(),
|
|
228
229
|
...this.startTreeSnapshots.toFields(),
|
|
229
230
|
...this.startGasUsed.toFields(),
|
|
230
231
|
...this.gasSettings.toFields(),
|
|
@@ -251,7 +252,7 @@ export class AvmCircuitPublicInputs {
|
|
|
251
252
|
static empty() {
|
|
252
253
|
return new AvmCircuitPublicInputs(
|
|
253
254
|
GlobalVariables.empty(),
|
|
254
|
-
|
|
255
|
+
ProtocolContracts.empty(),
|
|
255
256
|
TreeSnapshots.empty(),
|
|
256
257
|
Gas.empty(),
|
|
257
258
|
GasSettings.empty(),
|
|
@@ -282,7 +283,7 @@ export class AvmCircuitPublicInputs {
|
|
|
282
283
|
[inspect.custom]() {
|
|
283
284
|
return `AvmCircuitPublicInputs {
|
|
284
285
|
globalVariables: ${inspect(this.globalVariables)},
|
|
285
|
-
|
|
286
|
+
protocolContracts: ${inspect(this.protocolContracts)},
|
|
286
287
|
startTreeSnapshots: ${inspect(this.startTreeSnapshots)},
|
|
287
288
|
startGasUsed: ${inspect(this.startGasUsed)},
|
|
288
289
|
gasSettings: ${inspect(this.gasSettings)},
|
|
@@ -12,8 +12,14 @@ export type FileStoreSaveOptions = { public?: boolean; metadata?: Record<string,
|
|
|
12
12
|
|
|
13
13
|
/** Simple file store. */
|
|
14
14
|
export interface FileStore extends ReadOnlyFileStore {
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* Saves contents to the given path. Returns an URI that can be used later to `read` the file.
|
|
17
|
+
* Default: `compress` is false unless explicitly set.
|
|
18
|
+
*/
|
|
16
19
|
save(path: string, data: Buffer, opts?: FileStoreSaveOptions): Promise<string>;
|
|
17
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Uploads contents from a local file. Returns an URI that can be used later to `read` the file.
|
|
22
|
+
* Default: `compress` is true unless explicitly set to false.
|
|
23
|
+
*/
|
|
18
24
|
upload(destPath: string, srcPath: string, opts?: FileStoreSaveOptions): Promise<string>;
|
|
19
25
|
}
|
package/src/file-store/s3.ts
CHANGED
|
@@ -8,8 +8,9 @@ import {
|
|
|
8
8
|
S3Client,
|
|
9
9
|
} from '@aws-sdk/client-s3';
|
|
10
10
|
import { createReadStream, createWriteStream } from 'fs';
|
|
11
|
-
import { mkdir } from 'fs/promises';
|
|
12
|
-
import {
|
|
11
|
+
import { mkdir, mkdtemp, stat, unlink } from 'fs/promises';
|
|
12
|
+
import { tmpdir } from 'os';
|
|
13
|
+
import { basename, dirname, join } from 'path';
|
|
13
14
|
import { Readable } from 'stream';
|
|
14
15
|
import { finished } from 'stream/promises';
|
|
15
16
|
import { createGzip } from 'zlib';
|
|
@@ -49,15 +50,19 @@ export class S3FileStore implements FileStore {
|
|
|
49
50
|
|
|
50
51
|
public async save(path: string, data: Buffer, opts: FileStoreSaveOptions = {}): Promise<string> {
|
|
51
52
|
const key = this.getFullPath(path);
|
|
52
|
-
const shouldCompress =
|
|
53
|
+
const shouldCompress = !!opts.compress;
|
|
54
|
+
|
|
53
55
|
const body = shouldCompress ? (await import('zlib')).gzipSync(data) : data;
|
|
56
|
+
const contentLength = body.length;
|
|
57
|
+
const contentType = this.detectContentType(key, shouldCompress);
|
|
54
58
|
const put = new PutObjectCommand({
|
|
55
59
|
Bucket: this.bucketName,
|
|
56
60
|
Key: key,
|
|
57
61
|
Body: body,
|
|
58
|
-
|
|
62
|
+
ContentType: contentType,
|
|
59
63
|
CacheControl: opts.metadata?.['Cache-control'],
|
|
60
64
|
Metadata: this.extractUserMetadata(opts.metadata),
|
|
65
|
+
ContentLength: contentLength,
|
|
61
66
|
});
|
|
62
67
|
await this.s3.send(put);
|
|
63
68
|
return this.buildReturnedUrl(key, !!opts.public);
|
|
@@ -68,18 +73,59 @@ export class S3FileStore implements FileStore {
|
|
|
68
73
|
const shouldCompress = opts.compress !== false; // default true like GCS impl
|
|
69
74
|
|
|
70
75
|
await mkdir(dirname(srcPath), { recursive: true }).catch(() => undefined);
|
|
76
|
+
let contentLength: number | undefined;
|
|
77
|
+
let bodyPath = srcPath;
|
|
78
|
+
|
|
79
|
+
// We don't set Content-Encoding and we avoid SigV4 streaming (aws-chunked).
|
|
80
|
+
// With AWS SigV4 streaming uploads (Content-Encoding: aws-chunked[,gzip]), servers require
|
|
81
|
+
// x-amz-decoded-content-length (the size of the decoded payload) and an exact Content-Length
|
|
82
|
+
// that includes chunk metadata. For on-the-fly compression, providing
|
|
83
|
+
// those values without buffering or a pre-pass is impractical. Instead, we pre-gzip to a temp file
|
|
84
|
+
// to know ContentLength up-front and upload the gzipped bytes as-is, omitting Content-Encoding.
|
|
85
|
+
// Reference: AWS SigV4 streaming (chunked upload) requirements —
|
|
86
|
+
// https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html
|
|
87
|
+
if (shouldCompress) {
|
|
88
|
+
// Pre-gzip to a temp file so we know the exact length for R2/S3 headers
|
|
89
|
+
const tmpDir = await mkdtemp(join(tmpdir(), 's3-upload-'));
|
|
90
|
+
const gzPath = join(tmpDir, `${basename(srcPath)}.gz`);
|
|
91
|
+
const source = createReadStream(srcPath);
|
|
92
|
+
const gz = createGzip();
|
|
93
|
+
const out = createWriteStream(gzPath);
|
|
94
|
+
try {
|
|
95
|
+
await finished(source.pipe(gz).pipe(out));
|
|
96
|
+
const st = await stat(gzPath);
|
|
97
|
+
contentLength = st.size;
|
|
98
|
+
bodyPath = gzPath;
|
|
99
|
+
} catch (err) {
|
|
100
|
+
// Ensure temp file is removed on failure
|
|
101
|
+
await unlink(gzPath).catch(() => undefined);
|
|
102
|
+
throw err;
|
|
103
|
+
}
|
|
104
|
+
} else {
|
|
105
|
+
const st = await stat(srcPath);
|
|
106
|
+
contentLength = st.size;
|
|
107
|
+
bodyPath = srcPath;
|
|
108
|
+
}
|
|
71
109
|
|
|
72
|
-
const
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
110
|
+
const bodyStream = createReadStream(bodyPath);
|
|
111
|
+
const contentType = this.detectContentType(key, shouldCompress);
|
|
112
|
+
try {
|
|
113
|
+
const put = new PutObjectCommand({
|
|
114
|
+
Bucket: this.bucketName,
|
|
115
|
+
Key: key,
|
|
116
|
+
Body: bodyStream as any,
|
|
117
|
+
ContentType: contentType,
|
|
118
|
+
CacheControl: opts.metadata?.['Cache-control'],
|
|
119
|
+
Metadata: this.extractUserMetadata(opts.metadata),
|
|
120
|
+
// Explicitly set ContentLength so R2 can compute x-amz-decoded-content-length correctly
|
|
121
|
+
ContentLength: contentLength,
|
|
122
|
+
} as any);
|
|
123
|
+
await this.s3.send(put);
|
|
124
|
+
} finally {
|
|
125
|
+
if (shouldCompress && bodyPath !== srcPath) {
|
|
126
|
+
await unlink(bodyPath).catch(() => undefined);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
83
129
|
return this.buildReturnedUrl(key, !!opts.public);
|
|
84
130
|
}
|
|
85
131
|
|
|
@@ -125,6 +171,28 @@ export class S3FileStore implements FileStore {
|
|
|
125
171
|
return Object.keys(rest).length ? rest : undefined;
|
|
126
172
|
}
|
|
127
173
|
|
|
174
|
+
private detectContentType(key: string, isCompressed: boolean | undefined): string | undefined {
|
|
175
|
+
// Basic content type inference
|
|
176
|
+
const lower = key.toLowerCase();
|
|
177
|
+
if (lower.endsWith('.json') || lower.endsWith('.json.gz')) {
|
|
178
|
+
return 'application/json';
|
|
179
|
+
}
|
|
180
|
+
if (lower.endsWith('.txt') || lower.endsWith('.log') || lower.endsWith('.csv') || lower.endsWith('.md')) {
|
|
181
|
+
return 'text/plain; charset=utf-8';
|
|
182
|
+
}
|
|
183
|
+
if (lower.endsWith('.db') || lower.endsWith('.sqlite') || lower.endsWith('.bin')) {
|
|
184
|
+
return 'application/octet-stream';
|
|
185
|
+
}
|
|
186
|
+
if (lower.endsWith('.wasm') || lower.endsWith('.wasm.gz')) {
|
|
187
|
+
return 'application/wasm';
|
|
188
|
+
}
|
|
189
|
+
// If compressed, prefer octet-stream unless known
|
|
190
|
+
if (isCompressed) {
|
|
191
|
+
return 'application/octet-stream';
|
|
192
|
+
}
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
|
|
128
196
|
private buildReturnedUrl(key: string, makePublic: boolean): string {
|
|
129
197
|
if (!makePublic) {
|
|
130
198
|
return `s3://${this.bucketName}/${key}`;
|
|
@@ -52,6 +52,8 @@ export interface SequencerConfig {
|
|
|
52
52
|
skipCollectingAttestations?: boolean;
|
|
53
53
|
/** Do not invalidate the previous block if invalid when we are the proposer (for testing only) */
|
|
54
54
|
skipInvalidateBlockAsProposer?: boolean;
|
|
55
|
+
/** Broadcast invalid block proposals with corrupted state (for testing only) */
|
|
56
|
+
broadcastInvalidBlockProposal?: boolean;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
export const SequencerConfigSchema = z.object({
|
|
@@ -75,4 +77,5 @@ export const SequencerConfigSchema = z.object({
|
|
|
75
77
|
skipCollectingAttestations: z.boolean().optional(),
|
|
76
78
|
secondsBeforeInvalidatingBlockAsCommitteeMember: z.number(),
|
|
77
79
|
secondsBeforeInvalidatingBlockAsNonCommitteeMember: z.number(),
|
|
80
|
+
broadcastInvalidBlockProposal: z.boolean().optional(),
|
|
78
81
|
}) satisfies ZodFor<SequencerConfig>;
|
|
@@ -43,7 +43,7 @@ export interface ValidatorClientConfig {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
export type ValidatorClientFullConfig = ValidatorClientConfig &
|
|
46
|
-
Pick<SequencerConfig, 'txPublicSetupAllowList'> &
|
|
46
|
+
Pick<SequencerConfig, 'txPublicSetupAllowList' | 'broadcastInvalidBlockProposal'> &
|
|
47
47
|
Pick<SlasherConfig, 'slashBroadcastedInvalidBlockPenalty'>;
|
|
48
48
|
|
|
49
49
|
export const ValidatorClientConfigSchema = z.object({
|
|
@@ -4,9 +4,10 @@ import {
|
|
|
4
4
|
type NULLIFIER_TREE_HEIGHT,
|
|
5
5
|
} from '@aztec/constants';
|
|
6
6
|
import type { Fr } from '@aztec/foundation/fields';
|
|
7
|
-
import {
|
|
7
|
+
import { MembershipWitness } from '@aztec/foundation/trees';
|
|
8
8
|
|
|
9
9
|
import { siloNullifier } from '../../hash/hash.js';
|
|
10
|
+
import type { NullifierLeafPreimage } from '../../trees/nullifier_leaf.js';
|
|
10
11
|
import type { ClaimedLengthArray } from '../claimed_length_array.js';
|
|
11
12
|
import type { ScopedNullifier } from '../nullifier.js';
|
|
12
13
|
import { NullifierReadRequestHintsBuilder } from './nullifier_read_request_hints.js';
|
|
@@ -24,7 +25,7 @@ export function isValidNullifierReadRequest(readRequest: ScopedReadRequest, null
|
|
|
24
25
|
|
|
25
26
|
interface NullifierMembershipWitnessWithPreimage {
|
|
26
27
|
membershipWitness: MembershipWitness<typeof NULLIFIER_TREE_HEIGHT>;
|
|
27
|
-
leafPreimage:
|
|
28
|
+
leafPreimage: NullifierLeafPreimage;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
export function getNullifierReadRequestResetActions(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MAX_NULLIFIER_READ_REQUESTS_PER_TX, NULLIFIER_TREE_HEIGHT } from '@aztec/constants';
|
|
2
2
|
import { makeTuple } from '@aztec/foundation/array';
|
|
3
3
|
import type { BufferReader } from '@aztec/foundation/serialize';
|
|
4
|
-
import type { MembershipWitness
|
|
4
|
+
import type { MembershipWitness } from '@aztec/foundation/trees';
|
|
5
5
|
|
|
6
6
|
import { NullifierLeafPreimage } from '../../trees/index.js';
|
|
7
7
|
import { PendingReadHint, ReadRequestAction, ReadRequestResetHints, SettledReadHint } from './read_request_hints.js';
|
|
@@ -11,7 +11,7 @@ export type NullifierReadRequestHints<PENDING extends number, SETTLED extends nu
|
|
|
11
11
|
PENDING,
|
|
12
12
|
SETTLED,
|
|
13
13
|
typeof NULLIFIER_TREE_HEIGHT,
|
|
14
|
-
|
|
14
|
+
NullifierLeafPreimage
|
|
15
15
|
>;
|
|
16
16
|
|
|
17
17
|
export function nullifierReadRequestHintsFromBuffer<PENDING extends number, SETTLED extends number>(
|
|
@@ -64,7 +64,7 @@ export class NullifierReadRequestHintsBuilder<PENDING extends number, SETTLED ex
|
|
|
64
64
|
addSettledReadRequest(
|
|
65
65
|
readRequestIndex: number,
|
|
66
66
|
membershipWitness: MembershipWitness<typeof NULLIFIER_TREE_HEIGHT>,
|
|
67
|
-
leafPreimage:
|
|
67
|
+
leafPreimage: NullifierLeafPreimage,
|
|
68
68
|
) {
|
|
69
69
|
if (this.numSettledReadHints === this.maxSettled) {
|
|
70
70
|
throw new Error('Cannot add more settled read request.');
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
FUNCTION_TREE_HEIGHT,
|
|
3
|
-
PROTOCOL_CONTRACT_TREE_HEIGHT,
|
|
4
|
-
PUBLIC_DATA_TREE_HEIGHT,
|
|
5
|
-
UPDATES_VALUE_SIZE,
|
|
6
|
-
} from '@aztec/constants';
|
|
1
|
+
import { FUNCTION_TREE_HEIGHT, PUBLIC_DATA_TREE_HEIGHT, UPDATES_VALUE_SIZE } from '@aztec/constants';
|
|
7
2
|
import { Fr } from '@aztec/foundation/fields';
|
|
8
3
|
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
9
4
|
import { MembershipWitness } from '@aztec/foundation/trees';
|
|
@@ -11,7 +6,7 @@ import type { FieldsOf } from '@aztec/foundation/types';
|
|
|
11
6
|
|
|
12
7
|
import { DelayedPublicMutableValues } from '../delayed_public_mutable/delayed_public_mutable_values.js';
|
|
13
8
|
import { PublicKeys } from '../keys/public_keys.js';
|
|
14
|
-
import {
|
|
9
|
+
import { PublicDataTreeLeafPreimage } from '../trees/index.js';
|
|
15
10
|
import { VerificationKeyAsFields } from '../vks/verification_key.js';
|
|
16
11
|
import { PrivateCircuitPublicInputs } from './private_circuit_public_inputs.js';
|
|
17
12
|
|
|
@@ -94,16 +89,6 @@ export class PrivateVerificationKeyHints {
|
|
|
94
89
|
* The membership witness for the function leaf corresponding to the function being invoked.
|
|
95
90
|
*/
|
|
96
91
|
public functionLeafMembershipWitness: MembershipWitness<typeof FUNCTION_TREE_HEIGHT>,
|
|
97
|
-
/**
|
|
98
|
-
* The membership witness for the protocolContractLeaf.
|
|
99
|
-
*/
|
|
100
|
-
public protocolContractMembershipWitness: MembershipWitness<typeof PROTOCOL_CONTRACT_TREE_HEIGHT>,
|
|
101
|
-
/**
|
|
102
|
-
* The leaf of the protocol contract tree, of either:
|
|
103
|
-
* The protocol contract being called.
|
|
104
|
-
* The low leaf showing that the address of the contract being called is not in the tree.
|
|
105
|
-
*/
|
|
106
|
-
public protocolContractLeaf: ProtocolContractLeafPreimage,
|
|
107
92
|
|
|
108
93
|
public updatedClassIdHints: UpdatedClassIdHints,
|
|
109
94
|
) {}
|
|
@@ -120,8 +105,6 @@ export class PrivateVerificationKeyHints {
|
|
|
120
105
|
fields.publicKeys,
|
|
121
106
|
fields.saltedInitializationHash,
|
|
122
107
|
fields.functionLeafMembershipWitness,
|
|
123
|
-
fields.protocolContractMembershipWitness,
|
|
124
|
-
fields.protocolContractLeaf,
|
|
125
108
|
fields.updatedClassIdHints,
|
|
126
109
|
] as const;
|
|
127
110
|
}
|
|
@@ -151,8 +134,6 @@ export class PrivateVerificationKeyHints {
|
|
|
151
134
|
reader.readObject(PublicKeys),
|
|
152
135
|
reader.readObject(Fr),
|
|
153
136
|
reader.readObject(MembershipWitness.deserializer(FUNCTION_TREE_HEIGHT)),
|
|
154
|
-
reader.readObject(MembershipWitness.deserializer(PROTOCOL_CONTRACT_TREE_HEIGHT)),
|
|
155
|
-
reader.readObject(ProtocolContractLeafPreimage),
|
|
156
137
|
reader.readObject(UpdatedClassIdHints),
|
|
157
138
|
);
|
|
158
139
|
}
|
|
@@ -3,7 +3,7 @@ import { bufferSchemaFor } from '@aztec/foundation/schemas';
|
|
|
3
3
|
import { BufferReader, bigintToUInt64BE, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
4
4
|
|
|
5
5
|
import { AztecAddress } from '../aztec-address/index.js';
|
|
6
|
-
import {
|
|
6
|
+
import { PrivateTxConstantData } from '../tx/private_tx_constant_data.js';
|
|
7
7
|
import type { UInt64 } from '../types/shared.js';
|
|
8
8
|
import { PrivateAccumulatedData } from './private_accumulated_data.js';
|
|
9
9
|
import { PrivateValidationRequests } from './private_validation_requests.js';
|
|
@@ -17,7 +17,7 @@ export class PrivateKernelCircuitPublicInputs {
|
|
|
17
17
|
/**
|
|
18
18
|
* Data which is not modified by the circuits.
|
|
19
19
|
*/
|
|
20
|
-
public constants:
|
|
20
|
+
public constants: PrivateTxConstantData,
|
|
21
21
|
/**
|
|
22
22
|
* The side effect counter that non-revertible side effects are all beneath.
|
|
23
23
|
*/
|
|
@@ -82,7 +82,7 @@ export class PrivateKernelCircuitPublicInputs {
|
|
|
82
82
|
static fromBuffer(buffer: Buffer | BufferReader): PrivateKernelCircuitPublicInputs {
|
|
83
83
|
const reader = BufferReader.asReader(buffer);
|
|
84
84
|
return new PrivateKernelCircuitPublicInputs(
|
|
85
|
-
reader.readObject(
|
|
85
|
+
reader.readObject(PrivateTxConstantData),
|
|
86
86
|
reader.readObject(Fr),
|
|
87
87
|
reader.readObject(PrivateValidationRequests),
|
|
88
88
|
reader.readObject(PrivateAccumulatedData),
|
|
@@ -96,7 +96,7 @@ export class PrivateKernelCircuitPublicInputs {
|
|
|
96
96
|
|
|
97
97
|
static empty() {
|
|
98
98
|
return new PrivateKernelCircuitPublicInputs(
|
|
99
|
-
|
|
99
|
+
PrivateTxConstantData.empty(),
|
|
100
100
|
Fr.zero(),
|
|
101
101
|
PrivateValidationRequests.empty(),
|
|
102
102
|
PrivateAccumulatedData.empty(),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Fr } from '@aztec/foundation/fields';
|
|
2
2
|
import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
3
3
|
|
|
4
|
+
import { ProtocolContracts } from '../tx/protocol_contracts.js';
|
|
4
5
|
import { TxRequest } from '../tx/tx_request.js';
|
|
5
6
|
import { PrivateCallData } from './private_call_data.js';
|
|
6
7
|
|
|
@@ -18,9 +19,9 @@ export class PrivateKernelInitCircuitPrivateInputs {
|
|
|
18
19
|
*/
|
|
19
20
|
public vkTreeRoot: Fr,
|
|
20
21
|
/**
|
|
21
|
-
* The
|
|
22
|
+
* The protocol contracts.
|
|
22
23
|
*/
|
|
23
|
-
public
|
|
24
|
+
public protocolContracts: ProtocolContracts,
|
|
24
25
|
/**
|
|
25
26
|
* Private calldata corresponding to this iteration of the kernel.
|
|
26
27
|
*/
|
|
@@ -43,7 +44,7 @@ export class PrivateKernelInitCircuitPrivateInputs {
|
|
|
43
44
|
return serializeToBuffer(
|
|
44
45
|
this.txRequest,
|
|
45
46
|
this.vkTreeRoot,
|
|
46
|
-
this.
|
|
47
|
+
this.protocolContracts,
|
|
47
48
|
this.privateCall,
|
|
48
49
|
this.firstNullifierHint,
|
|
49
50
|
);
|
|
@@ -59,7 +60,7 @@ export class PrivateKernelInitCircuitPrivateInputs {
|
|
|
59
60
|
return new PrivateKernelInitCircuitPrivateInputs(
|
|
60
61
|
reader.readObject(TxRequest),
|
|
61
62
|
Fr.fromBuffer(reader),
|
|
62
|
-
|
|
63
|
+
reader.readObject(ProtocolContracts),
|
|
63
64
|
reader.readObject(PrivateCallData),
|
|
64
65
|
reader.readBoolean(),
|
|
65
66
|
Fr.fromBuffer(reader),
|
|
@@ -173,7 +173,7 @@ export class PrivateKernelTailCircuitPublicInputs {
|
|
|
173
173
|
this.constants.anchorBlockHeader,
|
|
174
174
|
this.constants.txContext,
|
|
175
175
|
this.constants.vkTreeRoot,
|
|
176
|
-
this.constants.
|
|
176
|
+
this.constants.protocolContractsHash,
|
|
177
177
|
);
|
|
178
178
|
return new PrivateToRollupKernelCircuitPublicInputs(
|
|
179
179
|
constants,
|
|
@@ -26,6 +26,8 @@ export class BlockProposalHash extends Buffer32 {
|
|
|
26
26
|
|
|
27
27
|
export type BlockProposalOptions = {
|
|
28
28
|
publishFullTxs: boolean;
|
|
29
|
+
/** Whether to generate an invalid block proposal for broadcasting. Use only for testing. */
|
|
30
|
+
broadcastInvalidBlockProposal?: boolean;
|
|
29
31
|
};
|
|
30
32
|
|
|
31
33
|
/**
|
|
@@ -21,8 +21,8 @@ export class BlockConstantData {
|
|
|
21
21
|
public l1ToL2TreeSnapshot: AppendOnlyTreeSnapshot,
|
|
22
22
|
/** Root of the verification key tree. */
|
|
23
23
|
public vkTreeRoot: Fr,
|
|
24
|
-
/**
|
|
25
|
-
public
|
|
24
|
+
/** Hash of the protocol contracts list. */
|
|
25
|
+
public protocolContractsHash: Fr,
|
|
26
26
|
/** Global variables for the block. */
|
|
27
27
|
public globalVariables: GlobalVariables,
|
|
28
28
|
/** Identifier of the prover. */
|
|
@@ -50,7 +50,7 @@ export class BlockConstantData {
|
|
|
50
50
|
fields.lastArchive,
|
|
51
51
|
fields.l1ToL2TreeSnapshot,
|
|
52
52
|
fields.vkTreeRoot,
|
|
53
|
-
fields.
|
|
53
|
+
fields.protocolContractsHash,
|
|
54
54
|
fields.globalVariables,
|
|
55
55
|
fields.proverId,
|
|
56
56
|
] as const;
|
|
@@ -17,8 +17,8 @@ export class CheckpointConstantData {
|
|
|
17
17
|
public version: Fr,
|
|
18
18
|
/** Root of the verification key tree. */
|
|
19
19
|
public vkTreeRoot: Fr,
|
|
20
|
-
/**
|
|
21
|
-
public
|
|
20
|
+
/** Hash of the protocol contracts list. */
|
|
21
|
+
public protocolContractsHash: Fr,
|
|
22
22
|
/** Identifier of the prover. */
|
|
23
23
|
public proverId: Fr,
|
|
24
24
|
/** Slot number of the checkpoint. */
|
|
@@ -40,7 +40,7 @@ export class CheckpointConstantData {
|
|
|
40
40
|
fields.chainId,
|
|
41
41
|
fields.version,
|
|
42
42
|
fields.vkTreeRoot,
|
|
43
|
-
fields.
|
|
43
|
+
fields.protocolContractsHash,
|
|
44
44
|
fields.proverId,
|
|
45
45
|
fields.slotNumber,
|
|
46
46
|
fields.coinbase,
|
|
@@ -20,9 +20,9 @@ export class EpochConstantData {
|
|
|
20
20
|
*/
|
|
21
21
|
public vkTreeRoot: Fr,
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Hash of the protocol contracts list.
|
|
24
24
|
*/
|
|
25
|
-
public
|
|
25
|
+
public protocolContractsHash: Fr,
|
|
26
26
|
/**
|
|
27
27
|
* Identifier of the prover of the epoch.
|
|
28
28
|
*/
|
|
@@ -34,13 +34,7 @@ export class EpochConstantData {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
static getFields(fields: FieldsOf<EpochConstantData>) {
|
|
37
|
-
return [
|
|
38
|
-
fields.chainId,
|
|
39
|
-
fields.version,
|
|
40
|
-
fields.vkTreeRoot,
|
|
41
|
-
fields.protocolContractTreeRoot,
|
|
42
|
-
fields.proverId,
|
|
43
|
-
] as const;
|
|
37
|
+
return [fields.chainId, fields.version, fields.vkTreeRoot, fields.protocolContractsHash, fields.proverId] as const;
|
|
44
38
|
}
|
|
45
39
|
|
|
46
40
|
toFields(): Fr[] {
|
|
@@ -2,6 +2,12 @@ import { fromEntries, getEntries, maxBy } from '@aztec/foundation/collection';
|
|
|
2
2
|
import { jsonParseWithSchema } from '@aztec/foundation/json-rpc';
|
|
3
3
|
import type { ReadOnlyFileStore } from '@aztec/stdlib/file-store';
|
|
4
4
|
|
|
5
|
+
import { createReadStream, createWriteStream } from 'fs';
|
|
6
|
+
import fs from 'fs/promises';
|
|
7
|
+
import pathMod from 'path';
|
|
8
|
+
import { pipeline } from 'stream/promises';
|
|
9
|
+
import { createGunzip, gunzipSync } from 'zlib';
|
|
10
|
+
|
|
5
11
|
import {
|
|
6
12
|
SnapshotDataKeys,
|
|
7
13
|
type SnapshotDataUrls,
|
|
@@ -20,7 +26,8 @@ export async function getSnapshotIndex(
|
|
|
20
26
|
try {
|
|
21
27
|
if (await store.exists(snapshotIndexPath)) {
|
|
22
28
|
const snapshotIndexData = await store.read(snapshotIndexPath);
|
|
23
|
-
|
|
29
|
+
const buf = maybeGunzip(snapshotIndexData);
|
|
30
|
+
return jsonParseWithSchema(buf.toString('utf-8'), SnapshotsIndexSchema);
|
|
24
31
|
} else {
|
|
25
32
|
return undefined;
|
|
26
33
|
}
|
|
@@ -50,10 +57,67 @@ export function makeSnapshotPaths(baseDir: string): SnapshotDataUrls {
|
|
|
50
57
|
return fromEntries(SnapshotDataKeys.map(key => [key, `${baseDir}/${key}.db`]));
|
|
51
58
|
}
|
|
52
59
|
|
|
60
|
+
function isGzipMagic(data: Buffer): boolean {
|
|
61
|
+
return data.length >= 2 && data[0] === 0x1f && data[1] === 0x8b;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function maybeGunzip(data: Buffer): Buffer {
|
|
65
|
+
const magicNumberIndicatesGzip = isGzipMagic(data);
|
|
66
|
+
|
|
67
|
+
if (magicNumberIndicatesGzip) {
|
|
68
|
+
try {
|
|
69
|
+
const out = gunzipSync(data);
|
|
70
|
+
return out;
|
|
71
|
+
} catch (err) {
|
|
72
|
+
throw new Error(`Decompression of gzipped data failed: ${(err as Error).message}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return data;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function detectGzip(localFilePathToPeek: string): Promise<boolean> {
|
|
79
|
+
// Peek the actual bytes we downloaded.
|
|
80
|
+
try {
|
|
81
|
+
const fd = await fs.open(localFilePathToPeek, 'r');
|
|
82
|
+
try {
|
|
83
|
+
const header = Buffer.alloc(2);
|
|
84
|
+
const { bytesRead } = await fd.read(header, 0, 2, 0);
|
|
85
|
+
return bytesRead >= 2 && isGzipMagic(header);
|
|
86
|
+
} finally {
|
|
87
|
+
await fd.close();
|
|
88
|
+
}
|
|
89
|
+
} catch {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
53
94
|
export async function downloadSnapshot(
|
|
54
95
|
snapshot: Pick<SnapshotMetadata, 'dataUrls'>,
|
|
55
96
|
localPaths: Record<SnapshotDataKeys, string>,
|
|
56
97
|
store: ReadOnlyFileStore,
|
|
57
98
|
): Promise<void> {
|
|
58
|
-
await Promise.all(
|
|
99
|
+
await Promise.all(
|
|
100
|
+
getEntries(localPaths).map(async ([key, path]) => {
|
|
101
|
+
await fs.mkdir(pathMod.dirname(path), { recursive: true });
|
|
102
|
+
|
|
103
|
+
const tmpPath = `${path}.download`;
|
|
104
|
+
try {
|
|
105
|
+
const url = snapshot.dataUrls[key];
|
|
106
|
+
await store.download(url, tmpPath);
|
|
107
|
+
|
|
108
|
+
const isGzip = await detectGzip(tmpPath);
|
|
109
|
+
|
|
110
|
+
const read = createReadStream(tmpPath);
|
|
111
|
+
const write = createWriteStream(path);
|
|
112
|
+
if (isGzip) {
|
|
113
|
+
const gunzip = createGunzip();
|
|
114
|
+
await pipeline(read, gunzip, write);
|
|
115
|
+
} else {
|
|
116
|
+
await pipeline(read, write);
|
|
117
|
+
}
|
|
118
|
+
} finally {
|
|
119
|
+
await fs.unlink(tmpPath).catch(() => undefined);
|
|
120
|
+
}
|
|
121
|
+
}),
|
|
122
|
+
);
|
|
59
123
|
}
|
package/src/snapshots/upload.ts
CHANGED
|
@@ -48,6 +48,7 @@ export async function uploadSnapshotToIndex(
|
|
|
48
48
|
|
|
49
49
|
await store.save(getSnapshotIndexPath(metadata), Buffer.from(jsonStringify(snapshotsIndex, true)), {
|
|
50
50
|
public: true, // Make the index publicly accessible
|
|
51
|
+
compress: false, // Ensure index.json is not gzipped
|
|
51
52
|
metadata: { ['Cache-control']: 'no-store' }, // Do not cache object versions
|
|
52
53
|
});
|
|
53
54
|
return newSnapshotMetadata;
|