@aztec/end-to-end 0.87.4 → 0.87.5
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/client_flows_benchmark.d.ts +3 -5
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.js +14 -24
- package/dest/bench/client_flows/data_extractor.d.ts +21 -0
- package/dest/bench/client_flows/data_extractor.d.ts.map +1 -1
- package/dest/bench/client_flows/data_extractor.js +122 -5
- package/dest/bench/utils.d.ts +0 -7
- package/dest/bench/utils.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +2 -6
- package/dest/fixtures/utils.d.ts.map +1 -1
- package/dest/fixtures/utils.js +4 -7
- package/dest/shared/capture_private_execution_steps.d.ts +7 -0
- package/dest/shared/capture_private_execution_steps.d.ts.map +1 -0
- package/dest/shared/capture_private_execution_steps.js +49 -0
- package/package.json +34 -34
- package/src/bench/client_flows/client_flows_benchmark.ts +10 -28
- package/src/bench/client_flows/data_extractor.ts +142 -8
- package/src/bench/utils.ts +1 -1
- package/src/e2e_p2p/shared.ts +2 -2
- package/src/fixtures/utils.ts +4 -7
- package/src/shared/capture_private_execution_steps.ts +68 -0
- package/dest/bench/client_flows/benchmark.d.ts +0 -59
- package/dest/bench/client_flows/benchmark.d.ts.map +0 -1
- package/dest/bench/client_flows/benchmark.js +0 -240
- package/src/bench/client_flows/benchmark.ts +0 -308
|
@@ -2,7 +2,6 @@ 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,
|
|
6
5
|
AztecAddress,
|
|
7
6
|
type AztecNode,
|
|
8
7
|
FeeJuicePaymentMethod,
|
|
@@ -48,7 +47,6 @@ import {
|
|
|
48
47
|
FeeJuicePortalTestingHarnessFactory,
|
|
49
48
|
type GasBridgingTestHarness,
|
|
50
49
|
} from '../../shared/gas_portal_test_harness.js';
|
|
51
|
-
import { ProxyLogger } from './benchmark.js';
|
|
52
50
|
import { type ClientFlowsConfig, FULL_FLOWS_CONFIG, KEY_FLOWS_CONFIG } from './config.js';
|
|
53
51
|
|
|
54
52
|
const { E2E_DATA_PATH: dataPath, BENCHMARK_CONFIG } = process.env;
|
|
@@ -93,8 +91,6 @@ export class ClientFlowsBenchmark {
|
|
|
93
91
|
// PXE used by the benchmarking user. It can be set up with client-side proving enabled
|
|
94
92
|
public userPXE!: PXE;
|
|
95
93
|
|
|
96
|
-
public realProofs = ['true', '1'].includes(process.env.REAL_PROOFS ?? '');
|
|
97
|
-
|
|
98
94
|
public paymentMethods: Record<BenchmarkingFeePaymentMethod, { forWallet: FeePaymentMethodGetter; circuits: number }> =
|
|
99
95
|
{
|
|
100
96
|
// eslint-disable-next-line camelcase
|
|
@@ -125,8 +121,6 @@ export class ClientFlowsBenchmark {
|
|
|
125
121
|
|
|
126
122
|
public config: ClientFlowsConfig;
|
|
127
123
|
|
|
128
|
-
private proxyLogger: ProxyLogger;
|
|
129
|
-
|
|
130
124
|
constructor(testName?: string, setupOptions: Partial<SetupOptions & DeployL1ContractsArgs> = {}) {
|
|
131
125
|
this.logger = createLogger(`bench:client_flows${testName ? `:${testName}` : ''}`);
|
|
132
126
|
this.snapshotManager = createSnapshotManager(
|
|
@@ -136,8 +130,6 @@ export class ClientFlowsBenchmark {
|
|
|
136
130
|
{ ...setupOptions },
|
|
137
131
|
);
|
|
138
132
|
this.config = BENCHMARK_CONFIG === 'key_flows' ? KEY_FLOWS_CONFIG : FULL_FLOWS_CONFIG;
|
|
139
|
-
ProxyLogger.create();
|
|
140
|
-
this.proxyLogger = ProxyLogger.getInstance();
|
|
141
133
|
}
|
|
142
134
|
|
|
143
135
|
async setup() {
|
|
@@ -171,7 +163,7 @@ export class ClientFlowsBenchmark {
|
|
|
171
163
|
expect(balanceAfter).toEqual(balanceBefore + amount);
|
|
172
164
|
}
|
|
173
165
|
|
|
174
|
-
async createBenchmarkingAccountManager(
|
|
166
|
+
async createBenchmarkingAccountManager(type: 'ecdsar1' | 'schnorr') {
|
|
175
167
|
const benchysSecretKey = Fr.random();
|
|
176
168
|
const salt = Fr.random();
|
|
177
169
|
|
|
@@ -179,10 +171,10 @@ export class ClientFlowsBenchmark {
|
|
|
179
171
|
let benchysAccountManager;
|
|
180
172
|
if (type === 'schnorr') {
|
|
181
173
|
benchysPrivateSigningKey = deriveSigningKey(benchysSecretKey);
|
|
182
|
-
benchysAccountManager = await getSchnorrAccount(
|
|
174
|
+
benchysAccountManager = await getSchnorrAccount(this.userPXE, benchysSecretKey, benchysPrivateSigningKey, salt);
|
|
183
175
|
} else if (type === 'ecdsar1') {
|
|
184
176
|
benchysPrivateSigningKey = randomBytes(32);
|
|
185
|
-
benchysAccountManager = await getEcdsaRAccount(
|
|
177
|
+
benchysAccountManager = await getEcdsaRAccount(this.userPXE, benchysSecretKey, benchysPrivateSigningKey, salt);
|
|
186
178
|
} else {
|
|
187
179
|
throw new Error(`Unknown account type: ${type}`);
|
|
188
180
|
}
|
|
@@ -220,15 +212,11 @@ export class ClientFlowsBenchmark {
|
|
|
220
212
|
const l1Contracts = await aztecNode.getL1ContractAddresses();
|
|
221
213
|
const userPXEConfigWithContracts = {
|
|
222
214
|
...userPXEConfig,
|
|
223
|
-
proverEnabled:
|
|
215
|
+
proverEnabled: ['true', '1'].includes(process.env.REAL_PROOFS ?? ''),
|
|
224
216
|
l1Contracts,
|
|
225
217
|
} as PXEServiceConfig;
|
|
226
218
|
|
|
227
|
-
this.userPXE = await createPXEService(this.aztecNode, userPXEConfigWithContracts,
|
|
228
|
-
loggers: {
|
|
229
|
-
prover: this.proxyLogger.createLogger('pxe:bb:wasm:bundle:proxied'),
|
|
230
|
-
},
|
|
231
|
-
});
|
|
219
|
+
this.userPXE = await createPXEService(this.aztecNode, userPXEConfigWithContracts, 'pxe-user');
|
|
232
220
|
},
|
|
233
221
|
);
|
|
234
222
|
}
|
|
@@ -349,7 +337,7 @@ export class ClientFlowsBenchmark {
|
|
|
349
337
|
}
|
|
350
338
|
|
|
351
339
|
public async createAndFundBenchmarkingWallet(accountType: AccountType) {
|
|
352
|
-
const benchysAccountManager = await this.createBenchmarkingAccountManager(
|
|
340
|
+
const benchysAccountManager = await this.createBenchmarkingAccountManager(accountType);
|
|
353
341
|
const benchysWallet = await benchysAccountManager.getWallet();
|
|
354
342
|
const benchysAddress = benchysAccountManager.getAddress();
|
|
355
343
|
const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(
|
|
@@ -358,19 +346,13 @@ export class ClientFlowsBenchmark {
|
|
|
358
346
|
);
|
|
359
347
|
const paymentMethod = new FeeJuicePaymentMethodWithClaim(benchysWallet, claim);
|
|
360
348
|
await benchysAccountManager.deploy({ fee: { paymentMethod } }).wait();
|
|
361
|
-
// Register benchy on
|
|
362
|
-
await this.
|
|
349
|
+
// Register benchy on admin's PXE so we can check its balances
|
|
350
|
+
await this.pxe.registerContract({
|
|
363
351
|
instance: benchysAccountManager.getInstance(),
|
|
364
352
|
artifact: accountType === 'ecdsar1' ? EcdsaRAccountContractArtifact : SchnorrAccountContractArtifact,
|
|
365
353
|
});
|
|
366
|
-
await this.
|
|
367
|
-
|
|
368
|
-
return new AccountWalletWithSecretKey(
|
|
369
|
-
this.userPXE,
|
|
370
|
-
entrypoint,
|
|
371
|
-
benchysWallet.getSecretKey(),
|
|
372
|
-
benchysAccountManager.salt,
|
|
373
|
-
);
|
|
354
|
+
await this.pxe.registerAccount(benchysWallet.getSecretKey(), benchysWallet.getCompleteAddress().partialAddress);
|
|
355
|
+
return benchysWallet;
|
|
374
356
|
}
|
|
375
357
|
|
|
376
358
|
public async applyDeployAmmSnapshot() {
|
|
@@ -5,16 +5,94 @@ 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';
|
|
9
8
|
|
|
10
9
|
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
|
-
|
|
14
|
+
const logLevel = ['silent', 'fatal', 'error', 'warn', 'info', 'verbose', 'debug', 'trace'] as const;
|
|
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
|
+
}
|
|
15
89
|
|
|
16
90
|
type NativeProverConfig = { bbBinaryPath?: string; bbWorkingDirectory?: string };
|
|
17
91
|
|
|
92
|
+
type ProverType = 'wasm' | 'native';
|
|
93
|
+
|
|
94
|
+
type Step = { fnName: string; gateCount: number; accGateCount?: number };
|
|
95
|
+
|
|
18
96
|
async function createProver(config: NativeProverConfig = {}, log: Logger) {
|
|
19
97
|
const simulationProvider = new WASMSimulator();
|
|
20
98
|
if (!config.bbBinaryPath || !config.bbWorkingDirectory) {
|
|
@@ -28,6 +106,33 @@ async function createProver(config: NativeProverConfig = {}, log: Logger) {
|
|
|
28
106
|
}
|
|
29
107
|
}
|
|
30
108
|
|
|
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
|
+
|
|
31
136
|
async function main() {
|
|
32
137
|
ProxyLogger.create();
|
|
33
138
|
const proxyLogger = ProxyLogger.getInstance();
|
|
@@ -55,15 +160,15 @@ async function main() {
|
|
|
55
160
|
});
|
|
56
161
|
const profileFile = await readFile(join(ivcFolder, flow, 'profile.json'));
|
|
57
162
|
const profile = JSON.parse(profileFile.toString()) as {
|
|
58
|
-
|
|
163
|
+
syncTime: number;
|
|
59
164
|
steps: {
|
|
60
|
-
|
|
165
|
+
fnName: string;
|
|
61
166
|
gateCount: number;
|
|
62
167
|
timings: { witgen: number; gateCount: number };
|
|
63
168
|
}[];
|
|
64
169
|
};
|
|
65
170
|
const privateExecutionSteps: PrivateExecutionStep[] = profile.steps.map((step, i) => ({
|
|
66
|
-
functionName: step.
|
|
171
|
+
functionName: step.fnName,
|
|
67
172
|
gateCount: step.gateCount,
|
|
68
173
|
bytecode: stepsFromFile[i].bytecode,
|
|
69
174
|
// TODO(AD) do we still want to take this from witness.json?
|
|
@@ -74,6 +179,7 @@ async function main() {
|
|
|
74
179
|
gateCount: step.timings.witgen,
|
|
75
180
|
},
|
|
76
181
|
}));
|
|
182
|
+
let stats: { duration: number; eventName: string; proofSize: number } | undefined;
|
|
77
183
|
|
|
78
184
|
let error: any;
|
|
79
185
|
let currentLogs: Log[] = [];
|
|
@@ -89,10 +195,38 @@ async function main() {
|
|
|
89
195
|
// Extract logs from this run from the proxy and write them to disk unconditionally
|
|
90
196
|
currentLogs = proxyLogger.getLogs();
|
|
91
197
|
await writeFile(join(ivcFolder, flow, 'logs.json'), JSON.stringify(currentLogs, null, 2));
|
|
92
|
-
|
|
93
|
-
|
|
198
|
+
|
|
199
|
+
if (!error) {
|
|
200
|
+
stats = currentLogs[0].data as { duration: number; eventName: string; proofSize: number };
|
|
94
201
|
}
|
|
95
|
-
|
|
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
|
+
};
|
|
96
230
|
await writeFile(join(ivcFolder, flow, 'benchmark.json'), JSON.stringify(benchmark, null, 2));
|
|
97
231
|
proxyLogger.flushLogs();
|
|
98
232
|
}
|
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
|
-
|
|
56
|
+
type GithubActionBenchmarkResult = {
|
|
57
57
|
name: string;
|
|
58
58
|
value: number;
|
|
59
59
|
range?: string;
|
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,
|
|
51
|
+
const pxeService = await createPXEService(node, rpcConfig, 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,
|
|
74
|
+
const pxe = await createPXEService(node, rpcConfig, true);
|
|
75
75
|
|
|
76
76
|
const account = await getSchnorrAccount(pxe, fundedAccount.secret, fundedAccount.signingKey, fundedAccount.salt);
|
|
77
77
|
await account.register();
|
package/src/fixtures/utils.ts
CHANGED
|
@@ -59,8 +59,8 @@ import {
|
|
|
59
59
|
} from '@aztec/pxe/server';
|
|
60
60
|
import type { SequencerClient } from '@aztec/sequencer-client';
|
|
61
61
|
import type { TestSequencerClient } from '@aztec/sequencer-client/test';
|
|
62
|
-
import {
|
|
63
|
-
import {
|
|
62
|
+
import { WASMSimulator } from '@aztec/simulator/client';
|
|
63
|
+
import { SimulationProviderRecorderWrapper } from '@aztec/simulator/testing';
|
|
64
64
|
import { getContractClassFromArtifact, getContractInstanceFromDeployParams } from '@aztec/stdlib/contract';
|
|
65
65
|
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
66
66
|
import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
|
|
@@ -171,15 +171,12 @@ export async function setupPXEService(
|
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
const simulationProvider = new WASMSimulator();
|
|
174
|
-
const
|
|
175
|
-
? new FileCircuitRecorder(process.env.CIRCUIT_RECORD_DIR)
|
|
176
|
-
: new MemoryCircuitRecorder();
|
|
177
|
-
const simulationProviderWithRecorder = new SimulationProviderRecorderWrapper(simulationProvider, recorder);
|
|
174
|
+
const simulationProviderWithRecorder = new SimulationProviderRecorderWrapper(simulationProvider);
|
|
178
175
|
const pxe = await createPXEServiceWithSimulationProvider(
|
|
179
176
|
aztecNode,
|
|
180
177
|
simulationProviderWithRecorder,
|
|
181
178
|
pxeServiceConfig,
|
|
182
|
-
|
|
179
|
+
useLogSuffix,
|
|
183
180
|
);
|
|
184
181
|
|
|
185
182
|
const teardown = async () => {
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type { ContractFunctionInteraction, DeployMethod, DeployOptions, Logger, ProfileMethodOptions } from '@aztec/aztec.js';
|
|
2
|
-
import { type PrivateExecutionStep } from '@aztec/stdlib/kernel';
|
|
3
|
-
import type { ProvingTimings, SimulationTimings } from '@aztec/stdlib/tx';
|
|
4
|
-
import type { GithubActionBenchmarkResult } from '../utils.js';
|
|
5
|
-
declare const logLevel: readonly ["silent", "fatal", "error", "warn", "info", "verbose", "debug", "trace"];
|
|
6
|
-
type LogLevel = (typeof logLevel)[number];
|
|
7
|
-
export type Log = {
|
|
8
|
-
type: LogLevel;
|
|
9
|
-
timestamp: number;
|
|
10
|
-
prefix: string;
|
|
11
|
-
message: string;
|
|
12
|
-
data: any;
|
|
13
|
-
};
|
|
14
|
-
declare const GATE_TYPES: readonly ["ecc_op", "busread", "lookup", "pub_inputs", "arithmetic", "delta_range", "elliptic", "aux", "poseidon2_external", "poseidon2_internal", "overflow"];
|
|
15
|
-
type GateType = (typeof GATE_TYPES)[number];
|
|
16
|
-
type StructuredTrace = {
|
|
17
|
-
[k in GateType]: number;
|
|
18
|
-
};
|
|
19
|
-
export declare class ProxyLogger {
|
|
20
|
-
private static instance;
|
|
21
|
-
private logs;
|
|
22
|
-
private constructor();
|
|
23
|
-
static create(): void;
|
|
24
|
-
static getInstance(): ProxyLogger;
|
|
25
|
-
createLogger(prefix: string): Logger;
|
|
26
|
-
private handleLog;
|
|
27
|
-
flushLogs(): void;
|
|
28
|
-
getLogs(): Log[];
|
|
29
|
-
}
|
|
30
|
-
export type ProverType = 'wasm' | 'native';
|
|
31
|
-
type OracleRecording = {
|
|
32
|
-
calls: number;
|
|
33
|
-
max: number;
|
|
34
|
-
min: number;
|
|
35
|
-
avg: number;
|
|
36
|
-
total: number;
|
|
37
|
-
};
|
|
38
|
-
type Step = Pick<PrivateExecutionStep, 'functionName' | 'gateCount'> & {
|
|
39
|
-
time: number;
|
|
40
|
-
accGateCount?: number;
|
|
41
|
-
oracles: Record<string, OracleRecording>;
|
|
42
|
-
};
|
|
43
|
-
type ClientFlowBenchmark = {
|
|
44
|
-
name: string;
|
|
45
|
-
timings: Omit<ProvingTimings & SimulationTimings, 'perFunction'> & {
|
|
46
|
-
witgen: number;
|
|
47
|
-
};
|
|
48
|
-
maxMemory: number;
|
|
49
|
-
proverType: ProverType;
|
|
50
|
-
minimumTrace: StructuredTrace;
|
|
51
|
-
totalGateCount: number;
|
|
52
|
-
steps: Step[];
|
|
53
|
-
error: string | undefined;
|
|
54
|
-
};
|
|
55
|
-
export declare function generateBenchmark(flow: string, logs: Log[], timings: ProvingTimings | SimulationTimings, privateExecutionSteps: PrivateExecutionStep[], proverType: ProverType, error: string | undefined): ClientFlowBenchmark;
|
|
56
|
-
export declare function convertProfileToGHBenchmark(benchmark: ClientFlowBenchmark): GithubActionBenchmarkResult[];
|
|
57
|
-
export declare function captureProfile(label: string, interaction: ContractFunctionInteraction | DeployMethod, opts?: Omit<ProfileMethodOptions & DeployOptions, 'profileMode'>, expectedSteps?: number): Promise<import("@aztec/aztec.js").TxProfileResult>;
|
|
58
|
-
export {};
|
|
59
|
-
//# sourceMappingURL=benchmark.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"benchmark.d.ts","sourceRoot":"","sources":["../../../src/bench/client_flows/benchmark.ts"],"names":[],"mappings":"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"}
|