@aztec/end-to-end 0.86.0 → 0.87.0-nightly.20250521
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.js +1 -1
- package/dest/bench/client_flows/config.d.ts +1 -1
- package/dest/bench/client_flows/config.d.ts.map +1 -1
- package/dest/bench/client_flows/config.js +22 -3
- package/dest/bench/client_flows/data_extractor.d.ts.map +1 -1
- package/dest/bench/client_flows/data_extractor.js +23 -12
- package/dest/bench/utils.d.ts +1 -1
- package/dest/bench/utils.d.ts.map +1 -1
- package/dest/bench/utils.js +9 -5
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +1 -1
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +1 -1
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +5 -2
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +8 -4
- package/dest/e2e_deploy_contract/deploy_test.d.ts +1 -1
- package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.d.ts +13 -5
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +41 -16
- package/dest/e2e_fees/bridging_race.notest.d.ts +2 -0
- package/dest/e2e_fees/bridging_race.notest.d.ts.map +1 -0
- package/dest/e2e_fees/bridging_race.notest.js +60 -0
- package/dest/e2e_fees/fees_test.d.ts +1 -1
- package/dest/e2e_fees/fees_test.d.ts.map +1 -1
- package/dest/e2e_fees/fees_test.js +15 -9
- package/dest/e2e_nested_contract/nested_contract_test.d.ts +2 -2
- package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
- package/dest/e2e_nested_contract/nested_contract_test.js +2 -2
- package/dest/e2e_p2p/p2p_network.d.ts +10 -214
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +20 -23
- package/dest/e2e_p2p/shared.d.ts +1 -1
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +3 -7
- package/dest/e2e_prover/e2e_prover_test.d.ts.map +1 -1
- package/dest/e2e_prover/e2e_prover_test.js +2 -1
- package/dest/e2e_token_contract/token_contract_test.d.ts +1 -1
- package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
- package/dest/e2e_token_contract/token_contract_test.js +1 -1
- package/dest/fixtures/fixtures.d.ts +4 -6
- package/dest/fixtures/fixtures.d.ts.map +1 -1
- package/dest/fixtures/fixtures.js +2 -2
- package/dest/fixtures/get_bb_config.d.ts.map +1 -1
- package/dest/fixtures/l1_to_l2_messaging.d.ts +5 -1
- package/dest/fixtures/l1_to_l2_messaging.d.ts.map +1 -1
- package/dest/fixtures/l1_to_l2_messaging.js +5 -4
- package/dest/fixtures/setup_l1_contracts.d.ts +1 -1
- package/dest/fixtures/setup_l1_contracts.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.d.ts +1 -2
- package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.js +3 -3
- package/dest/fixtures/snapshot_manager.d.ts.map +1 -1
- package/dest/fixtures/snapshot_manager.js +6 -2
- package/dest/fixtures/utils.d.ts +6 -6
- package/dest/fixtures/utils.d.ts.map +1 -1
- package/dest/fixtures/utils.js +64 -63
- package/dest/shared/capture_private_execution_steps.d.ts.map +1 -1
- package/dest/shared/capture_private_execution_steps.js +8 -4
- package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
- package/dest/shared/submit-transactions.d.ts.map +1 -1
- package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
- package/dest/shared/uniswap_l1_l2.js +1 -1
- package/dest/simulators/token_simulator.d.ts.map +1 -1
- package/dest/simulators/token_simulator.js +1 -1
- package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
- package/dest/spartan/utils.d.ts +0 -1
- package/dest/spartan/utils.d.ts.map +1 -1
- package/package.json +38 -37
- package/src/bench/client_flows/client_flows_benchmark.ts +1 -1
- package/src/bench/client_flows/config.ts +12 -4
- package/src/bench/client_flows/data_extractor.ts +40 -20
- package/src/bench/utils.ts +7 -3
- package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +1 -1
- package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +16 -5
- package/src/e2e_deploy_contract/deploy_test.ts +1 -1
- package/src/e2e_epochs/epochs_test.ts +51 -18
- package/src/e2e_fees/bridging_race.notest.ts +74 -0
- package/src/e2e_fees/fees_test.ts +24 -9
- package/src/e2e_nested_contract/nested_contract_test.ts +6 -3
- package/src/e2e_p2p/p2p_network.ts +27 -21
- package/src/e2e_p2p/shared.ts +4 -6
- package/src/e2e_prover/e2e_prover_test.ts +1 -0
- package/src/e2e_token_contract/token_contract_test.ts +1 -1
- package/src/fixtures/dumps/epoch_proof_result.json +1 -1
- package/src/fixtures/fixtures.ts +2 -2
- package/src/fixtures/l1_to_l2_messaging.ts +1 -1
- package/src/fixtures/setup_p2p_test.ts +3 -3
- package/src/fixtures/snapshot_manager.ts +2 -2
- package/src/fixtures/utils.ts +57 -66
- package/src/shared/capture_private_execution_steps.ts +9 -2
- package/src/shared/uniswap_l1_l2.ts +1 -1
- package/src/simulators/token_simulator.ts +0 -1
- package/src/spartan/setup_test_wallets.ts +6 -3
|
@@ -6,13 +6,17 @@ export type ClientFlowConfig = {
|
|
|
6
6
|
recursions?: number[];
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
-
type ClientFlows = 'deployments' | 'transfers' | 'bridging' | 'amm';
|
|
9
|
+
type ClientFlows = 'accountDeployments' | 'deployments' | 'transfers' | 'bridging' | 'amm';
|
|
10
10
|
|
|
11
11
|
export type ClientFlowsConfig = {
|
|
12
12
|
[key in ClientFlows]: ClientFlowConfig;
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
export const KEY_FLOWS_CONFIG: ClientFlowsConfig = {
|
|
16
|
+
accountDeployments: {
|
|
17
|
+
accounts: ['ecdsar1', 'schnorr'],
|
|
18
|
+
feePaymentMethods: ['sponsored_fpc'],
|
|
19
|
+
},
|
|
16
20
|
deployments: {
|
|
17
21
|
accounts: ['ecdsar1', 'schnorr'],
|
|
18
22
|
feePaymentMethods: ['sponsored_fpc'],
|
|
@@ -26,13 +30,17 @@ export const KEY_FLOWS_CONFIG: ClientFlowsConfig = {
|
|
|
26
30
|
feePaymentMethods: ['sponsored_fpc'],
|
|
27
31
|
},
|
|
28
32
|
transfers: {
|
|
29
|
-
accounts: ['ecdsar1'
|
|
30
|
-
feePaymentMethods: ['sponsored_fpc', '
|
|
31
|
-
recursions: [1],
|
|
33
|
+
accounts: ['ecdsar1'],
|
|
34
|
+
feePaymentMethods: ['sponsored_fpc', 'private_fpc'],
|
|
35
|
+
recursions: [0, 1],
|
|
32
36
|
},
|
|
33
37
|
};
|
|
34
38
|
|
|
35
39
|
export const FULL_FLOWS_CONFIG: ClientFlowsConfig = {
|
|
40
|
+
accountDeployments: {
|
|
41
|
+
accounts: ['ecdsar1', 'schnorr'],
|
|
42
|
+
feePaymentMethods: ['bridged_fee_juice', 'sponsored_fpc'],
|
|
43
|
+
},
|
|
36
44
|
deployments: {
|
|
37
45
|
accounts: ['ecdsar1', 'schnorr'],
|
|
38
46
|
feePaymentMethods: ['bridged_fee_juice', 'sponsored_fpc'],
|
|
@@ -2,6 +2,7 @@ import type { Logger } from '@aztec/aztec.js';
|
|
|
2
2
|
import { BBNativePrivateKernelProver } from '@aztec/bb-prover/client/native';
|
|
3
3
|
import { BBWASMBundlePrivateKernelProver } from '@aztec/bb-prover/client/wasm/bundle';
|
|
4
4
|
import { createLogger, logger } from '@aztec/foundation/log';
|
|
5
|
+
import { Timer } from '@aztec/foundation/timer';
|
|
5
6
|
import { WASMSimulator } from '@aztec/simulator/client';
|
|
6
7
|
import type { PrivateExecutionStep } from '@aztec/stdlib/kernel';
|
|
7
8
|
|
|
@@ -18,7 +19,7 @@ type Log = {
|
|
|
18
19
|
timestamp: number;
|
|
19
20
|
prefix: string;
|
|
20
21
|
message: string;
|
|
21
|
-
|
|
22
|
+
|
|
22
23
|
data: any;
|
|
23
24
|
};
|
|
24
25
|
|
|
@@ -105,18 +106,18 @@ async function createProver(config: NativeProverConfig = {}, log: Logger) {
|
|
|
105
106
|
}
|
|
106
107
|
}
|
|
107
108
|
|
|
108
|
-
function getMinimumTrace(logs: Log[]
|
|
109
|
-
const minimumMessage = '
|
|
109
|
+
function getMinimumTrace(logs: Log[]): StructuredTrace {
|
|
110
|
+
const minimumMessage = 'Trace details:';
|
|
110
111
|
const minimumMessageIndex = logs.findIndex(log => log.message.includes(minimumMessage));
|
|
111
112
|
const candidateLogs = logs.slice(minimumMessageIndex - GATE_TYPES.length, minimumMessageIndex);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
+
|
|
120
121
|
const traceSizes = traceLogs.map(log => {
|
|
121
122
|
const [gateType, gateSizeStr] = log
|
|
122
123
|
.replace(/\n.*\)$/, '')
|
|
@@ -127,6 +128,7 @@ function getMinimumTrace(logs: Log[], proverType: ProverType): StructuredTrace {
|
|
|
127
128
|
assert(GATE_TYPES.includes(gateType as GateType), `Gate type ${gateType} is not recognized`);
|
|
128
129
|
return { [gateType]: gateSize };
|
|
129
130
|
});
|
|
131
|
+
|
|
130
132
|
assert(traceSizes.length === GATE_TYPES.length, 'Decoded trace sizes do not match expected amount of gate types');
|
|
131
133
|
return traceSizes.reduce((acc, curr) => ({ ...acc, ...curr }), {}) as StructuredTrace;
|
|
132
134
|
}
|
|
@@ -156,23 +158,36 @@ async function main() {
|
|
|
156
158
|
const witnessStack = JSON.parse(witnesses.toString()).map((witnessMap: Record<string, string>) => {
|
|
157
159
|
return new Map<number, string>(Object.entries(witnessMap).map(([k, v]) => [Number(k), v]));
|
|
158
160
|
});
|
|
159
|
-
const
|
|
160
|
-
const
|
|
161
|
-
|
|
161
|
+
const profileFile = await readFile(join(ivcFolder, flow, 'profile.json'));
|
|
162
|
+
const profile = JSON.parse(profileFile.toString()) as {
|
|
163
|
+
syncTime: number;
|
|
164
|
+
steps: {
|
|
165
|
+
fnName: string;
|
|
166
|
+
gateCount: number;
|
|
167
|
+
timings: { witgen: number; gateCount: number };
|
|
168
|
+
}[];
|
|
169
|
+
};
|
|
170
|
+
const privateExecutionSteps: PrivateExecutionStep[] = profile.steps.map((step, i) => ({
|
|
162
171
|
functionName: step.fnName,
|
|
163
172
|
gateCount: step.gateCount,
|
|
164
173
|
bytecode: stepsFromFile[i].bytecode,
|
|
165
174
|
// TODO(AD) do we still want to take this from witness.json?
|
|
166
175
|
witness: witnessStack[i],
|
|
167
|
-
|
|
168
|
-
|
|
176
|
+
vk: stepsFromFile[i].vk,
|
|
177
|
+
timings: {
|
|
178
|
+
witgen: step.timings.witgen,
|
|
179
|
+
gateCount: step.timings.witgen,
|
|
180
|
+
},
|
|
169
181
|
}));
|
|
170
182
|
let stats: { duration: number; eventName: string; proofSize: number } | undefined;
|
|
171
|
-
|
|
172
|
-
let error: any
|
|
183
|
+
|
|
184
|
+
let error: any;
|
|
173
185
|
let currentLogs: Log[] = [];
|
|
186
|
+
let provingTime;
|
|
174
187
|
try {
|
|
188
|
+
const provingTimer = new Timer();
|
|
175
189
|
await prover.createClientIvcProof(privateExecutionSteps);
|
|
190
|
+
provingTime = provingTimer.ms();
|
|
176
191
|
} catch (e) {
|
|
177
192
|
userLog.error(`Failed to generate client ivc proof for ${flow}`, e);
|
|
178
193
|
error = (e as Error).message;
|
|
@@ -185,9 +200,9 @@ async function main() {
|
|
|
185
200
|
stats = currentLogs[0].data as { duration: number; eventName: string; proofSize: number };
|
|
186
201
|
}
|
|
187
202
|
|
|
188
|
-
const minimumTrace = getMinimumTrace(currentLogs
|
|
203
|
+
const minimumTrace = getMinimumTrace(currentLogs);
|
|
189
204
|
|
|
190
|
-
const steps =
|
|
205
|
+
const steps = profile.steps.reduce<Step[]>((acc, step, i) => {
|
|
191
206
|
const previousAccGateCount = i === 0 ? 0 : acc[i - 1].accGateCount!;
|
|
192
207
|
return [
|
|
193
208
|
...acc,
|
|
@@ -195,11 +210,16 @@ async function main() {
|
|
|
195
210
|
fnName: step.fnName,
|
|
196
211
|
gateCount: step.gateCount,
|
|
197
212
|
accGateCount: previousAccGateCount + step.gateCount,
|
|
213
|
+
timings: {
|
|
214
|
+
witgen: step.timings.witgen,
|
|
215
|
+
},
|
|
198
216
|
},
|
|
199
217
|
];
|
|
200
218
|
}, []);
|
|
201
219
|
const totalGateCount = steps[steps.length - 1].accGateCount;
|
|
202
220
|
const benchmark = {
|
|
221
|
+
syncTime: profile.syncTime,
|
|
222
|
+
provingTime,
|
|
203
223
|
proverType,
|
|
204
224
|
minimumTrace: minimumTrace,
|
|
205
225
|
totalGateCount,
|
package/src/bench/utils.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type { AztecNodeService } from '@aztec/aztec-node';
|
|
2
2
|
import { type AztecNode, BatchCall, type SentTx, type WaitOpts } from '@aztec/aztec.js';
|
|
3
3
|
import { mean, stdDev, times } from '@aztec/foundation/collection';
|
|
4
|
-
import { BenchmarkingContract } from '@aztec/noir-contracts.js/Benchmarking';
|
|
4
|
+
import { BenchmarkingContract } from '@aztec/noir-test-contracts.js/Benchmarking';
|
|
5
5
|
import { type PXEService, type PXEServiceConfig, createPXEService } from '@aztec/pxe/server';
|
|
6
6
|
import type { MetricsType } from '@aztec/telemetry-client';
|
|
7
7
|
import type { BenchmarkDataPoint, BenchmarkMetricsType, BenchmarkTelemetryClient } from '@aztec/telemetry-client/bench';
|
|
8
8
|
|
|
9
|
-
import { writeFileSync } from 'fs';
|
|
9
|
+
import { mkdirSync, writeFileSync } from 'fs';
|
|
10
|
+
import path from 'path';
|
|
10
11
|
|
|
11
12
|
import { type EndToEndContext, type SetupOptions, setup } from '../fixtures/utils.js';
|
|
12
13
|
|
|
@@ -36,6 +37,7 @@ export async function benchmarkSetup(
|
|
|
36
37
|
throw new Error(`No benchmark data generated. Please review your test setup.`);
|
|
37
38
|
}
|
|
38
39
|
const benchOutput = opts.benchOutput ?? process.env.BENCH_OUTPUT ?? 'bench.json';
|
|
40
|
+
mkdirSync(path.dirname(benchOutput), { recursive: true });
|
|
39
41
|
writeFileSync(benchOutput, JSON.stringify(formatted));
|
|
40
42
|
context.logger.info(`Wrote ${data.length} metrics to ${benchOutput}`);
|
|
41
43
|
await origTeardown();
|
|
@@ -136,7 +138,7 @@ export async function sendTxs(
|
|
|
136
138
|
): Promise<SentTx[]> {
|
|
137
139
|
const calls = times(txCount, index => makeCall(index, context, contract, heavyPublicCompute));
|
|
138
140
|
context.logger.info(`Creating ${txCount} txs`);
|
|
139
|
-
const provenTxs = await Promise.all(calls.map(call => call.prove(
|
|
141
|
+
const provenTxs = await Promise.all(calls.map(call => call.prove()));
|
|
140
142
|
context.logger.info(`Sending ${txCount} txs`);
|
|
141
143
|
return provenTxs.map(tx => tx.send());
|
|
142
144
|
}
|
|
@@ -166,7 +168,9 @@ export async function createNewPXE(node: AztecNode, contract: BenchmarkingContra
|
|
|
166
168
|
l1ChainId,
|
|
167
169
|
rollupVersion,
|
|
168
170
|
} as PXEServiceConfig;
|
|
171
|
+
// docs:start:PXEcreate
|
|
169
172
|
const pxe = await createPXEService(node, pxeConfig);
|
|
173
|
+
// docs:end:PXEcreate
|
|
170
174
|
await pxe.registerContract(contract);
|
|
171
175
|
return pxe;
|
|
172
176
|
}
|
|
@@ -11,9 +11,9 @@ import {
|
|
|
11
11
|
createLogger,
|
|
12
12
|
} from '@aztec/aztec.js';
|
|
13
13
|
import { MAX_NOTE_HASHES_PER_TX } from '@aztec/constants';
|
|
14
|
-
import { InvalidAccountContract } from '@aztec/noir-contracts.js/InvalidAccount';
|
|
15
14
|
import type { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
16
15
|
import { TokenBlacklistContract } from '@aztec/noir-contracts.js/TokenBlacklist';
|
|
16
|
+
import { InvalidAccountContract } from '@aztec/noir-test-contracts.js/InvalidAccount';
|
|
17
17
|
|
|
18
18
|
import { jest } from '@jest/globals';
|
|
19
19
|
|
|
@@ -11,10 +11,16 @@ import {
|
|
|
11
11
|
createLogger,
|
|
12
12
|
} from '@aztec/aztec.js';
|
|
13
13
|
import { CheatCodes } from '@aztec/aztec.js/testing';
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
type DeployL1ContractsReturnType,
|
|
16
|
+
type ExtendedViemWalletClient,
|
|
17
|
+
createExtendedL1Client,
|
|
18
|
+
deployL1Contract,
|
|
19
|
+
} from '@aztec/ethereum';
|
|
15
20
|
import { InboxAbi, OutboxAbi, TestERC20Abi, TestERC20Bytecode } from '@aztec/l1-artifacts';
|
|
16
21
|
import { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
17
22
|
import { TokenBridgeContract } from '@aztec/noir-contracts.js/TokenBridge';
|
|
23
|
+
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
18
24
|
|
|
19
25
|
import { getContract } from 'viem';
|
|
20
26
|
|
|
@@ -38,6 +44,7 @@ export class CrossChainMessagingTest {
|
|
|
38
44
|
aztecNode!: AztecNode;
|
|
39
45
|
pxe!: PXE;
|
|
40
46
|
aztecNodeConfig!: AztecNodeConfig;
|
|
47
|
+
aztecNodeAdmin!: AztecNodeAdmin;
|
|
41
48
|
|
|
42
49
|
l1Client!: ExtendedViemWalletClient | undefined;
|
|
43
50
|
|
|
@@ -51,7 +58,9 @@ export class CrossChainMessagingTest {
|
|
|
51
58
|
|
|
52
59
|
inbox!: any; // GetContractReturnType<typeof InboxAbi> | undefined;
|
|
53
60
|
outbox!: any; // GetContractReturnType<typeof OutboxAbi> | undefined;
|
|
54
|
-
|
|
61
|
+
cheatCodes!: CheatCodes;
|
|
62
|
+
|
|
63
|
+
deployL1ContractsValues!: DeployL1ContractsReturnType;
|
|
55
64
|
|
|
56
65
|
constructor(testName: string) {
|
|
57
66
|
this.logger = createLogger(`e2e:e2e_cross_chain_messaging:${testName}`);
|
|
@@ -59,15 +68,17 @@ export class CrossChainMessagingTest {
|
|
|
59
68
|
}
|
|
60
69
|
|
|
61
70
|
async assumeProven() {
|
|
62
|
-
await this.
|
|
71
|
+
await this.cheatCodes.rollup.markAsProven();
|
|
63
72
|
}
|
|
64
73
|
|
|
65
74
|
async setup() {
|
|
66
|
-
const { aztecNode, pxe, aztecNodeConfig } = await this.snapshotManager.setup();
|
|
75
|
+
const { aztecNode, pxe, aztecNodeConfig, deployL1ContractsValues } = await this.snapshotManager.setup();
|
|
67
76
|
this.aztecNode = aztecNode;
|
|
68
77
|
this.pxe = pxe;
|
|
69
78
|
this.aztecNodeConfig = aztecNodeConfig;
|
|
70
|
-
this.
|
|
79
|
+
this.cheatCodes = await CheatCodes.create(this.aztecNodeConfig.l1RpcUrls, this.pxe);
|
|
80
|
+
this.deployL1ContractsValues = deployL1ContractsValues;
|
|
81
|
+
this.aztecNodeAdmin = aztecNode;
|
|
71
82
|
}
|
|
72
83
|
|
|
73
84
|
snapshot = <T>(
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
createLogger,
|
|
14
14
|
getContractInstanceFromDeployParams,
|
|
15
15
|
} from '@aztec/aztec.js';
|
|
16
|
-
import type { StatefulTestContract } from '@aztec/noir-contracts.js/StatefulTest';
|
|
16
|
+
import type { StatefulTestContract } from '@aztec/noir-test-contracts.js/StatefulTest';
|
|
17
17
|
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
18
18
|
|
|
19
19
|
import { type ISnapshotManager, createSnapshotManager, deployAccounts } from '../fixtures/snapshot_manager.js';
|
|
@@ -10,7 +10,7 @@ import type { TestProverNode } from '@aztec/prover-node/test';
|
|
|
10
10
|
import type { SequencerPublisher } from '@aztec/sequencer-client';
|
|
11
11
|
import type { TestSequencerClient } from '@aztec/sequencer-client/test';
|
|
12
12
|
import type { L2BlockNumber } from '@aztec/stdlib/block';
|
|
13
|
-
import type
|
|
13
|
+
import { type L1RollupConstants, getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
14
14
|
|
|
15
15
|
import { join } from 'path';
|
|
16
16
|
import type { Hex } from 'viem';
|
|
@@ -23,15 +23,23 @@ import {
|
|
|
23
23
|
setup,
|
|
24
24
|
} from '../fixtures/utils.js';
|
|
25
25
|
|
|
26
|
-
// This can be lowered to as much as 2s in non-CI
|
|
27
|
-
export const L1_BLOCK_TIME_IN_S = process.env.L1_BLOCK_TIME ? parseInt(process.env.L1_BLOCK_TIME) : 8;
|
|
28
|
-
export const L2_SLOT_DURATION_IN_L1_SLOTS = 2;
|
|
29
26
|
export const WORLD_STATE_BLOCK_HISTORY = 2;
|
|
30
27
|
export const WORLD_STATE_BLOCK_CHECK_INTERVAL = 50;
|
|
31
28
|
export const ARCHIVER_POLL_INTERVAL = 50;
|
|
32
29
|
|
|
33
30
|
export type EpochsTestOpts = Partial<
|
|
34
|
-
Pick<
|
|
31
|
+
Pick<
|
|
32
|
+
SetupOptions,
|
|
33
|
+
| 'startProverNode'
|
|
34
|
+
| 'aztecProofSubmissionWindow'
|
|
35
|
+
| 'aztecEpochDuration'
|
|
36
|
+
| 'proverTestDelayMs'
|
|
37
|
+
| 'l1PublishRetryIntervalMS'
|
|
38
|
+
| 'txPropagationMaxQueryAttempts'
|
|
39
|
+
| 'proverNodeConfig'
|
|
40
|
+
| 'ethereumSlotDuration'
|
|
41
|
+
| 'aztecSlotDuration'
|
|
42
|
+
>
|
|
35
43
|
>;
|
|
36
44
|
|
|
37
45
|
/**
|
|
@@ -54,17 +62,33 @@ export class EpochsTestContext {
|
|
|
54
62
|
|
|
55
63
|
public epochDuration!: number;
|
|
56
64
|
|
|
65
|
+
public L1_BLOCK_TIME_IN_S!: number;
|
|
66
|
+
public L2_SLOT_DURATION_IN_S!: number;
|
|
67
|
+
|
|
57
68
|
public static async setup(opts: EpochsTestOpts = {}) {
|
|
58
69
|
const test = new EpochsTestContext();
|
|
59
70
|
await test.setup(opts);
|
|
60
71
|
return test;
|
|
61
72
|
}
|
|
62
73
|
|
|
74
|
+
public static getSlotDurations(opts: EpochsTestOpts = {}) {
|
|
75
|
+
const envEthereumSlotDuration = process.env.L1_BLOCK_TIME ? parseInt(process.env.L1_BLOCK_TIME) : 8;
|
|
76
|
+
const ethereumSlotDuration = opts.ethereumSlotDuration ?? envEthereumSlotDuration;
|
|
77
|
+
const aztecSlotDuration = opts.aztecSlotDuration ?? ethereumSlotDuration * 2;
|
|
78
|
+
const aztecEpochDuration = opts.aztecEpochDuration ?? 4;
|
|
79
|
+
const aztecProofSubmissionWindow = opts.aztecProofSubmissionWindow ?? aztecEpochDuration * 2 - 1;
|
|
80
|
+
return { ethereumSlotDuration, aztecSlotDuration, aztecEpochDuration, aztecProofSubmissionWindow };
|
|
81
|
+
}
|
|
82
|
+
|
|
63
83
|
public async setup(opts: EpochsTestOpts = {}) {
|
|
84
|
+
const { ethereumSlotDuration, aztecSlotDuration, aztecEpochDuration, aztecProofSubmissionWindow } =
|
|
85
|
+
EpochsTestContext.getSlotDurations(opts);
|
|
86
|
+
|
|
87
|
+
this.L1_BLOCK_TIME_IN_S = ethereumSlotDuration;
|
|
88
|
+
this.L2_SLOT_DURATION_IN_S = aztecSlotDuration;
|
|
89
|
+
|
|
64
90
|
// Set up system without any account nor protocol contracts
|
|
65
91
|
// and with faster block times and shorter epochs.
|
|
66
|
-
const aztecEpochDuration = opts.aztecEpochDuration ?? 4;
|
|
67
|
-
const proofSubmissionWindow = opts.aztecProofSubmissionWindow ?? aztecEpochDuration * 2 - 1;
|
|
68
92
|
const context = await setup(0, {
|
|
69
93
|
checkIntervalMs: 50,
|
|
70
94
|
archiverPollingIntervalMS: ARCHIVER_POLL_INTERVAL,
|
|
@@ -72,9 +96,9 @@ export class EpochsTestContext {
|
|
|
72
96
|
skipProtocolContracts: true,
|
|
73
97
|
salt: 1,
|
|
74
98
|
aztecEpochDuration,
|
|
75
|
-
aztecSlotDuration
|
|
76
|
-
ethereumSlotDuration
|
|
77
|
-
aztecProofSubmissionWindow
|
|
99
|
+
aztecSlotDuration,
|
|
100
|
+
ethereumSlotDuration,
|
|
101
|
+
aztecProofSubmissionWindow,
|
|
78
102
|
minTxsPerBlock: 0,
|
|
79
103
|
realProofs: false,
|
|
80
104
|
startProverNode: true,
|
|
@@ -84,7 +108,7 @@ export class EpochsTestContext {
|
|
|
84
108
|
proverId: Fr.fromString('1'),
|
|
85
109
|
// This must be enough so that the tx from the prover is delayed properly,
|
|
86
110
|
// but not so much to hang the sequencer and timeout the teardown
|
|
87
|
-
txPropagationMaxQueryAttempts: 12,
|
|
111
|
+
txPropagationMaxQueryAttempts: opts.txPropagationMaxQueryAttempts ?? 12,
|
|
88
112
|
worldStateBlockHistory: WORLD_STATE_BLOCK_HISTORY,
|
|
89
113
|
...opts,
|
|
90
114
|
});
|
|
@@ -116,11 +140,11 @@ export class EpochsTestContext {
|
|
|
116
140
|
this.epochDuration = aztecEpochDuration;
|
|
117
141
|
this.constants = {
|
|
118
142
|
epochDuration: aztecEpochDuration,
|
|
119
|
-
slotDuration:
|
|
143
|
+
slotDuration: aztecSlotDuration,
|
|
120
144
|
l1StartBlock: await this.rollup.getL1StartBlock(),
|
|
121
145
|
l1GenesisTime: await this.rollup.getL1GenesisTime(),
|
|
122
|
-
ethereumSlotDuration
|
|
123
|
-
proofSubmissionWindow,
|
|
146
|
+
ethereumSlotDuration,
|
|
147
|
+
proofSubmissionWindow: aztecProofSubmissionWindow,
|
|
124
148
|
};
|
|
125
149
|
|
|
126
150
|
this.logger.info(
|
|
@@ -143,8 +167,8 @@ export class EpochsTestContext {
|
|
|
143
167
|
createAndSyncProverNode(
|
|
144
168
|
proverNodePrivateKey,
|
|
145
169
|
{ ...this.context.config, proverId: Fr.fromString(suffix) },
|
|
170
|
+
{ dataDirectory: join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')) },
|
|
146
171
|
this.context.aztecNode,
|
|
147
|
-
join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')),
|
|
148
172
|
),
|
|
149
173
|
);
|
|
150
174
|
this.proverNodes.push(proverNode);
|
|
@@ -174,14 +198,14 @@ export class EpochsTestContext {
|
|
|
174
198
|
public async waitUntilEpochStarts(epoch: number) {
|
|
175
199
|
const [start] = getTimestampRangeForEpoch(BigInt(epoch), this.constants);
|
|
176
200
|
this.logger.info(`Waiting until L1 timestamp ${start} is reached as the start of epoch ${epoch}`);
|
|
177
|
-
await waitUntilL1Timestamp(this.l1Client, start - BigInt(L1_BLOCK_TIME_IN_S));
|
|
201
|
+
await waitUntilL1Timestamp(this.l1Client, start - BigInt(this.L1_BLOCK_TIME_IN_S));
|
|
178
202
|
return start;
|
|
179
203
|
}
|
|
180
204
|
|
|
181
205
|
/** Waits until the given L2 block number is mined. */
|
|
182
206
|
public async waitUntilL2BlockNumber(target: number, timeout = 60) {
|
|
183
207
|
await retryUntil(
|
|
184
|
-
() => Promise.resolve(target
|
|
208
|
+
() => Promise.resolve(target <= this.monitor.l2BlockNumber),
|
|
185
209
|
`Wait until L2 block ${target}`,
|
|
186
210
|
timeout,
|
|
187
211
|
0.1,
|
|
@@ -191,11 +215,20 @@ export class EpochsTestContext {
|
|
|
191
215
|
/** Waits until the given L2 block number is marked as proven. */
|
|
192
216
|
public async waitUntilProvenL2BlockNumber(t: number, timeout = 60) {
|
|
193
217
|
await retryUntil(
|
|
194
|
-
() => Promise.resolve(t
|
|
218
|
+
() => Promise.resolve(t <= this.monitor.l2ProvenBlockNumber),
|
|
195
219
|
`Wait proven L2 block ${t}`,
|
|
196
220
|
timeout,
|
|
197
221
|
0.1,
|
|
198
222
|
);
|
|
223
|
+
return this.monitor.l2ProvenBlockNumber;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/** Waits until the end of the proof submission window for a given epoch. */
|
|
227
|
+
public async waitUntilEndOfProofSubmissionWindow(epochNumber: number | bigint) {
|
|
228
|
+
const deadline = getProofSubmissionDeadlineTimestamp(BigInt(epochNumber), this.constants);
|
|
229
|
+
const date = new Date(Number(deadline) * 1000);
|
|
230
|
+
this.logger.info(`Waiting until end of submission window for epoch ${epochNumber} at ${date}`, { deadline });
|
|
231
|
+
await waitUntilL1Timestamp(this.l1Client, deadline);
|
|
199
232
|
}
|
|
200
233
|
|
|
201
234
|
/** Waits for the aztec node to sync to the target block number. */
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { getSchnorrAccount } from '@aztec/accounts/schnorr';
|
|
2
|
+
import { Fr, type Logger, type PXE, sleep } from '@aztec/aztec.js';
|
|
3
|
+
import { FEE_FUNDING_FOR_TESTER_ACCOUNT } from '@aztec/constants';
|
|
4
|
+
import { Fq } from '@aztec/foundation/fields';
|
|
5
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
6
|
+
|
|
7
|
+
import { jest } from '@jest/globals';
|
|
8
|
+
import type { Hex } from 'viem';
|
|
9
|
+
|
|
10
|
+
import { FeesTest } from './fees_test.js';
|
|
11
|
+
|
|
12
|
+
jest.setTimeout(300_000);
|
|
13
|
+
|
|
14
|
+
// Regression for https://github.com/AztecProtocol/aztec-packages/issues/12366
|
|
15
|
+
// Similar to e2e_fees/account_init but with no automine
|
|
16
|
+
describe('e2e_fees bridging_race', () => {
|
|
17
|
+
const ETHEREUM_SLOT_DURATION = 4;
|
|
18
|
+
const AZTEC_SLOT_DURATION = ETHEREUM_SLOT_DURATION * 2;
|
|
19
|
+
|
|
20
|
+
const t = new FeesTest('bridging_race', 1, {
|
|
21
|
+
ethereumSlotDuration: ETHEREUM_SLOT_DURATION,
|
|
22
|
+
aztecSlotDuration: AZTEC_SLOT_DURATION,
|
|
23
|
+
minTxsPerBlock: 0,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
beforeAll(async () => {
|
|
27
|
+
await t.applyInitialAccountsSnapshot();
|
|
28
|
+
await t.applyPublicDeployAccountsSnapshot();
|
|
29
|
+
await t.applySetupFeeJuiceSnapshot();
|
|
30
|
+
|
|
31
|
+
({ pxe, logger } = await t.setup());
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
afterAll(async () => {
|
|
35
|
+
await t.teardown();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
let logger: Logger;
|
|
39
|
+
let pxe: PXE;
|
|
40
|
+
let bobsAddress: AztecAddress;
|
|
41
|
+
|
|
42
|
+
beforeEach(async () => {
|
|
43
|
+
const bobsSecretKey = Fr.random();
|
|
44
|
+
const bobsPrivateSigningKey = Fq.random();
|
|
45
|
+
const bobsAccountManager = await getSchnorrAccount(pxe, bobsSecretKey, bobsPrivateSigningKey, Fr.random());
|
|
46
|
+
const bobsCompleteAddress = await bobsAccountManager.getCompleteAddress();
|
|
47
|
+
bobsAddress = bobsCompleteAddress.address;
|
|
48
|
+
await bobsAccountManager.getWallet();
|
|
49
|
+
await bobsAccountManager.register();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('Alice bridges funds to Bob', async () => {
|
|
53
|
+
// Tweak the token manager so the bridging happens immediately before the end of the current L2 slot
|
|
54
|
+
// This caused the message to be "not in state" when tried to be used
|
|
55
|
+
const l1TokenManager = t.feeJuiceBridgeTestHarness.l1TokenManager;
|
|
56
|
+
const origApprove = l1TokenManager.approve.bind(l1TokenManager);
|
|
57
|
+
l1TokenManager.approve = async (amount: bigint, address: Hex, addressName = '') => {
|
|
58
|
+
await origApprove(amount, address, addressName);
|
|
59
|
+
const sleepTime = (Number(t.chainMonitor.l2BlockTimestamp) + AZTEC_SLOT_DURATION) * 1000 - Date.now() - 500;
|
|
60
|
+
logger.info(`Sleeping for ${sleepTime}ms until near end of L2 slot before sending L1 fee juice to L2 inbox`);
|
|
61
|
+
await sleep(sleepTime);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// Waiting for the archiver to sync the message _before_ waiting for the mandatory 2 L2 blocks to pass fixed it
|
|
65
|
+
// This was added everywhere we wait for two blocks, which is spread across three different places in the codebase
|
|
66
|
+
// Yes, we need to REFACTOR it at some point
|
|
67
|
+
const amount = FEE_FUNDING_FOR_TESTER_ACCOUNT;
|
|
68
|
+
const claim = await t.feeJuiceBridgeTestHarness.prepareTokensOnL1(amount, bobsAddress);
|
|
69
|
+
const { claimSecret: secret, messageLeafIndex: index } = claim;
|
|
70
|
+
await t.feeJuiceContract.methods.claim(bobsAddress, amount, secret, index).send().wait();
|
|
71
|
+
const [balance] = await t.getGasBalanceFn(bobsAddress);
|
|
72
|
+
expect(balance).toEqual(amount);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
@@ -21,11 +21,11 @@ import { ChainMonitor } from '@aztec/ethereum/test';
|
|
|
21
21
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
22
22
|
import { TestERC20Abi } from '@aztec/l1-artifacts';
|
|
23
23
|
import { AppSubscriptionContract } from '@aztec/noir-contracts.js/AppSubscription';
|
|
24
|
-
import { CounterContract } from '@aztec/noir-contracts.js/Counter';
|
|
25
24
|
import { FPCContract } from '@aztec/noir-contracts.js/FPC';
|
|
26
25
|
import { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice';
|
|
27
26
|
import { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC';
|
|
28
27
|
import { TokenContract as BananaCoin } from '@aztec/noir-contracts.js/Token';
|
|
28
|
+
import { CounterContract } from '@aztec/noir-test-contracts.js/Counter';
|
|
29
29
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
30
30
|
import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice';
|
|
31
31
|
import { GasSettings } from '@aztec/stdlib/gas';
|
|
@@ -310,17 +310,33 @@ export class FeesTest {
|
|
|
310
310
|
};
|
|
311
311
|
|
|
312
312
|
this.getProverFee = async (blockNumber: number) => {
|
|
313
|
+
const block = await this.pxe.getBlock(blockNumber);
|
|
314
|
+
|
|
313
315
|
const publicClient = getPublicClient({
|
|
314
316
|
l1RpcUrls: context.aztecNodeConfig.l1RpcUrls,
|
|
315
317
|
l1ChainId: context.aztecNodeConfig.l1ChainId,
|
|
316
318
|
});
|
|
317
319
|
const rollup = new RollupContract(publicClient, data.rollupAddress);
|
|
318
320
|
|
|
319
|
-
|
|
321
|
+
// @todo @lherskind As we deal with #13601
|
|
322
|
+
// Right now the value is from `FeeLib.sol`
|
|
323
|
+
const L1_GAS_PER_EPOCH_VERIFIED = 1000000n;
|
|
324
|
+
|
|
325
|
+
// We round up
|
|
326
|
+
const mulDiv = (a: bigint, b: bigint, c: bigint) => (a * b) / c + ((a * b) % c > 0n ? 1n : 0n);
|
|
327
|
+
|
|
328
|
+
const { baseFee } = await rollup.getL1FeesAt(block!.header.globalVariables.timestamp.toBigInt());
|
|
329
|
+
const proverCost =
|
|
330
|
+
mulDiv(
|
|
331
|
+
mulDiv(L1_GAS_PER_EPOCH_VERIFIED, baseFee, await rollup.getEpochDuration()),
|
|
332
|
+
1n,
|
|
333
|
+
await rollup.getManaTarget(),
|
|
334
|
+
) + (await rollup.getProvingCostPerMana());
|
|
335
|
+
|
|
336
|
+
const price = await rollup.getFeeAssetPerEth();
|
|
320
337
|
|
|
321
|
-
const block = await this.pxe.getBlock(blockNumber);
|
|
322
338
|
const mana = block!.header.totalManaUsed.toBigInt();
|
|
323
|
-
return mana *
|
|
339
|
+
return mulDiv(mana * proverCost, price, 10n ** 9n);
|
|
324
340
|
};
|
|
325
341
|
},
|
|
326
342
|
);
|
|
@@ -333,16 +349,15 @@ export class FeesTest {
|
|
|
333
349
|
const feeJuiceContract = this.feeJuiceBridgeTestHarness.feeJuice;
|
|
334
350
|
expect((await context.pxe.getContractMetadata(feeJuiceContract.address)).isContractPubliclyDeployed).toBe(true);
|
|
335
351
|
|
|
336
|
-
|
|
337
|
-
this.logger.info(`SponsoredFPC
|
|
352
|
+
const sponsoredFPC = await setupSponsoredFPC(context.pxe);
|
|
353
|
+
this.logger.info(`SponsoredFPC at ${sponsoredFPC.address}`);
|
|
338
354
|
|
|
339
355
|
return {
|
|
340
|
-
sponsoredFPCAddress:
|
|
356
|
+
sponsoredFPCAddress: sponsoredFPC.address,
|
|
341
357
|
};
|
|
342
358
|
},
|
|
343
359
|
async data => {
|
|
344
|
-
|
|
345
|
-
this.sponsoredFPC = sponsoredFPC;
|
|
360
|
+
this.sponsoredFPC = await SponsoredFPCContract.at(data.sponsoredFPCAddress, this.aliceWallet);
|
|
346
361
|
},
|
|
347
362
|
);
|
|
348
363
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getSchnorrWallet } from '@aztec/accounts/schnorr';
|
|
2
2
|
import { type AccountWallet, type CompleteAddress, type Logger, type PXE, createLogger } from '@aztec/aztec.js';
|
|
3
|
-
import { ChildContract } from '@aztec/noir-contracts.js/Child';
|
|
4
|
-
import { ParentContract } from '@aztec/noir-contracts.js/Parent';
|
|
3
|
+
import { ChildContract } from '@aztec/noir-test-contracts.js/Child';
|
|
4
|
+
import { ParentContract } from '@aztec/noir-test-contracts.js/Parent';
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
type ISnapshotManager,
|
|
@@ -23,7 +23,10 @@ export class NestedContractTest {
|
|
|
23
23
|
parentContract!: ParentContract;
|
|
24
24
|
childContract!: ChildContract;
|
|
25
25
|
|
|
26
|
-
constructor(
|
|
26
|
+
constructor(
|
|
27
|
+
testName: string,
|
|
28
|
+
private numberOfAccounts = 1,
|
|
29
|
+
) {
|
|
27
30
|
this.logger = createLogger(`e2e:e2e_nested_contract:${testName}`);
|
|
28
31
|
this.snapshotManager = createSnapshotManager(`e2e_nested_contract/${testName}-${numberOfAccounts}`, dataPath);
|
|
29
32
|
}
|