@aztec/end-to-end 5.0.0-rc.1 → 5.0.0-rc.2
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 +4 -4
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.js +9 -6
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +3 -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 -6
- package/dest/e2e_epochs/epochs_test.d.ts +1 -1
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +2 -2
- package/dest/e2e_fees/bridging_race.notest.js +10 -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 +4 -2
- package/dest/e2e_l1_publisher/write_json.d.ts +1 -1
- package/dest/e2e_l1_publisher/write_json.d.ts.map +1 -1
- package/dest/e2e_l1_publisher/write_json.js +2 -1
- package/dest/e2e_p2p/p2p_network.d.ts +2 -2
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +10 -8
- package/dest/e2e_p2p/shared.d.ts +26 -1
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +40 -0
- package/dest/fixtures/e2e_prover_test.d.ts +1 -1
- package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
- package/dest/fixtures/e2e_prover_test.js +3 -3
- package/dest/fixtures/fixtures.d.ts +2 -1
- package/dest/fixtures/fixtures.d.ts.map +1 -1
- package/dest/fixtures/fixtures.js +6 -0
- package/dest/fixtures/setup.d.ts +4 -2
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +34 -6
- package/dest/fixtures/setup_p2p_test.d.ts +1 -1
- package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.js +3 -3
- package/dest/fixtures/token_utils.d.ts +22 -4
- package/dest/fixtures/token_utils.d.ts.map +1 -1
- package/dest/fixtures/token_utils.js +21 -1
- package/dest/shared/timing_env.js +254 -0
- package/dest/simulators/lending_simulator.js +1 -1
- package/dest/spartan/setup_test_wallets.d.ts +1 -1
- package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
- package/dest/spartan/setup_test_wallets.js +5 -1
- package/package.json +41 -41
- package/src/bench/client_flows/client_flows_benchmark.ts +22 -8
- package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +14 -5
- package/src/e2e_epochs/epochs_test.ts +2 -2
- package/src/e2e_fees/bridging_race.notest.ts +10 -0
- package/src/e2e_fees/fees_test.ts +10 -2
- package/src/e2e_l1_publisher/write_json.ts +1 -0
- package/src/e2e_p2p/p2p_network.ts +10 -7
- package/src/e2e_p2p/shared.ts +59 -0
- package/src/fixtures/e2e_prover_test.ts +4 -3
- package/src/fixtures/fixtures.ts +8 -0
- package/src/fixtures/setup.ts +40 -10
- package/src/fixtures/setup_p2p_test.ts +3 -3
- package/src/fixtures/token_utils.ts +39 -4
- package/src/guides/up_quick_start.sh +5 -0
- package/src/shared/timing_env.mjs +259 -0
- package/src/simulators/lending_simulator.ts +1 -1
- package/src/spartan/setup_test_wallets.ts +4 -1
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { appendFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { basename } from 'node:path';
|
|
3
|
+
import CustomEnvironment from '../../../foundation/src/jest/env.mjs';
|
|
4
|
+
// Per-test e2e timing environment. Gated entirely on the TEST_TIMING_FILE env var: when unset, this
|
|
5
|
+
// behaves exactly like the base CustomEnvironment (it only delegates). When set, it records, per test
|
|
6
|
+
// worker process, the time spent in jest before/after hooks and the test body, and merges in the
|
|
7
|
+
// function-level time captured by setup.ts/teardown.ts via a collector shared on `this.global`.
|
|
8
|
+
//
|
|
9
|
+
// Output is one JSONL file per worker process (the env runs once per worker). Each line carries a
|
|
10
|
+
// `type` discriminator and is one of:
|
|
11
|
+
// - `type: 'test'` (`name` set): beforeEach hooks, the it() body, afterEach hooks for one test; or
|
|
12
|
+
// - `type: 'suite'` (`name: null`): the suite-scoped beforeAll/afterAll hooks for the whole file.
|
|
13
|
+
export default class TimingEnvironment extends CustomEnvironment {
|
|
14
|
+
constructor(config, context){
|
|
15
|
+
super(config, context);
|
|
16
|
+
this.timingFile = process.env.TEST_TIMING_FILE;
|
|
17
|
+
if (!this.timingFile) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
this.suite = basename(context?.testPath ?? config?.testPath ?? 'unknown').replace(/\.test\.[cm]?[jt]s$/, '');
|
|
21
|
+
this.meta = {
|
|
22
|
+
commit: process.env.COMMIT_HASH ?? null,
|
|
23
|
+
branch: process.env.TARGET_BRANCH ?? process.env.REF_NAME ?? null,
|
|
24
|
+
runId: process.env.RUN_ID ?? null
|
|
25
|
+
};
|
|
26
|
+
// Shared collector. setup.ts (running in the sandbox realm) reads `globalThis.__e2eTimings`; this
|
|
27
|
+
// env (host realm) reads `this.global.__e2eTimings` — they are the same object. `current` is the
|
|
28
|
+
// full name of the test currently running (null during beforeAll/afterAll), used to tag fn spans.
|
|
29
|
+
this.collector = {
|
|
30
|
+
current: null,
|
|
31
|
+
fnSpans: []
|
|
32
|
+
};
|
|
33
|
+
this.global.__e2eTimings = this.collector;
|
|
34
|
+
// Records to flush as JSONL on teardown. One per test plus one suite-scoped record.
|
|
35
|
+
this.records = [];
|
|
36
|
+
this.recordsByName = new Map();
|
|
37
|
+
// The suite-scoped record (beforeAll/afterAll); bodyMs/totalMs are computed at flush time.
|
|
38
|
+
this.suiteRecord = {
|
|
39
|
+
name: null,
|
|
40
|
+
status: 'passed',
|
|
41
|
+
beforeHooksMs: 0,
|
|
42
|
+
afterHooksMs: 0
|
|
43
|
+
};
|
|
44
|
+
// Start times keyed by hook type (beforeAll/beforeEach/afterAll/afterEach).
|
|
45
|
+
this.hookStarts = {};
|
|
46
|
+
this.testStarts = new Map();
|
|
47
|
+
// Guards against double-flushing (we flush on both the teardown event and the teardown method).
|
|
48
|
+
this.flushed = false;
|
|
49
|
+
}
|
|
50
|
+
// Flush on the teardown method too: the jest lifecycle always calls this, whereas the 'teardown'
|
|
51
|
+
// event is not reliably delivered when a test run is interrupted. Whichever fires first wins.
|
|
52
|
+
async teardown() {
|
|
53
|
+
this.finalizeAndFlush();
|
|
54
|
+
await super.teardown();
|
|
55
|
+
}
|
|
56
|
+
async handleTestEvent(event, state) {
|
|
57
|
+
// Run the base env first so its unhandledRejection patching for after-hooks stays intact.
|
|
58
|
+
await super.handleTestEvent(event, state);
|
|
59
|
+
if (!this.timingFile) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const now = Date.now();
|
|
63
|
+
switch(event.name){
|
|
64
|
+
case 'hook_start':
|
|
65
|
+
{
|
|
66
|
+
this.hookStarts[event.hook.type] = now;
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
case 'hook_success':
|
|
70
|
+
case 'hook_failure':
|
|
71
|
+
{
|
|
72
|
+
const start = this.hookStarts[event.hook.type];
|
|
73
|
+
if (start === undefined) {
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
delete this.hookStarts[event.hook.type];
|
|
77
|
+
const ms = now - start;
|
|
78
|
+
if (event.hook.type === 'beforeEach') {
|
|
79
|
+
this.addToCurrent('beforeHooksMs', ms);
|
|
80
|
+
} else if (event.hook.type === 'afterEach') {
|
|
81
|
+
this.addToCurrent('afterHooksMs', ms);
|
|
82
|
+
} else if (event.hook.type === 'beforeAll') {
|
|
83
|
+
this.suiteRecord.beforeHooksMs += ms;
|
|
84
|
+
} else if (event.hook.type === 'afterAll') {
|
|
85
|
+
this.suiteRecord.afterHooksMs += ms;
|
|
86
|
+
}
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
case 'test_start':
|
|
90
|
+
{
|
|
91
|
+
const name = this.fullTestName(event.test);
|
|
92
|
+
const record = {
|
|
93
|
+
type: 'test',
|
|
94
|
+
name,
|
|
95
|
+
status: 'passed',
|
|
96
|
+
setupFnMs: 0,
|
|
97
|
+
beforeHooksMs: 0,
|
|
98
|
+
bodyMs: 0,
|
|
99
|
+
teardownFnMs: 0,
|
|
100
|
+
afterHooksMs: 0,
|
|
101
|
+
totalMs: 0,
|
|
102
|
+
startedAt: new Date(now).toISOString()
|
|
103
|
+
};
|
|
104
|
+
this.records.push(record);
|
|
105
|
+
this.recordsByName.set(name, record);
|
|
106
|
+
this.testStarts.set(name, now);
|
|
107
|
+
this.collector.current = name;
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case 'test_fn_start':
|
|
111
|
+
{
|
|
112
|
+
this.testStarts.set(`fn:${this.fullTestName(event.test)}`, now);
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
case 'test_fn_success':
|
|
116
|
+
case 'test_fn_failure':
|
|
117
|
+
{
|
|
118
|
+
const name = this.fullTestName(event.test);
|
|
119
|
+
const start = this.testStarts.get(`fn:${name}`);
|
|
120
|
+
const record = this.recordsByName.get(name);
|
|
121
|
+
if (record && start !== undefined) {
|
|
122
|
+
record.bodyMs = now - start;
|
|
123
|
+
}
|
|
124
|
+
if (record && event.name === 'test_fn_failure') {
|
|
125
|
+
record.status = 'failed';
|
|
126
|
+
}
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
case 'test_done':
|
|
130
|
+
{
|
|
131
|
+
const name = this.fullTestName(event.test);
|
|
132
|
+
const record = this.recordsByName.get(name);
|
|
133
|
+
const start = this.testStarts.get(name);
|
|
134
|
+
if (record && start !== undefined) {
|
|
135
|
+
record.totalMs = now - start;
|
|
136
|
+
}
|
|
137
|
+
if (record && event.test?.errors?.length) {
|
|
138
|
+
record.status = 'failed';
|
|
139
|
+
}
|
|
140
|
+
this.mergeFnSpans(name, record);
|
|
141
|
+
this.collector.current = null;
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
case 'teardown':
|
|
145
|
+
{
|
|
146
|
+
this.finalizeAndFlush();
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
default:
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/** The record for the test currently running, if any. */ currentRecord() {
|
|
154
|
+
return this.collector.current ? this.recordsByName.get(this.collector.current) : undefined;
|
|
155
|
+
}
|
|
156
|
+
/** Adds `ms` to a hook bucket on the current per-test record, or the suite record during beforeAll/afterAll. */ addToCurrent(field, ms) {
|
|
157
|
+
const record = this.currentRecord();
|
|
158
|
+
if (record) {
|
|
159
|
+
record[field] += ms;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/** Builds the full test name by walking up the describe blocks, matching jest's currentTestName. */ fullTestName(test) {
|
|
163
|
+
if (!test) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
const parts = [];
|
|
167
|
+
let node = test;
|
|
168
|
+
while(node && node.name && node.name !== 'ROOT_DESCRIBE_BLOCK'){
|
|
169
|
+
parts.unshift(node.name);
|
|
170
|
+
node = node.parent;
|
|
171
|
+
}
|
|
172
|
+
return parts.join(' ');
|
|
173
|
+
}
|
|
174
|
+
/** Moves fn spans tagged with `name` into the matching record's setup/teardown buckets. */ mergeFnSpans(name, record) {
|
|
175
|
+
if (!record) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const remaining = [];
|
|
179
|
+
for (const span of this.collector.fnSpans){
|
|
180
|
+
if (span.name === name) {
|
|
181
|
+
if (span.kind === 'setup') {
|
|
182
|
+
record.setupFnMs += span.ms;
|
|
183
|
+
} else if (span.kind === 'teardown') {
|
|
184
|
+
record.teardownFnMs += span.ms;
|
|
185
|
+
}
|
|
186
|
+
} else {
|
|
187
|
+
remaining.push(span);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
this.collector.fnSpans = remaining;
|
|
191
|
+
}
|
|
192
|
+
/** Finalizes the suite-scoped record (untagged fn spans + beforeAll/afterAll) and writes all JSONL. */ finalizeAndFlush() {
|
|
193
|
+
if (this.flushed || !this.timingFile) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
this.flushed = true;
|
|
197
|
+
const suite = {
|
|
198
|
+
setupFnMs: 0,
|
|
199
|
+
beforeHooksMs: this.suiteRecord.beforeHooksMs,
|
|
200
|
+
teardownFnMs: 0,
|
|
201
|
+
afterHooksMs: this.suiteRecord.afterHooksMs
|
|
202
|
+
};
|
|
203
|
+
for (const span of this.collector.fnSpans){
|
|
204
|
+
if (span.name === null || span.name === undefined) {
|
|
205
|
+
if (span.kind === 'setup') {
|
|
206
|
+
suite.setupFnMs += span.ms;
|
|
207
|
+
} else if (span.kind === 'teardown') {
|
|
208
|
+
suite.teardownFnMs += span.ms;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
this.collector.fnSpans = [];
|
|
213
|
+
const lines = [];
|
|
214
|
+
for (const record of this.records){
|
|
215
|
+
lines.push(this.toLine({
|
|
216
|
+
...record
|
|
217
|
+
}));
|
|
218
|
+
}
|
|
219
|
+
lines.push(this.toLine({
|
|
220
|
+
type: 'suite',
|
|
221
|
+
name: null,
|
|
222
|
+
status: 'passed',
|
|
223
|
+
setupFnMs: suite.setupFnMs,
|
|
224
|
+
beforeHooksMs: suite.beforeHooksMs,
|
|
225
|
+
teardownFnMs: suite.teardownFnMs,
|
|
226
|
+
afterHooksMs: suite.afterHooksMs,
|
|
227
|
+
totalMs: suite.beforeHooksMs + suite.afterHooksMs
|
|
228
|
+
}));
|
|
229
|
+
const payload = lines.join('\n') + '\n';
|
|
230
|
+
try {
|
|
231
|
+
// One file per worker process, but a worker may run several suites: append so we keep them all.
|
|
232
|
+
appendFileSync(this.timingFile, payload);
|
|
233
|
+
} catch {
|
|
234
|
+
try {
|
|
235
|
+
writeFileSync(this.timingFile, payload);
|
|
236
|
+
} catch {
|
|
237
|
+
// Timing is best-effort; never fail a test because we couldn't write the file.
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/** Flattens metadata onto a record and serializes to a single JSON line. */ toLine(record) {
|
|
242
|
+
const obj = {
|
|
243
|
+
suite: this.suite,
|
|
244
|
+
...record,
|
|
245
|
+
...this.meta
|
|
246
|
+
};
|
|
247
|
+
for (const key of Object.keys(obj)){
|
|
248
|
+
if (key.endsWith('Ms') && typeof obj[key] === 'number') {
|
|
249
|
+
obj[key] = Math.round(obj[key]);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return JSON.stringify(obj);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
@@ -172,7 +172,7 @@ const computeMultiplier = (rate, dt)=>{
|
|
|
172
172
|
expect(asset['last_updated_ts']).toEqual(BigInt(this.time));
|
|
173
173
|
for (const key of [
|
|
174
174
|
this.account.address,
|
|
175
|
-
AztecAddress.
|
|
175
|
+
AztecAddress.fromFieldUnsafe(await this.account.key())
|
|
176
176
|
]){
|
|
177
177
|
const { result: privatePos } = await this.lendingContract.methods.get_position(key).simulate({
|
|
178
178
|
from: this.account.address
|
|
@@ -42,4 +42,4 @@ export type WorkerWalletWrapper = {
|
|
|
42
42
|
cleanup: () => Promise<void>;
|
|
43
43
|
};
|
|
44
44
|
export declare function createWorkerWalletClient(nodeUrl: string, proverEnabled: boolean, logger: Logger): Promise<WorkerWalletWrapper>;
|
|
45
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
45
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dXBfdGVzdF93YWxsZXRzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3BhcnRhbi9zZXR1cF90ZXN0X3dhbGxldHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBSXpELE9BQU8sRUFBRSxLQUFLLGdCQUFnQixFQUE2QixNQUFNLHFCQUFxQixDQUFDO0FBR3ZGLE9BQU8sRUFBRSxLQUFLLFNBQVMsRUFBb0MsTUFBTSxzQkFBc0IsQ0FBQztBQUl4RixPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUVwRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFVL0QsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRTNELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUUvRCxNQUFNLFdBQVcsWUFBWTtJQUMzQixTQUFTLEVBQUUsU0FBUyxDQUFDO0lBQ3JCLE1BQU0sRUFBRSxVQUFVLENBQUM7SUFDbkIsUUFBUSxFQUFFLFlBQVksRUFBRSxDQUFDO0lBQ3pCLGFBQWEsRUFBRSxhQUFhLENBQUM7SUFDN0IsaUJBQWlCLEVBQUUsWUFBWSxDQUFDO0lBQ2hDLFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsZ0JBQWdCLEVBQUUsWUFBWSxDQUFDO0lBQy9CLFlBQVksRUFBRSxZQUFZLENBQUM7Q0FDNUI7QUFFRCxNQUFNLE1BQU0seUJBQXlCLEdBQUcsSUFBSSxDQUMxQyxZQUFZLEVBQ1osY0FBYyxHQUFHLGVBQWUsR0FBRyxXQUFXLEdBQUcsbUJBQW1CLENBQ3JFLENBQUM7QUFNRix3QkFBc0IsMkJBQTJCLENBQy9DLE9BQU8sRUFBRSxNQUFNLEVBQ2YsVUFBVSxFQUFFLE1BQU0sRUFDbEIsTUFBTSxFQUFFLE1BQU0sR0FDYixPQUFPLENBQUMsWUFBWSxDQUFDLENBeUJ2QjtBQUVELHdCQUFzQixxQ0FBcUMsQ0FDekQsTUFBTSxFQUFFLFVBQVUsRUFDbEIsU0FBUyxFQUFFLFNBQVMsRUFDcEIsVUFBVSxFQUFFLE1BQU0sRUFDbEIsTUFBTSxFQUFFLE1BQU0sRUFDZCxxQkFBcUIsU0FBSSxHQUN4QixPQUFPLENBQUMsWUFBWSxDQUFDLENBK0N2QjtBQThGRCx3QkFBc0IsMkJBQTJCLENBQy9DLE1BQU0sRUFBRSxVQUFVLEVBQ2xCLFNBQVMsRUFBRSxTQUFTLEVBQ3BCLE1BQU0sRUFBRSxNQUFNLEVBQ2QscUJBQXFCLFNBQUksRUFDekIsSUFBSSxDQUFDLEVBQUU7SUFBRSxXQUFXLENBQUMsRUFBRSxPQUFPLENBQUE7Q0FBRSxHQUMvQixPQUFPLENBQUMseUJBQXlCLENBQUMsQ0FpQ3BDO0FBRUQsd0JBQXNCLDRCQUE0QixDQUNoRCxPQUFPLEVBQUUsTUFBTSxFQUNmLFNBQVMsRUFBRSxNQUFNLEVBQUUsRUFDbkIsb0JBQW9CLEVBQUUsTUFBTSxFQUM1QixVQUFVLEVBQUUsTUFBTSxFQUNsQixNQUFNLEVBQUUsTUFBTSxFQUNkLHFCQUFxQixTQUFJLEdBQ3hCLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0ErQ3ZCO0FBK0VELHdCQUFzQixnQkFBZ0IsQ0FBQyxFQUNyQyxNQUFNLEVBQ04sWUFBWSxFQUNaLE1BQU0sRUFDTixjQUFjLEVBQ2QsTUFBTSxFQUNOLGdCQUFnQixFQUNqQixFQUFFO0lBQ0QsTUFBTSxFQUFFLFVBQVUsQ0FBQztJQUNuQixZQUFZLEVBQUUsWUFBWSxDQUFDO0lBQzNCLE1BQU0sRUFBRSxNQUFNLENBQUM7SUFDZixjQUFjLEVBQUUsTUFBTSxDQUFDO0lBQ3ZCLE1BQU0sRUFBRSxNQUFNLENBQUM7SUFDZixnQkFBZ0IsQ0FBQyxFQUFFLGdCQUFnQixDQUFDO0NBQ3JDLGlCQXVCQTtBQUVELE1BQU0sTUFBTSxhQUFhLEdBQUc7SUFDMUIsTUFBTSxFQUFFLFVBQVUsQ0FBQztJQUNuQixTQUFTLEVBQUUsU0FBUyxDQUFDO0lBQ3JCLE9BQU8sRUFBRSxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztDQUM5QixDQUFDO0FBRUYsd0JBQXNCLDhCQUE4QixDQUNsRCxPQUFPLEVBQUUsTUFBTSxFQUNmLGFBQWEsRUFBRSxPQUFPLEVBQ3RCLE1BQU0sRUFBRSxNQUFNLEdBQ2IsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQXFCeEI7QUFFRCxNQUFNLE1BQU0sbUJBQW1CLEdBQUc7SUFDaEMsTUFBTSxFQUFFLFlBQVksQ0FBQztJQUNyQixTQUFTLEVBQUUsU0FBUyxDQUFDO0lBQ3JCLE9BQU8sRUFBRSxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztDQUM5QixDQUFDO0FBRUYsd0JBQXNCLHdCQUF3QixDQUM1QyxPQUFPLEVBQUUsTUFBTSxFQUNmLGFBQWEsRUFBRSxPQUFPLEVBQ3RCLE1BQU0sRUFBRSxNQUFNLEdBQ2IsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBMkI5QiJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup_test_wallets.d.ts","sourceRoot":"","sources":["../../src/spartan/setup_test_wallets.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAIzD,OAAO,EAAE,KAAK,gBAAgB,EAA6B,MAAM,qBAAqB,CAAC;AAGvF,OAAO,EAAE,KAAK,SAAS,EAAoC,MAAM,sBAAsB,CAAC;AAIxF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"setup_test_wallets.d.ts","sourceRoot":"","sources":["../../src/spartan/setup_test_wallets.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@ import { createExtendedL1Client } from '@aztec/ethereum/client';
|
|
|
12
12
|
import { makeBackoff, retry, retryUntil } from '@aztec/foundation/retry';
|
|
13
13
|
import { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
14
14
|
import { Gas } from '@aztec/stdlib/gas';
|
|
15
|
+
import { TxStatus } from '@aztec/stdlib/tx';
|
|
15
16
|
import { getGasLimits } from '@aztec/wallet-sdk/base-wallet';
|
|
16
17
|
import { registerInitialLocalNetworkAccountsInWallet } from '@aztec/wallets/testing';
|
|
17
18
|
import { getACVMConfig } from '../fixtures/get_acvm_config.js';
|
|
@@ -276,9 +277,12 @@ export async function performTransfers({ wallet, testAccounts, rounds, transferA
|
|
|
276
277
|
});
|
|
277
278
|
});
|
|
278
279
|
const provenTxs = await Promise.all(txs);
|
|
280
|
+
// Wait only for the txs to be proposed, not checkpointed. This is enough to keep the chain
|
|
281
|
+
// loaded for the reorg scenario, and avoids each round blocking on the (slower) checkpoint lag.
|
|
279
282
|
await Promise.all(provenTxs.map((t)=>t.send({
|
|
280
283
|
wait: {
|
|
281
|
-
timeout: 600
|
|
284
|
+
timeout: 600,
|
|
285
|
+
waitForStatus: TxStatus.PROPOSED
|
|
282
286
|
}
|
|
283
287
|
})));
|
|
284
288
|
logger.info(`Completed round ${i + 1} / ${rounds}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/end-to-end",
|
|
3
|
-
"version": "5.0.0-rc.
|
|
3
|
+
"version": "5.0.0-rc.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -29,45 +29,45 @@
|
|
|
29
29
|
"formatting": "run -T prettier --check ./src && run -T eslint ./src"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@aztec/accounts": "5.0.0-rc.
|
|
33
|
-
"@aztec/archiver": "5.0.0-rc.
|
|
34
|
-
"@aztec/aztec": "5.0.0-rc.
|
|
35
|
-
"@aztec/aztec-node": "5.0.0-rc.
|
|
36
|
-
"@aztec/aztec.js": "5.0.0-rc.
|
|
37
|
-
"@aztec/bb-prover": "5.0.0-rc.
|
|
38
|
-
"@aztec/bb.js": "5.0.0-rc.
|
|
39
|
-
"@aztec/blob-client": "5.0.0-rc.
|
|
40
|
-
"@aztec/blob-lib": "5.0.0-rc.
|
|
41
|
-
"@aztec/bot": "5.0.0-rc.
|
|
42
|
-
"@aztec/cli": "5.0.0-rc.
|
|
43
|
-
"@aztec/constants": "5.0.0-rc.
|
|
44
|
-
"@aztec/entrypoints": "5.0.0-rc.
|
|
45
|
-
"@aztec/epoch-cache": "5.0.0-rc.
|
|
46
|
-
"@aztec/ethereum": "5.0.0-rc.
|
|
47
|
-
"@aztec/foundation": "5.0.0-rc.
|
|
48
|
-
"@aztec/kv-store": "5.0.0-rc.
|
|
49
|
-
"@aztec/l1-artifacts": "5.0.0-rc.
|
|
50
|
-
"@aztec/node-keystore": "5.0.0-rc.
|
|
51
|
-
"@aztec/noir-contracts.js": "5.0.0-rc.
|
|
52
|
-
"@aztec/noir-noirc_abi": "5.0.0-rc.
|
|
53
|
-
"@aztec/noir-protocol-circuits-types": "5.0.0-rc.
|
|
54
|
-
"@aztec/noir-test-contracts.js": "5.0.0-rc.
|
|
55
|
-
"@aztec/p2p": "5.0.0-rc.
|
|
56
|
-
"@aztec/protocol-contracts": "5.0.0-rc.
|
|
57
|
-
"@aztec/prover-client": "5.0.0-rc.
|
|
58
|
-
"@aztec/prover-node": "5.0.0-rc.
|
|
59
|
-
"@aztec/pxe": "5.0.0-rc.
|
|
60
|
-
"@aztec/sequencer-client": "5.0.0-rc.
|
|
61
|
-
"@aztec/simulator": "5.0.0-rc.
|
|
62
|
-
"@aztec/slasher": "5.0.0-rc.
|
|
63
|
-
"@aztec/standard-contracts": "5.0.0-rc.
|
|
64
|
-
"@aztec/stdlib": "5.0.0-rc.
|
|
65
|
-
"@aztec/telemetry-client": "5.0.0-rc.
|
|
66
|
-
"@aztec/validator-client": "5.0.0-rc.
|
|
67
|
-
"@aztec/validator-ha-signer": "5.0.0-rc.
|
|
68
|
-
"@aztec/wallet-sdk": "5.0.0-rc.
|
|
69
|
-
"@aztec/wallets": "5.0.0-rc.
|
|
70
|
-
"@aztec/world-state": "5.0.0-rc.
|
|
32
|
+
"@aztec/accounts": "5.0.0-rc.2",
|
|
33
|
+
"@aztec/archiver": "5.0.0-rc.2",
|
|
34
|
+
"@aztec/aztec": "5.0.0-rc.2",
|
|
35
|
+
"@aztec/aztec-node": "5.0.0-rc.2",
|
|
36
|
+
"@aztec/aztec.js": "5.0.0-rc.2",
|
|
37
|
+
"@aztec/bb-prover": "5.0.0-rc.2",
|
|
38
|
+
"@aztec/bb.js": "5.0.0-rc.2",
|
|
39
|
+
"@aztec/blob-client": "5.0.0-rc.2",
|
|
40
|
+
"@aztec/blob-lib": "5.0.0-rc.2",
|
|
41
|
+
"@aztec/bot": "5.0.0-rc.2",
|
|
42
|
+
"@aztec/cli": "5.0.0-rc.2",
|
|
43
|
+
"@aztec/constants": "5.0.0-rc.2",
|
|
44
|
+
"@aztec/entrypoints": "5.0.0-rc.2",
|
|
45
|
+
"@aztec/epoch-cache": "5.0.0-rc.2",
|
|
46
|
+
"@aztec/ethereum": "5.0.0-rc.2",
|
|
47
|
+
"@aztec/foundation": "5.0.0-rc.2",
|
|
48
|
+
"@aztec/kv-store": "5.0.0-rc.2",
|
|
49
|
+
"@aztec/l1-artifacts": "5.0.0-rc.2",
|
|
50
|
+
"@aztec/node-keystore": "5.0.0-rc.2",
|
|
51
|
+
"@aztec/noir-contracts.js": "5.0.0-rc.2",
|
|
52
|
+
"@aztec/noir-noirc_abi": "5.0.0-rc.2",
|
|
53
|
+
"@aztec/noir-protocol-circuits-types": "5.0.0-rc.2",
|
|
54
|
+
"@aztec/noir-test-contracts.js": "5.0.0-rc.2",
|
|
55
|
+
"@aztec/p2p": "5.0.0-rc.2",
|
|
56
|
+
"@aztec/protocol-contracts": "5.0.0-rc.2",
|
|
57
|
+
"@aztec/prover-client": "5.0.0-rc.2",
|
|
58
|
+
"@aztec/prover-node": "5.0.0-rc.2",
|
|
59
|
+
"@aztec/pxe": "5.0.0-rc.2",
|
|
60
|
+
"@aztec/sequencer-client": "5.0.0-rc.2",
|
|
61
|
+
"@aztec/simulator": "5.0.0-rc.2",
|
|
62
|
+
"@aztec/slasher": "5.0.0-rc.2",
|
|
63
|
+
"@aztec/standard-contracts": "5.0.0-rc.2",
|
|
64
|
+
"@aztec/stdlib": "5.0.0-rc.2",
|
|
65
|
+
"@aztec/telemetry-client": "5.0.0-rc.2",
|
|
66
|
+
"@aztec/validator-client": "5.0.0-rc.2",
|
|
67
|
+
"@aztec/validator-ha-signer": "5.0.0-rc.2",
|
|
68
|
+
"@aztec/wallet-sdk": "5.0.0-rc.2",
|
|
69
|
+
"@aztec/wallets": "5.0.0-rc.2",
|
|
70
|
+
"@aztec/world-state": "5.0.0-rc.2",
|
|
71
71
|
"@iarna/toml": "^2.2.5",
|
|
72
72
|
"@jest/globals": "^30.0.0",
|
|
73
73
|
"@noble/curves": "=1.0.0",
|
|
@@ -170,6 +170,6 @@
|
|
|
170
170
|
"setupFiles": [
|
|
171
171
|
"../../foundation/src/jest/setup.mjs"
|
|
172
172
|
],
|
|
173
|
-
"testEnvironment": "
|
|
173
|
+
"testEnvironment": "./shared/timing_env.mjs"
|
|
174
174
|
}
|
|
175
175
|
}
|
|
@@ -20,7 +20,7 @@ import { AMMContract } from '@aztec/noir-contracts.js/AMM';
|
|
|
20
20
|
import { FPCContract } from '@aztec/noir-contracts.js/FPC';
|
|
21
21
|
import { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice';
|
|
22
22
|
import { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC';
|
|
23
|
-
import {
|
|
23
|
+
import { TestTokenContract as BananaCoin, TestTokenContract } from '@aztec/noir-test-contracts.js/TestToken';
|
|
24
24
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
25
25
|
import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice';
|
|
26
26
|
import { type PXEConfig, getPXEConfig } from '@aztec/pxe/server';
|
|
@@ -28,7 +28,12 @@ import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
|
28
28
|
import { Gas, GasSettings } from '@aztec/stdlib/gas';
|
|
29
29
|
import { deriveSigningKey } from '@aztec/stdlib/keys';
|
|
30
30
|
|
|
31
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
AUTOMINE_E2E_OPTS,
|
|
33
|
+
L1_DIRECT_WRITE_ACCOUNT_INDEX,
|
|
34
|
+
MNEMONIC,
|
|
35
|
+
getPaddedMaxFeesPerGas,
|
|
36
|
+
} from '../../fixtures/fixtures.js';
|
|
32
37
|
import { type EndToEndContext, type SetupOptions, setup, teardown } from '../../fixtures/setup.js';
|
|
33
38
|
import { mintTokensToPrivate } from '../../fixtures/token_utils.js';
|
|
34
39
|
import { setupSponsoredFPC } from '../../fixtures/utils.js';
|
|
@@ -71,13 +76,13 @@ export class ClientFlowsBenchmark {
|
|
|
71
76
|
public bananaFPC!: FPCContract;
|
|
72
77
|
public bananaFPCInstance!: ContractInstanceWithAddress;
|
|
73
78
|
// Random asset we want to trade
|
|
74
|
-
public candyBarCoin!:
|
|
79
|
+
public candyBarCoin!: TestTokenContract;
|
|
75
80
|
public candyBarCoinInstance!: ContractInstanceWithAddress;
|
|
76
81
|
// AMM contract
|
|
77
82
|
public amm!: AMMContract;
|
|
78
83
|
public ammInstance!: ContractInstanceWithAddress;
|
|
79
84
|
// Liquidity token for AMM
|
|
80
|
-
public liquidityToken!:
|
|
85
|
+
public liquidityToken!: TestTokenContract;
|
|
81
86
|
public liquidityTokenInstance!: ContractInstanceWithAddress;
|
|
82
87
|
// Sponsored FPC contract
|
|
83
88
|
public sponsoredFPC!: SponsoredFPCContract;
|
|
@@ -134,7 +139,8 @@ export class ClientFlowsBenchmark {
|
|
|
134
139
|
async setup() {
|
|
135
140
|
this.logger.info('Setting up subsystems from fresh');
|
|
136
141
|
// Token allowlist entries are test-only: FPC-based fee payment with custom tokens won't work on mainnet alpha.
|
|
137
|
-
|
|
142
|
+
// BananaCoin is the codegen'd TestToken here, so the allowlist must key on its class, not canonical Token's.
|
|
143
|
+
const tokenAllowList = await getTokenAllowedSetupFunctions(BananaCoin.artifact);
|
|
138
144
|
this.context = await setup(2, {
|
|
139
145
|
...this.setupOptions,
|
|
140
146
|
fundSponsoredFPC: true,
|
|
@@ -235,7 +241,15 @@ export class ClientFlowsBenchmark {
|
|
|
235
241
|
this.feeJuiceBridgeTestHarness = await FeeJuicePortalTestingHarnessFactory.create({
|
|
236
242
|
aztecNode: this.context.aztecNodeService,
|
|
237
243
|
aztecNodeAdmin: this.context.aztecNodeService,
|
|
238
|
-
|
|
244
|
+
// Bridge from a dedicated L1 account so its direct writes don't race the sequencer publisher's
|
|
245
|
+
// txs on the deployer account (see L1_DIRECT_WRITE_ACCOUNT_INDEX).
|
|
246
|
+
l1Client: createExtendedL1Client(
|
|
247
|
+
this.context.config.l1RpcUrls,
|
|
248
|
+
MNEMONIC,
|
|
249
|
+
undefined,
|
|
250
|
+
undefined,
|
|
251
|
+
L1_DIRECT_WRITE_ACCOUNT_INDEX,
|
|
252
|
+
),
|
|
239
253
|
wallet: this.adminWallet,
|
|
240
254
|
logger: this.logger,
|
|
241
255
|
});
|
|
@@ -259,7 +273,7 @@ export class ClientFlowsBenchmark {
|
|
|
259
273
|
|
|
260
274
|
async applyDeployCandyBarToken() {
|
|
261
275
|
this.logger.info('Applying candy bar token deployment');
|
|
262
|
-
const { contract: candyBarCoin, instance: candyBarCoinInstance } = await
|
|
276
|
+
const { contract: candyBarCoin, instance: candyBarCoinInstance } = await TestTokenContract.deploy(
|
|
263
277
|
this.adminWallet,
|
|
264
278
|
this.adminAddress,
|
|
265
279
|
'CBC',
|
|
@@ -348,7 +362,7 @@ export class ClientFlowsBenchmark {
|
|
|
348
362
|
|
|
349
363
|
public async applyDeployAmm() {
|
|
350
364
|
this.logger.info('Applying AMM deployment');
|
|
351
|
-
const { contract: liquidityToken, instance: liquidityTokenInstance } = await
|
|
365
|
+
const { contract: liquidityToken, instance: liquidityTokenInstance } = await TestTokenContract.deploy(
|
|
352
366
|
this.adminWallet,
|
|
353
367
|
this.adminAddress,
|
|
354
368
|
'LPT',
|
|
@@ -40,6 +40,7 @@ export class CrossChainMessagingTest {
|
|
|
40
40
|
private setupOptions: SetupOptions;
|
|
41
41
|
private deployL1ContractsArgs: Partial<DeployAztecL1ContractsArgs>;
|
|
42
42
|
private pxeOpts: Partial<PXEConfig>;
|
|
43
|
+
private l1HarnessAccountIndex?: number;
|
|
43
44
|
logger: Logger;
|
|
44
45
|
context!: EndToEndContext;
|
|
45
46
|
aztecNode!: AztecNode;
|
|
@@ -79,6 +80,7 @@ export class CrossChainMessagingTest {
|
|
|
79
80
|
opts: SetupOptions = {},
|
|
80
81
|
deployL1ContractsArgs: Partial<DeployAztecL1ContractsArgs> = {},
|
|
81
82
|
pxeOpts: Partial<PXEConfig> = {},
|
|
83
|
+
l1HarnessAccountIndex?: number,
|
|
82
84
|
) {
|
|
83
85
|
this.logger = createLogger(`e2e:e2e_cross_chain_messaging:${testName}`);
|
|
84
86
|
this.setupOptions = opts;
|
|
@@ -87,6 +89,7 @@ export class CrossChainMessagingTest {
|
|
|
87
89
|
...deployL1ContractsArgs,
|
|
88
90
|
};
|
|
89
91
|
this.pxeOpts = pxeOpts;
|
|
92
|
+
this.l1HarnessAccountIndex = l1HarnessAccountIndex;
|
|
90
93
|
this.requireEpochProven = opts.startProverNode ?? false;
|
|
91
94
|
}
|
|
92
95
|
|
|
@@ -177,18 +180,24 @@ export class CrossChainMessagingTest {
|
|
|
177
180
|
|
|
178
181
|
await ensureAuthRegistryPublished(this.wallet, this.ownerAddress);
|
|
179
182
|
|
|
180
|
-
|
|
183
|
+
const harnessL1Client = createExtendedL1Client(
|
|
184
|
+
this.aztecNodeConfig.l1RpcUrls,
|
|
185
|
+
MNEMONIC,
|
|
186
|
+
undefined,
|
|
187
|
+
undefined,
|
|
188
|
+
this.l1HarnessAccountIndex,
|
|
189
|
+
);
|
|
181
190
|
|
|
182
|
-
const underlyingERC20Address = await deployL1Contract(
|
|
191
|
+
const underlyingERC20Address = await deployL1Contract(harnessL1Client, TestERC20Abi, TestERC20Bytecode, [
|
|
183
192
|
'Underlying',
|
|
184
193
|
'UND',
|
|
185
|
-
|
|
194
|
+
harnessL1Client.account.address,
|
|
186
195
|
]).then(({ address }) => address);
|
|
187
196
|
|
|
188
197
|
this.logger.verbose(`Setting up cross chain harness...`);
|
|
189
198
|
this.crossChainTestHarness = await CrossChainTestHarness.new(
|
|
190
199
|
this.aztecNode,
|
|
191
|
-
|
|
200
|
+
harnessL1Client,
|
|
192
201
|
this.wallet,
|
|
193
202
|
this.ownerAddress,
|
|
194
203
|
this.logger,
|
|
@@ -222,7 +231,7 @@ export class CrossChainMessagingTest {
|
|
|
222
231
|
this.ethAccount,
|
|
223
232
|
tokenPortalAddress,
|
|
224
233
|
crossChainContext.underlying,
|
|
225
|
-
|
|
234
|
+
harnessL1Client,
|
|
226
235
|
pickL1ContractAddresses(this.aztecNodeConfig),
|
|
227
236
|
this.wallet,
|
|
228
237
|
this.ownerAddress,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { InitialAccountData } from '@aztec/accounts/testing';
|
|
2
2
|
import type { Archiver } from '@aztec/archiver';
|
|
3
|
-
import { type AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
|
|
3
|
+
import { type AztecNodeConfig, AztecNodeService, createAztecNodeService } from '@aztec/aztec-node';
|
|
4
4
|
import { getAccountContractAddress } from '@aztec/aztec.js/account';
|
|
5
5
|
import type { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
6
6
|
import { getTimestampRangeForEpoch } from '@aztec/aztec.js/block';
|
|
@@ -310,7 +310,7 @@ export class EpochsTestContext {
|
|
|
310
310
|
const p2pEnabled = resolvedConfig.p2pEnabled || mockGossipSubNetwork !== undefined;
|
|
311
311
|
const p2pIp = resolvedConfig.p2pIp ?? (p2pEnabled ? '127.0.0.1' : undefined);
|
|
312
312
|
const node = await withLoggerBindings({ actor: `${actorPrefix}-${nodeIndex}` }, () =>
|
|
313
|
-
|
|
313
|
+
createAztecNodeService(
|
|
314
314
|
{
|
|
315
315
|
...resolvedConfig,
|
|
316
316
|
dataDirectory: join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')),
|
|
@@ -15,6 +15,10 @@ jest.setTimeout(300_000);
|
|
|
15
15
|
|
|
16
16
|
// Regression for https://github.com/AztecProtocol/aztec-packages/issues/12366
|
|
17
17
|
// Similar to e2e_fees/account_init but with no automine
|
|
18
|
+
// Disabled (.notest.ts): this regression was covered by fixes applied at each "wait for two blocks"
|
|
19
|
+
// site in the codebase; keeping the file as reference for the original race scenario. Uses FeesTest
|
|
20
|
+
// with prod sequencer (ethSlot=4s, aztecSlot=8s, inboxLag default, minTxsPerBlock=0) and
|
|
21
|
+
// GasBridgingTestHarness for L1↔L2 fee-juice bridging. Single account, fake in-proc prover node.
|
|
18
22
|
describe('e2e_fees bridging_race', () => {
|
|
19
23
|
const ETHEREUM_SLOT_DURATION = 4;
|
|
20
24
|
const AZTEC_SLOT_DURATION = ETHEREUM_SLOT_DURATION * 2;
|
|
@@ -50,6 +54,10 @@ describe('e2e_fees bridging_race', () => {
|
|
|
50
54
|
bobsAddress = bobsAccountManager.address;
|
|
51
55
|
});
|
|
52
56
|
|
|
57
|
+
// Reproduces a timing race where an L1→L2 fee-juice bridge message lands just before the end of an
|
|
58
|
+
// L2 slot, causing the archiver to miss it. The fix was to wait for the archiver to see the message
|
|
59
|
+
// before waiting for the required two-block confirmation. The sleep injected into approve() simulates
|
|
60
|
+
// the near-slot-boundary timing.
|
|
53
61
|
it('Alice bridges funds to Bob', async () => {
|
|
54
62
|
// Tweak the token manager so the bridging happens immediately before the end of the current L2 slot
|
|
55
63
|
// This caused the message to be "not in state" when tried to be used
|
|
@@ -59,6 +67,8 @@ describe('e2e_fees bridging_race', () => {
|
|
|
59
67
|
await origApprove(amount, address, addressName);
|
|
60
68
|
const sleepTime = (Number(t.chainMonitor.checkpointTimestamp) + AZTEC_SLOT_DURATION) * 1000 - Date.now() - 500;
|
|
61
69
|
logger.info(`Sleeping for ${sleepTime}ms until near end of L2 slot before sending L1 fee juice to L2 inbox`);
|
|
70
|
+
// REFACTOR: hand-rolled slot-boundary sleep; replace with a timing helper that derives the remaining
|
|
71
|
+
// slot time from the chain monitor's slot boundaries rather than computing it inline.
|
|
62
72
|
await sleep(sleepTime);
|
|
63
73
|
};
|
|
64
74
|
|
|
@@ -23,7 +23,7 @@ import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
|
23
23
|
|
|
24
24
|
import { getContract } from 'viem';
|
|
25
25
|
|
|
26
|
-
import { MNEMONIC, getPaddedMaxFeesPerGas } from '../fixtures/fixtures.js';
|
|
26
|
+
import { L1_DIRECT_WRITE_ACCOUNT_INDEX, MNEMONIC, getPaddedMaxFeesPerGas } from '../fixtures/fixtures.js';
|
|
27
27
|
import {
|
|
28
28
|
type EndToEndContext,
|
|
29
29
|
type SetupOptions,
|
|
@@ -213,7 +213,15 @@ export class FeesTest {
|
|
|
213
213
|
this.feeJuiceBridgeTestHarness = await FeeJuicePortalTestingHarnessFactory.create({
|
|
214
214
|
aztecNode: this.context.aztecNodeService,
|
|
215
215
|
aztecNodeAdmin: this.context.aztecNodeService,
|
|
216
|
-
|
|
216
|
+
// Bridge from a dedicated L1 account so its direct writes don't race the sequencer publisher's
|
|
217
|
+
// txs on the deployer account (see L1_DIRECT_WRITE_ACCOUNT_INDEX).
|
|
218
|
+
l1Client: createExtendedL1Client(
|
|
219
|
+
this.context.config.l1RpcUrls,
|
|
220
|
+
MNEMONIC,
|
|
221
|
+
undefined,
|
|
222
|
+
undefined,
|
|
223
|
+
L1_DIRECT_WRITE_ACCOUNT_INDEX,
|
|
224
|
+
),
|
|
217
225
|
wallet: this.wallet,
|
|
218
226
|
logger: this.logger,
|
|
219
227
|
});
|
|
@@ -66,6 +66,7 @@ export async function writeJson(
|
|
|
66
66
|
feePerL2Gas: Number(checkpointHeader.gasFees.feePerL2Gas),
|
|
67
67
|
},
|
|
68
68
|
totalManaUsed: checkpointHeader.totalManaUsed.toNumber(),
|
|
69
|
+
accumulatedFees: checkpointHeader.accumulatedFees.toNumber(),
|
|
69
70
|
},
|
|
70
71
|
headerHash: asHex(checkpointHeader.hash()),
|
|
71
72
|
numTxs: block.body.txEffects.length,
|