@aztec/end-to-end 0.87.2 → 0.87.3-nightly.20250528
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/bench/client_flows/benchmark.d.ts +59 -0
- package/dest/bench/client_flows/benchmark.d.ts.map +1 -0
- package/dest/bench/client_flows/benchmark.js +240 -0
- package/dest/bench/client_flows/client_flows_benchmark.d.ts +5 -3
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.js +24 -14
- package/dest/bench/client_flows/data_extractor.d.ts +0 -21
- package/dest/bench/client_flows/data_extractor.d.ts.map +1 -1
- package/dest/bench/client_flows/data_extractor.js +5 -122
- package/dest/bench/utils.d.ts +7 -0
- package/dest/bench/utils.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.d.ts +3 -2
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +5 -4
- package/dest/e2e_p2p/shared.js +6 -2
- package/dest/fixtures/snapshot_manager.d.ts.map +1 -1
- package/dest/fixtures/snapshot_manager.js +4 -4
- package/dest/fixtures/utils.d.ts +2 -3
- package/dest/fixtures/utils.d.ts.map +1 -1
- package/dest/fixtures/utils.js +7 -4
- package/package.json +35 -34
- package/src/bench/client_flows/benchmark.ts +308 -0
- package/src/bench/client_flows/client_flows_benchmark.ts +28 -10
- package/src/bench/client_flows/data_extractor.ts +8 -142
- package/src/bench/utils.ts +1 -1
- package/src/e2e_p2p/p2p_network.ts +13 -1
- package/src/e2e_p2p/shared.ts +2 -2
- package/src/fixtures/snapshot_manager.ts +5 -2
- package/src/fixtures/utils.ts +9 -5
- package/dest/shared/capture_private_execution_steps.d.ts +0 -7
- package/dest/shared/capture_private_execution_steps.d.ts.map +0 -1
- package/dest/shared/capture_private_execution_steps.js +0 -49
- package/src/shared/capture_private_execution_steps.ts +0 -68
|
@@ -2,6 +2,7 @@ import { EcdsaRAccountContractArtifact, getEcdsaRAccount } from '@aztec/accounts
|
|
|
2
2
|
import { SchnorrAccountContractArtifact, getSchnorrAccount, getSchnorrWallet } from '@aztec/accounts/schnorr';
|
|
3
3
|
import {
|
|
4
4
|
type AccountWallet,
|
|
5
|
+
AccountWalletWithSecretKey,
|
|
5
6
|
AztecAddress,
|
|
6
7
|
type AztecNode,
|
|
7
8
|
FeeJuicePaymentMethod,
|
|
@@ -47,6 +48,7 @@ import {
|
|
|
47
48
|
FeeJuicePortalTestingHarnessFactory,
|
|
48
49
|
type GasBridgingTestHarness,
|
|
49
50
|
} from '../../shared/gas_portal_test_harness.js';
|
|
51
|
+
import { ProxyLogger } from './benchmark.js';
|
|
50
52
|
import { type ClientFlowsConfig, FULL_FLOWS_CONFIG, KEY_FLOWS_CONFIG } from './config.js';
|
|
51
53
|
|
|
52
54
|
const { E2E_DATA_PATH: dataPath, BENCHMARK_CONFIG } = process.env;
|
|
@@ -91,6 +93,8 @@ export class ClientFlowsBenchmark {
|
|
|
91
93
|
// PXE used by the benchmarking user. It can be set up with client-side proving enabled
|
|
92
94
|
public userPXE!: PXE;
|
|
93
95
|
|
|
96
|
+
public realProofs = ['true', '1'].includes(process.env.REAL_PROOFS ?? '');
|
|
97
|
+
|
|
94
98
|
public paymentMethods: Record<BenchmarkingFeePaymentMethod, { forWallet: FeePaymentMethodGetter; circuits: number }> =
|
|
95
99
|
{
|
|
96
100
|
// eslint-disable-next-line camelcase
|
|
@@ -121,6 +125,8 @@ export class ClientFlowsBenchmark {
|
|
|
121
125
|
|
|
122
126
|
public config: ClientFlowsConfig;
|
|
123
127
|
|
|
128
|
+
private proxyLogger: ProxyLogger;
|
|
129
|
+
|
|
124
130
|
constructor(testName?: string, setupOptions: Partial<SetupOptions & DeployL1ContractsArgs> = {}) {
|
|
125
131
|
this.logger = createLogger(`bench:client_flows${testName ? `:${testName}` : ''}`);
|
|
126
132
|
this.snapshotManager = createSnapshotManager(
|
|
@@ -130,6 +136,8 @@ export class ClientFlowsBenchmark {
|
|
|
130
136
|
{ ...setupOptions },
|
|
131
137
|
);
|
|
132
138
|
this.config = BENCHMARK_CONFIG === 'key_flows' ? KEY_FLOWS_CONFIG : FULL_FLOWS_CONFIG;
|
|
139
|
+
ProxyLogger.create();
|
|
140
|
+
this.proxyLogger = ProxyLogger.getInstance();
|
|
133
141
|
}
|
|
134
142
|
|
|
135
143
|
async setup() {
|
|
@@ -163,7 +171,7 @@ export class ClientFlowsBenchmark {
|
|
|
163
171
|
expect(balanceAfter).toEqual(balanceBefore + amount);
|
|
164
172
|
}
|
|
165
173
|
|
|
166
|
-
async createBenchmarkingAccountManager(type: 'ecdsar1' | 'schnorr') {
|
|
174
|
+
async createBenchmarkingAccountManager(pxe: PXE, type: 'ecdsar1' | 'schnorr') {
|
|
167
175
|
const benchysSecretKey = Fr.random();
|
|
168
176
|
const salt = Fr.random();
|
|
169
177
|
|
|
@@ -171,10 +179,10 @@ export class ClientFlowsBenchmark {
|
|
|
171
179
|
let benchysAccountManager;
|
|
172
180
|
if (type === 'schnorr') {
|
|
173
181
|
benchysPrivateSigningKey = deriveSigningKey(benchysSecretKey);
|
|
174
|
-
benchysAccountManager = await getSchnorrAccount(
|
|
182
|
+
benchysAccountManager = await getSchnorrAccount(pxe, benchysSecretKey, benchysPrivateSigningKey, salt);
|
|
175
183
|
} else if (type === 'ecdsar1') {
|
|
176
184
|
benchysPrivateSigningKey = randomBytes(32);
|
|
177
|
-
benchysAccountManager = await getEcdsaRAccount(
|
|
185
|
+
benchysAccountManager = await getEcdsaRAccount(pxe, benchysSecretKey, benchysPrivateSigningKey, salt);
|
|
178
186
|
} else {
|
|
179
187
|
throw new Error(`Unknown account type: ${type}`);
|
|
180
188
|
}
|
|
@@ -212,11 +220,15 @@ export class ClientFlowsBenchmark {
|
|
|
212
220
|
const l1Contracts = await aztecNode.getL1ContractAddresses();
|
|
213
221
|
const userPXEConfigWithContracts = {
|
|
214
222
|
...userPXEConfig,
|
|
215
|
-
proverEnabled:
|
|
223
|
+
proverEnabled: this.realProofs,
|
|
216
224
|
l1Contracts,
|
|
217
225
|
} as PXEServiceConfig;
|
|
218
226
|
|
|
219
|
-
this.userPXE = await createPXEService(this.aztecNode, userPXEConfigWithContracts,
|
|
227
|
+
this.userPXE = await createPXEService(this.aztecNode, userPXEConfigWithContracts, {
|
|
228
|
+
loggers: {
|
|
229
|
+
prover: this.proxyLogger.createLogger('pxe:bb:wasm:bundle:proxied'),
|
|
230
|
+
},
|
|
231
|
+
});
|
|
220
232
|
},
|
|
221
233
|
);
|
|
222
234
|
}
|
|
@@ -337,7 +349,7 @@ export class ClientFlowsBenchmark {
|
|
|
337
349
|
}
|
|
338
350
|
|
|
339
351
|
public async createAndFundBenchmarkingWallet(accountType: AccountType) {
|
|
340
|
-
const benchysAccountManager = await this.createBenchmarkingAccountManager(accountType);
|
|
352
|
+
const benchysAccountManager = await this.createBenchmarkingAccountManager(this.pxe, accountType);
|
|
341
353
|
const benchysWallet = await benchysAccountManager.getWallet();
|
|
342
354
|
const benchysAddress = benchysAccountManager.getAddress();
|
|
343
355
|
const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(
|
|
@@ -346,13 +358,19 @@ export class ClientFlowsBenchmark {
|
|
|
346
358
|
);
|
|
347
359
|
const paymentMethod = new FeeJuicePaymentMethodWithClaim(benchysWallet, claim);
|
|
348
360
|
await benchysAccountManager.deploy({ fee: { paymentMethod } }).wait();
|
|
349
|
-
// Register benchy on
|
|
350
|
-
await this.
|
|
361
|
+
// Register benchy on the user's PXE, where we're going to be interacting from
|
|
362
|
+
await this.userPXE.registerContract({
|
|
351
363
|
instance: benchysAccountManager.getInstance(),
|
|
352
364
|
artifact: accountType === 'ecdsar1' ? EcdsaRAccountContractArtifact : SchnorrAccountContractArtifact,
|
|
353
365
|
});
|
|
354
|
-
await this.
|
|
355
|
-
|
|
366
|
+
await this.userPXE.registerAccount(benchysWallet.getSecretKey(), benchysWallet.getCompleteAddress().partialAddress);
|
|
367
|
+
const entrypoint = await benchysAccountManager.getAccount();
|
|
368
|
+
return new AccountWalletWithSecretKey(
|
|
369
|
+
this.userPXE,
|
|
370
|
+
entrypoint,
|
|
371
|
+
benchysWallet.getSecretKey(),
|
|
372
|
+
benchysAccountManager.salt,
|
|
373
|
+
);
|
|
356
374
|
}
|
|
357
375
|
|
|
358
376
|
public async applyDeployAmmSnapshot() {
|
|
@@ -5,94 +5,16 @@ import { createLogger, logger } from '@aztec/foundation/log';
|
|
|
5
5
|
import { Timer } from '@aztec/foundation/timer';
|
|
6
6
|
import { WASMSimulator } from '@aztec/simulator/client';
|
|
7
7
|
import type { PrivateExecutionStep } from '@aztec/stdlib/kernel';
|
|
8
|
+
import type { ProvingTimings, SimulationTimings } from '@aztec/stdlib/tx';
|
|
8
9
|
|
|
9
10
|
import { Decoder } from 'msgpackr';
|
|
10
|
-
import assert from 'node:assert';
|
|
11
11
|
import { readFile, readdir, writeFile } from 'node:fs/promises';
|
|
12
12
|
import { join } from 'node:path';
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
type LogLevel = (typeof logLevel)[number];
|
|
16
|
-
|
|
17
|
-
type Log = {
|
|
18
|
-
type: LogLevel;
|
|
19
|
-
timestamp: number;
|
|
20
|
-
prefix: string;
|
|
21
|
-
message: string;
|
|
22
|
-
|
|
23
|
-
data: any;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const GATE_TYPES = [
|
|
27
|
-
'ecc_op',
|
|
28
|
-
'busread',
|
|
29
|
-
'lookup',
|
|
30
|
-
'pub_inputs',
|
|
31
|
-
'arithmetic',
|
|
32
|
-
'delta_range',
|
|
33
|
-
'elliptic',
|
|
34
|
-
'aux',
|
|
35
|
-
'poseidon2_external',
|
|
36
|
-
'poseidon2_internal',
|
|
37
|
-
'overflow',
|
|
38
|
-
] as const;
|
|
39
|
-
|
|
40
|
-
type GateType = (typeof GATE_TYPES)[number];
|
|
41
|
-
|
|
42
|
-
type StructuredTrace = {
|
|
43
|
-
[k in GateType]: number;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export class ProxyLogger {
|
|
47
|
-
private static instance: ProxyLogger;
|
|
48
|
-
private logs: Log[] = [];
|
|
49
|
-
|
|
50
|
-
private constructor() {}
|
|
51
|
-
|
|
52
|
-
static create() {
|
|
53
|
-
ProxyLogger.instance = new ProxyLogger();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
static getInstance() {
|
|
57
|
-
return ProxyLogger.instance;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
createLogger(prefix: string): Logger {
|
|
61
|
-
return new Proxy(createLogger(prefix), {
|
|
62
|
-
get: (target: Logger, prop: keyof Logger) => {
|
|
63
|
-
if (logLevel.includes(prop as (typeof logLevel)[number])) {
|
|
64
|
-
return function (this: Logger, ...data: Parameters<Logger[LogLevel]>) {
|
|
65
|
-
const loggingFn = prop as LogLevel;
|
|
66
|
-
const args = [loggingFn, prefix, ...data] as Parameters<ProxyLogger['handleLog']>;
|
|
67
|
-
ProxyLogger.getInstance().handleLog(...args);
|
|
68
|
-
target[loggingFn].call(this, ...[data[0], data[1]]);
|
|
69
|
-
};
|
|
70
|
-
} else {
|
|
71
|
-
return target[prop];
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
private handleLog(type: (typeof logLevel)[number], prefix: string, message: string, data: any) {
|
|
78
|
-
this.logs.unshift({ type, prefix, message, data, timestamp: Date.now() });
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
public flushLogs() {
|
|
82
|
-
this.logs = [];
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
public getLogs() {
|
|
86
|
-
return this.logs;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
14
|
+
import { type Log, type ProverType, ProxyLogger, generateBenchmark } from './benchmark.js';
|
|
89
15
|
|
|
90
16
|
type NativeProverConfig = { bbBinaryPath?: string; bbWorkingDirectory?: string };
|
|
91
17
|
|
|
92
|
-
type ProverType = 'wasm' | 'native';
|
|
93
|
-
|
|
94
|
-
type Step = { fnName: string; gateCount: number; accGateCount?: number };
|
|
95
|
-
|
|
96
18
|
async function createProver(config: NativeProverConfig = {}, log: Logger) {
|
|
97
19
|
const simulationProvider = new WASMSimulator();
|
|
98
20
|
if (!config.bbBinaryPath || !config.bbWorkingDirectory) {
|
|
@@ -106,33 +28,6 @@ async function createProver(config: NativeProverConfig = {}, log: Logger) {
|
|
|
106
28
|
}
|
|
107
29
|
}
|
|
108
30
|
|
|
109
|
-
function getMinimumTrace(logs: Log[]): StructuredTrace {
|
|
110
|
-
const minimumMessage = 'Trace details:';
|
|
111
|
-
const minimumMessageIndex = logs.findIndex(log => log.message.includes(minimumMessage));
|
|
112
|
-
const candidateLogs = logs.slice(minimumMessageIndex - GATE_TYPES.length, minimumMessageIndex);
|
|
113
|
-
|
|
114
|
-
const traceLogs = candidateLogs
|
|
115
|
-
.filter(log => GATE_TYPES.some(type => log.message.includes(type)))
|
|
116
|
-
.map(log => log.message.split(/\t|\n/))
|
|
117
|
-
.flat()
|
|
118
|
-
.map(log => log.replace(/\(mem: .*\)/, '').trim())
|
|
119
|
-
.filter(Boolean);
|
|
120
|
-
|
|
121
|
-
const traceSizes = traceLogs.map(log => {
|
|
122
|
-
const [gateType, gateSizeStr] = log
|
|
123
|
-
.replace(/\n.*\)$/, '')
|
|
124
|
-
.replace(/bb - /, '')
|
|
125
|
-
.split(':')
|
|
126
|
-
.map(s => s.trim());
|
|
127
|
-
const gateSize = parseInt(gateSizeStr);
|
|
128
|
-
assert(GATE_TYPES.includes(gateType as GateType), `Gate type ${gateType} is not recognized`);
|
|
129
|
-
return { [gateType]: gateSize };
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
assert(traceSizes.length === GATE_TYPES.length, 'Decoded trace sizes do not match expected amount of gate types');
|
|
133
|
-
return traceSizes.reduce((acc, curr) => ({ ...acc, ...curr }), {}) as StructuredTrace;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
31
|
async function main() {
|
|
137
32
|
ProxyLogger.create();
|
|
138
33
|
const proxyLogger = ProxyLogger.getInstance();
|
|
@@ -160,15 +55,15 @@ async function main() {
|
|
|
160
55
|
});
|
|
161
56
|
const profileFile = await readFile(join(ivcFolder, flow, 'profile.json'));
|
|
162
57
|
const profile = JSON.parse(profileFile.toString()) as {
|
|
163
|
-
|
|
58
|
+
timings: ProvingTimings | SimulationTimings;
|
|
164
59
|
steps: {
|
|
165
|
-
|
|
60
|
+
functionName: string;
|
|
166
61
|
gateCount: number;
|
|
167
62
|
timings: { witgen: number; gateCount: number };
|
|
168
63
|
}[];
|
|
169
64
|
};
|
|
170
65
|
const privateExecutionSteps: PrivateExecutionStep[] = profile.steps.map((step, i) => ({
|
|
171
|
-
functionName: step.
|
|
66
|
+
functionName: step.functionName,
|
|
172
67
|
gateCount: step.gateCount,
|
|
173
68
|
bytecode: stepsFromFile[i].bytecode,
|
|
174
69
|
// TODO(AD) do we still want to take this from witness.json?
|
|
@@ -179,7 +74,6 @@ async function main() {
|
|
|
179
74
|
gateCount: step.timings.witgen,
|
|
180
75
|
},
|
|
181
76
|
}));
|
|
182
|
-
let stats: { duration: number; eventName: string; proofSize: number } | undefined;
|
|
183
77
|
|
|
184
78
|
let error: any;
|
|
185
79
|
let currentLogs: Log[] = [];
|
|
@@ -195,38 +89,10 @@ async function main() {
|
|
|
195
89
|
// Extract logs from this run from the proxy and write them to disk unconditionally
|
|
196
90
|
currentLogs = proxyLogger.getLogs();
|
|
197
91
|
await writeFile(join(ivcFolder, flow, 'logs.json'), JSON.stringify(currentLogs, null, 2));
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
stats = currentLogs[0].data as { duration: number; eventName: string; proofSize: number };
|
|
92
|
+
if (!(profile.timings as ProvingTimings).proving) {
|
|
93
|
+
(profile.timings as ProvingTimings).proving = provingTime;
|
|
201
94
|
}
|
|
202
|
-
|
|
203
|
-
const minimumTrace = getMinimumTrace(currentLogs);
|
|
204
|
-
|
|
205
|
-
const steps = profile.steps.reduce<Step[]>((acc, step, i) => {
|
|
206
|
-
const previousAccGateCount = i === 0 ? 0 : acc[i - 1].accGateCount!;
|
|
207
|
-
return [
|
|
208
|
-
...acc,
|
|
209
|
-
{
|
|
210
|
-
fnName: step.fnName,
|
|
211
|
-
gateCount: step.gateCount,
|
|
212
|
-
accGateCount: previousAccGateCount + step.gateCount,
|
|
213
|
-
timings: {
|
|
214
|
-
witgen: step.timings.witgen,
|
|
215
|
-
},
|
|
216
|
-
},
|
|
217
|
-
];
|
|
218
|
-
}, []);
|
|
219
|
-
const totalGateCount = steps[steps.length - 1].accGateCount;
|
|
220
|
-
const benchmark = {
|
|
221
|
-
syncTime: profile.syncTime,
|
|
222
|
-
provingTime,
|
|
223
|
-
proverType,
|
|
224
|
-
minimumTrace: minimumTrace,
|
|
225
|
-
totalGateCount,
|
|
226
|
-
stats,
|
|
227
|
-
steps,
|
|
228
|
-
error,
|
|
229
|
-
};
|
|
95
|
+
const benchmark = generateBenchmark(flow, currentLogs, profile.timings, privateExecutionSteps, proverType, error);
|
|
230
96
|
await writeFile(join(ivcFolder, flow, 'benchmark.json'), JSON.stringify(benchmark, null, 2));
|
|
231
97
|
proxyLogger.flushLogs();
|
|
232
98
|
}
|
package/src/bench/utils.ts
CHANGED
|
@@ -53,7 +53,7 @@ type MetricFilter = {
|
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
// See https://github.com/benchmark-action/github-action-benchmark/blob/e3c661617bc6aa55f26ae4457c737a55545a86a4/src/extract.ts#L659-L670
|
|
56
|
-
type GithubActionBenchmarkResult = {
|
|
56
|
+
export type GithubActionBenchmarkResult = {
|
|
57
57
|
name: string;
|
|
58
58
|
value: number;
|
|
59
59
|
range?: string;
|
|
@@ -82,6 +82,7 @@ export class P2PNetworkTest {
|
|
|
82
82
|
initialValidatorConfig: AztecNodeConfig,
|
|
83
83
|
// If set enable metrics collection
|
|
84
84
|
private metricsPort?: number,
|
|
85
|
+
startProverNode?: boolean,
|
|
85
86
|
) {
|
|
86
87
|
this.logger = createLogger(`e2e:e2e_p2p:${testName}`);
|
|
87
88
|
|
|
@@ -105,6 +106,7 @@ export class P2PNetworkTest {
|
|
|
105
106
|
salt: 420,
|
|
106
107
|
metricsPort: metricsPort,
|
|
107
108
|
numberOfInitialFundedAccounts: 2,
|
|
109
|
+
startProverNode,
|
|
108
110
|
},
|
|
109
111
|
{
|
|
110
112
|
...initialValidatorConfig,
|
|
@@ -124,12 +126,14 @@ export class P2PNetworkTest {
|
|
|
124
126
|
basePort,
|
|
125
127
|
metricsPort,
|
|
126
128
|
initialConfig,
|
|
129
|
+
startProverNode,
|
|
127
130
|
}: {
|
|
128
131
|
testName: string;
|
|
129
132
|
numberOfNodes: number;
|
|
130
133
|
basePort?: number;
|
|
131
134
|
metricsPort?: number;
|
|
132
135
|
initialConfig?: Partial<AztecNodeConfig>;
|
|
136
|
+
startProverNode?: boolean;
|
|
133
137
|
}) {
|
|
134
138
|
const port = basePort || (await getPort());
|
|
135
139
|
|
|
@@ -141,7 +145,15 @@ export class P2PNetworkTest {
|
|
|
141
145
|
bootstrapNodeEnr,
|
|
142
146
|
);
|
|
143
147
|
|
|
144
|
-
return new P2PNetworkTest(
|
|
148
|
+
return new P2PNetworkTest(
|
|
149
|
+
testName,
|
|
150
|
+
bootstrapNodeEnr,
|
|
151
|
+
port,
|
|
152
|
+
numberOfNodes,
|
|
153
|
+
initialValidatorConfig,
|
|
154
|
+
metricsPort,
|
|
155
|
+
startProverNode,
|
|
156
|
+
);
|
|
145
157
|
}
|
|
146
158
|
|
|
147
159
|
get fundedAccount() {
|
package/src/e2e_p2p/shared.ts
CHANGED
|
@@ -48,7 +48,7 @@ export const createPXEServiceAndSubmitTransactions = async (
|
|
|
48
48
|
): Promise<NodeContext> => {
|
|
49
49
|
const rpcConfig = getRpcConfig();
|
|
50
50
|
rpcConfig.proverEnabled = false;
|
|
51
|
-
const pxeService = await createPXEService(node, rpcConfig, true);
|
|
51
|
+
const pxeService = await createPXEService(node, rpcConfig, { useLogSuffix: true });
|
|
52
52
|
|
|
53
53
|
const account = await getSchnorrAccount(
|
|
54
54
|
pxeService,
|
|
@@ -71,7 +71,7 @@ export async function createPXEServiceAndPrepareTransactions(
|
|
|
71
71
|
): Promise<{ pxeService: PXEService; txs: ProvenTx[]; node: AztecNodeService }> {
|
|
72
72
|
const rpcConfig = getRpcConfig();
|
|
73
73
|
rpcConfig.proverEnabled = false;
|
|
74
|
-
const pxe = await createPXEService(node, rpcConfig, true);
|
|
74
|
+
const pxe = await createPXEService(node, rpcConfig, { useLogSuffix: true });
|
|
75
75
|
|
|
76
76
|
const account = await getSchnorrAccount(pxe, fundedAccount.secret, fundedAccount.signingKey, fundedAccount.salt);
|
|
77
77
|
await account.register();
|
|
@@ -387,10 +387,13 @@ async function setupFromFresh(
|
|
|
387
387
|
logger.info(`Funding rewardDistributor in ${rewardDistributorMintTxHash}`);
|
|
388
388
|
}
|
|
389
389
|
|
|
390
|
+
const dateProvider = new TestDateProvider();
|
|
391
|
+
|
|
390
392
|
const watcher = new AnvilTestWatcher(
|
|
391
393
|
new EthCheatCodesWithState(aztecNodeConfig.l1RpcUrls),
|
|
392
394
|
deployL1ContractsValues.l1ContractAddresses.rollupAddress,
|
|
393
395
|
deployL1ContractsValues.l1Client,
|
|
396
|
+
dateProvider,
|
|
394
397
|
);
|
|
395
398
|
await watcher.start();
|
|
396
399
|
|
|
@@ -423,7 +426,6 @@ async function setupFromFresh(
|
|
|
423
426
|
await blobSink.start();
|
|
424
427
|
|
|
425
428
|
logger.verbose('Creating and synching an aztec node...');
|
|
426
|
-
const dateProvider = new TestDateProvider();
|
|
427
429
|
const aztecNode = await AztecNodeService.createAndSync(
|
|
428
430
|
aztecNodeConfig,
|
|
429
431
|
{ telemetry, dateProvider },
|
|
@@ -523,15 +525,16 @@ async function setupFromState(statePath: string, logger: Logger): Promise<Subsys
|
|
|
523
525
|
logger.verbose('Creating ETH clients...');
|
|
524
526
|
const l1Client = createExtendedL1Client(aztecNodeConfig.l1RpcUrls, mnemonicToAccount(MNEMONIC));
|
|
525
527
|
|
|
528
|
+
const dateProvider = new TestDateProvider();
|
|
526
529
|
const watcher = new AnvilTestWatcher(
|
|
527
530
|
new EthCheatCodesWithState(aztecNodeConfig.l1RpcUrls),
|
|
528
531
|
aztecNodeConfig.l1Contracts.rollupAddress,
|
|
529
532
|
l1Client,
|
|
533
|
+
dateProvider,
|
|
530
534
|
);
|
|
531
535
|
await watcher.start();
|
|
532
536
|
|
|
533
537
|
const telemetry = initTelemetryClient(getTelemetryConfig());
|
|
534
|
-
const dateProvider = new TestDateProvider();
|
|
535
538
|
const blobSink = await createBlobSinkServer(
|
|
536
539
|
{
|
|
537
540
|
l1ChainId: aztecNodeConfig.l1ChainId,
|
package/src/fixtures/utils.ts
CHANGED
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
type DeployL1ContractsReturnType,
|
|
34
34
|
ForwarderContract,
|
|
35
35
|
NULL_KEY,
|
|
36
|
+
type Operator,
|
|
36
37
|
createExtendedL1Client,
|
|
37
38
|
deployL1Contracts,
|
|
38
39
|
getL1ContractsConfigEnvVars,
|
|
@@ -59,8 +60,8 @@ import {
|
|
|
59
60
|
} from '@aztec/pxe/server';
|
|
60
61
|
import type { SequencerClient } from '@aztec/sequencer-client';
|
|
61
62
|
import type { TestSequencerClient } from '@aztec/sequencer-client/test';
|
|
62
|
-
import { WASMSimulator } from '@aztec/simulator/client';
|
|
63
|
-
import {
|
|
63
|
+
import { MemoryCircuitRecorder, SimulationProviderRecorderWrapper, WASMSimulator } from '@aztec/simulator/client';
|
|
64
|
+
import { FileCircuitRecorder } from '@aztec/simulator/testing';
|
|
64
65
|
import { getContractClassFromArtifact, getContractInstanceFromDeployParams } from '@aztec/stdlib/contract';
|
|
65
66
|
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
66
67
|
import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
|
|
@@ -171,12 +172,15 @@ export async function setupPXEService(
|
|
|
171
172
|
}
|
|
172
173
|
|
|
173
174
|
const simulationProvider = new WASMSimulator();
|
|
174
|
-
const
|
|
175
|
+
const recorder = process.env.CIRCUIT_RECORD_DIR
|
|
176
|
+
? new FileCircuitRecorder(process.env.CIRCUIT_RECORD_DIR)
|
|
177
|
+
: new MemoryCircuitRecorder();
|
|
178
|
+
const simulationProviderWithRecorder = new SimulationProviderRecorderWrapper(simulationProvider, recorder);
|
|
175
179
|
const pxe = await createPXEServiceWithSimulationProvider(
|
|
176
180
|
aztecNode,
|
|
177
181
|
simulationProviderWithRecorder,
|
|
178
182
|
pxeServiceConfig,
|
|
179
|
-
useLogSuffix,
|
|
183
|
+
{ useLogSuffix },
|
|
180
184
|
);
|
|
181
185
|
|
|
182
186
|
const teardown = async () => {
|
|
@@ -280,7 +284,7 @@ export type SetupOptions = {
|
|
|
280
284
|
/** Salt to use in L1 contract deployment */
|
|
281
285
|
salt?: number;
|
|
282
286
|
/** An initial set of validators */
|
|
283
|
-
initialValidators?:
|
|
287
|
+
initialValidators?: Operator[];
|
|
284
288
|
/** Anvil Start time */
|
|
285
289
|
l1StartTime?: number;
|
|
286
290
|
/** The anvil time where we should at the earliest be seeing L2 blocks */
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This module exposes the ability to capture the private exection steps that go into our "Client IVC" prover.
|
|
3
|
-
* These are used for debugging and benchmarking barretenberg (the prover component).
|
|
4
|
-
*/
|
|
5
|
-
import type { ContractFunctionInteraction, DeployMethod, DeployOptions, ProfileMethodOptions } from '@aztec/aztec.js/contracts';
|
|
6
|
-
export declare function capturePrivateExecutionStepsIfEnvSet(label: string, interaction: ContractFunctionInteraction | DeployMethod, opts?: Omit<ProfileMethodOptions & DeployOptions, 'profileMode'>, expectedSteps?: number): Promise<void>;
|
|
7
|
-
//# sourceMappingURL=capture_private_execution_steps.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"capture_private_execution_steps.d.ts","sourceRoot":"","sources":["../../src/shared/capture_private_execution_steps.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EACV,2BAA2B,EAC3B,YAAY,EACZ,aAAa,EACb,oBAAoB,EACrB,MAAM,2BAA2B,CAAC;AASnC,wBAAsB,oCAAoC,CACxD,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,2BAA2B,GAAG,YAAY,EACvD,IAAI,CAAC,EAAE,IAAI,CAAC,oBAAoB,GAAG,aAAa,EAAE,aAAa,CAAC,EAChE,aAAa,CAAC,EAAE,MAAM,iBA6CvB"}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This module exposes the ability to capture the private exection steps that go into our "Client IVC" prover.
|
|
3
|
-
* These are used for debugging and benchmarking barretenberg (the prover component).
|
|
4
|
-
*/ import { createLogger } from '@aztec/foundation/log';
|
|
5
|
-
import { serializePrivateExecutionSteps } from '@aztec/stdlib/kernel';
|
|
6
|
-
import { promises as fs } from 'fs';
|
|
7
|
-
import path from 'path';
|
|
8
|
-
const logger = createLogger('e2e:capture-private-execution-steps');
|
|
9
|
-
export async function capturePrivateExecutionStepsIfEnvSet(label, interaction, opts, expectedSteps) {
|
|
10
|
-
// Not included in env_var.ts as internal to e2e tests.
|
|
11
|
-
const ivcFolder = process.env.CAPTURE_IVC_FOLDER;
|
|
12
|
-
if (!ivcFolder) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
const profileMode = [
|
|
16
|
-
'execution-steps',
|
|
17
|
-
'full'
|
|
18
|
-
].includes(process.env.PROFILE_MODE ?? '') ? process.env.PROFILE_MODE : 'execution-steps';
|
|
19
|
-
logger.info(`Capturing client ivc execution profile for ${label} in mode ${profileMode}`);
|
|
20
|
-
const result = await interaction.profile({
|
|
21
|
-
...opts,
|
|
22
|
-
profileMode
|
|
23
|
-
});
|
|
24
|
-
if (expectedSteps !== undefined && result.executionSteps.length !== expectedSteps) {
|
|
25
|
-
throw new Error(`Expected ${expectedSteps} execution steps, got ${result.executionSteps.length}`);
|
|
26
|
-
}
|
|
27
|
-
const resultsDirectory = path.join(ivcFolder, label);
|
|
28
|
-
logger.info(`Writing private execution steps to ${resultsDirectory}`);
|
|
29
|
-
await fs.mkdir(resultsDirectory, {
|
|
30
|
-
recursive: true
|
|
31
|
-
});
|
|
32
|
-
// Write the client IVC files read by the prover.
|
|
33
|
-
const ivcInputsPath = path.join(resultsDirectory, 'ivc-inputs.msgpack');
|
|
34
|
-
await fs.writeFile(ivcInputsPath, serializePrivateExecutionSteps(result.executionSteps));
|
|
35
|
-
if (profileMode === 'full') {
|
|
36
|
-
// If we have gate counts, write the steps in human-readable format.
|
|
37
|
-
await fs.writeFile(path.join(resultsDirectory, 'profile.json'), JSON.stringify({
|
|
38
|
-
timings: result.timings,
|
|
39
|
-
steps: result.executionSteps.map((step)=>({
|
|
40
|
-
fnName: step.functionName,
|
|
41
|
-
gateCount: step.gateCount,
|
|
42
|
-
timings: step.timings
|
|
43
|
-
}))
|
|
44
|
-
}, null, 2));
|
|
45
|
-
// In full mode, we also write the raw witnesses in a more human-readable format.
|
|
46
|
-
await fs.writeFile(path.join(resultsDirectory, 'witnesses.json'), JSON.stringify(result.executionSteps.map((step)=>Object.fromEntries(step.witness))));
|
|
47
|
-
}
|
|
48
|
-
logger.info(`Wrote private execution steps to ${resultsDirectory}`);
|
|
49
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This module exposes the ability to capture the private exection steps that go into our "Client IVC" prover.
|
|
3
|
-
* These are used for debugging and benchmarking barretenberg (the prover component).
|
|
4
|
-
*/
|
|
5
|
-
import type {
|
|
6
|
-
ContractFunctionInteraction,
|
|
7
|
-
DeployMethod,
|
|
8
|
-
DeployOptions,
|
|
9
|
-
ProfileMethodOptions,
|
|
10
|
-
} from '@aztec/aztec.js/contracts';
|
|
11
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
12
|
-
import { serializePrivateExecutionSteps } from '@aztec/stdlib/kernel';
|
|
13
|
-
|
|
14
|
-
import { promises as fs } from 'fs';
|
|
15
|
-
import path from 'path';
|
|
16
|
-
|
|
17
|
-
const logger = createLogger('e2e:capture-private-execution-steps');
|
|
18
|
-
|
|
19
|
-
export async function capturePrivateExecutionStepsIfEnvSet(
|
|
20
|
-
label: string,
|
|
21
|
-
interaction: ContractFunctionInteraction | DeployMethod,
|
|
22
|
-
opts?: Omit<ProfileMethodOptions & DeployOptions, 'profileMode'>,
|
|
23
|
-
expectedSteps?: number,
|
|
24
|
-
) {
|
|
25
|
-
// Not included in env_var.ts as internal to e2e tests.
|
|
26
|
-
const ivcFolder = process.env.CAPTURE_IVC_FOLDER;
|
|
27
|
-
if (!ivcFolder) {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
const profileMode = ['execution-steps', 'full'].includes(process.env.PROFILE_MODE ?? '')
|
|
31
|
-
? (process.env.PROFILE_MODE as 'full' | 'execution-steps')
|
|
32
|
-
: 'execution-steps';
|
|
33
|
-
logger.info(`Capturing client ivc execution profile for ${label} in mode ${profileMode}`);
|
|
34
|
-
const result = await interaction.profile({ ...opts, profileMode });
|
|
35
|
-
if (expectedSteps !== undefined && result.executionSteps.length !== expectedSteps) {
|
|
36
|
-
throw new Error(`Expected ${expectedSteps} execution steps, got ${result.executionSteps.length}`);
|
|
37
|
-
}
|
|
38
|
-
const resultsDirectory = path.join(ivcFolder, label);
|
|
39
|
-
logger.info(`Writing private execution steps to ${resultsDirectory}`);
|
|
40
|
-
await fs.mkdir(resultsDirectory, { recursive: true });
|
|
41
|
-
// Write the client IVC files read by the prover.
|
|
42
|
-
const ivcInputsPath = path.join(resultsDirectory, 'ivc-inputs.msgpack');
|
|
43
|
-
await fs.writeFile(ivcInputsPath, serializePrivateExecutionSteps(result.executionSteps));
|
|
44
|
-
if (profileMode === 'full') {
|
|
45
|
-
// If we have gate counts, write the steps in human-readable format.
|
|
46
|
-
await fs.writeFile(
|
|
47
|
-
path.join(resultsDirectory, 'profile.json'),
|
|
48
|
-
JSON.stringify(
|
|
49
|
-
{
|
|
50
|
-
timings: result.timings,
|
|
51
|
-
steps: result.executionSteps.map(step => ({
|
|
52
|
-
fnName: step.functionName,
|
|
53
|
-
gateCount: step.gateCount,
|
|
54
|
-
timings: step.timings,
|
|
55
|
-
})),
|
|
56
|
-
},
|
|
57
|
-
null,
|
|
58
|
-
2,
|
|
59
|
-
),
|
|
60
|
-
);
|
|
61
|
-
// In full mode, we also write the raw witnesses in a more human-readable format.
|
|
62
|
-
await fs.writeFile(
|
|
63
|
-
path.join(resultsDirectory, 'witnesses.json'),
|
|
64
|
-
JSON.stringify(result.executionSteps.map(step => Object.fromEntries(step.witness))),
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
logger.info(`Wrote private execution steps to ${resultsDirectory}`);
|
|
68
|
-
}
|