@aztec/end-to-end 0.0.1-commit.2448fdb → 0.0.1-commit.2606882
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/bench/client_flows/benchmark.d.ts +15 -1
- package/dest/bench/client_flows/benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/benchmark.js +17 -0
- package/dest/bench/client_flows/client_flows_benchmark.d.ts +2 -2
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.js +25 -35
- package/dest/bench/utils.d.ts +1 -1
- package/dest/bench/utils.d.ts.map +1 -1
- package/dest/bench/utils.js +2 -0
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +3 -3
- 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 +13 -4
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +15 -4
- 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 +39 -7
- package/dest/e2e_deploy_contract/deploy_test.d.ts +3 -3
- package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
- package/dest/e2e_deploy_contract/deploy_test.js +2 -1
- package/dest/e2e_epochs/epochs_test.d.ts +23 -2
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +83 -12
- package/dest/e2e_fees/fees_test.d.ts +5 -2
- package/dest/e2e_fees/fees_test.d.ts.map +1 -1
- package/dest/e2e_fees/fees_test.js +31 -5
- package/dest/e2e_nested_contract/nested_contract_test.d.ts +3 -3
- package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
- package/dest/e2e_nested_contract/nested_contract_test.js +2 -1
- package/dest/e2e_p2p/inactivity_slash_test.js +3 -3
- package/dest/e2e_p2p/p2p_network.d.ts +11 -10
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +47 -28
- package/dest/e2e_p2p/reqresp/utils.d.ts +1 -1
- package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -1
- package/dest/e2e_p2p/reqresp/utils.js +42 -13
- package/dest/e2e_p2p/shared.d.ts +23 -26
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +62 -80
- package/dest/e2e_token_contract/token_contract_test.d.ts +3 -3
- package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
- package/dest/e2e_token_contract/token_contract_test.js +4 -2
- package/dest/fixtures/e2e_prover_test.d.ts +6 -5
- package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
- package/dest/fixtures/e2e_prover_test.js +9 -13
- package/dest/fixtures/elu_monitor.d.ts +21 -0
- package/dest/fixtures/elu_monitor.d.ts.map +1 -0
- package/dest/fixtures/elu_monitor.js +102 -0
- package/dest/fixtures/fixtures.d.ts +70 -1
- package/dest/fixtures/fixtures.d.ts.map +1 -1
- package/dest/fixtures/fixtures.js +65 -0
- package/dest/fixtures/get_bb_config.d.ts +1 -1
- package/dest/fixtures/get_bb_config.d.ts.map +1 -1
- package/dest/fixtures/get_bb_config.js +5 -5
- package/dest/fixtures/ha_setup.d.ts +2 -2
- package/dest/fixtures/ha_setup.d.ts.map +1 -1
- package/dest/fixtures/ha_setup.js +1 -1
- package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts +25 -0
- package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts.map +1 -0
- package/dest/fixtures/schnorr_hardcoded_account_contract.js +37 -0
- package/dest/fixtures/setup.d.ts +44 -10
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +145 -19
- package/dest/fixtures/setup_p2p_test.d.ts +10 -6
- package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.js +8 -8
- package/dest/fixtures/token_utils.d.ts +1 -1
- package/dest/fixtures/token_utils.d.ts.map +1 -1
- package/dest/fixtures/token_utils.js +2 -5
- package/dest/fixtures/utils.d.ts +2 -2
- package/dest/fixtures/utils.d.ts.map +1 -1
- package/dest/fixtures/utils.js +1 -1
- package/dest/install_legacy_contracts.d.cts +1 -1
- package/dest/install_legacy_contracts.d.cts.map +1 -1
- package/dest/legacy-jest-resolver.d.cts +1 -1
- package/dest/legacy-jest-resolver.d.cts.map +1 -1
- package/dest/shared/cross_chain_test_harness.d.ts +4 -2
- package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
- package/dest/shared/cross_chain_test_harness.js +9 -5
- package/dest/shared/gas_portal_test_harness.d.ts +8 -5
- package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
- package/dest/shared/gas_portal_test_harness.js +17 -8
- package/dest/shared/jest_setup.js +41 -1
- package/dest/shared/submit-transactions.d.ts +1 -1
- package/dest/shared/submit-transactions.d.ts.map +1 -1
- package/dest/shared/uniswap_l1_l2.d.ts +1 -1
- package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
- package/dest/shared/uniswap_l1_l2.js +50 -32
- package/dest/shared/wait_for_l1_to_l2_message.d.ts +13 -0
- package/dest/shared/wait_for_l1_to_l2_message.d.ts.map +1 -0
- package/dest/shared/wait_for_l1_to_l2_message.js +10 -0
- package/dest/simulators/lending_simulator.d.ts +10 -3
- package/dest/simulators/lending_simulator.d.ts.map +1 -1
- package/dest/simulators/lending_simulator.js +23 -11
- package/dest/simulators/token_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 +67 -43
- package/dest/spartan/tx_metrics.d.ts +18 -4
- package/dest/spartan/tx_metrics.d.ts.map +1 -1
- package/dest/spartan/tx_metrics.js +74 -21
- package/dest/spartan/utils/config.d.ts +10 -30
- package/dest/spartan/utils/config.d.ts.map +1 -1
- package/dest/spartan/utils/config.js +3 -1
- package/dest/spartan/utils/index.d.ts +2 -1
- package/dest/spartan/utils/index.d.ts.map +1 -1
- package/dest/spartan/utils/index.js +2 -0
- package/dest/spartan/utils/nodes.d.ts +4 -5
- package/dest/spartan/utils/nodes.d.ts.map +1 -1
- package/dest/spartan/utils/nodes.js +11 -11
- package/dest/spartan/utils/pod_logs.d.ts +25 -0
- package/dest/spartan/utils/pod_logs.d.ts.map +1 -0
- package/dest/spartan/utils/pod_logs.js +74 -0
- package/dest/test-wallet/test_wallet.d.ts +3 -2
- package/dest/test-wallet/test_wallet.d.ts.map +1 -1
- package/dest/test-wallet/test_wallet.js +52 -28
- package/dest/test-wallet/utils.d.ts +3 -3
- package/dest/test-wallet/utils.d.ts.map +1 -1
- package/dest/test-wallet/utils.js +2 -7
- package/dest/test-wallet/wallet_worker_script.js +7 -2
- package/dest/test-wallet/worker_wallet.d.ts +2 -1
- package/dest/test-wallet/worker_wallet.d.ts.map +1 -1
- package/dest/test-wallet/worker_wallet.js +6 -2
- package/dest/test-wallet/worker_wallet_schema.d.ts +110 -224
- package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -1
- package/dest/test-wallet/worker_wallet_schema.js +14 -2
- package/package.json +48 -46
- package/src/bench/client_flows/benchmark.ts +19 -0
- package/src/bench/client_flows/client_flows_benchmark.ts +62 -51
- package/src/bench/utils.ts +2 -1
- package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +21 -4
- package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +49 -11
- package/src/e2e_deploy_contract/deploy_test.ts +3 -2
- package/src/e2e_epochs/epochs_test.ts +85 -9
- package/src/e2e_fees/fees_test.ts +37 -4
- package/src/e2e_nested_contract/nested_contract_test.ts +3 -1
- package/src/e2e_p2p/inactivity_slash_test.ts +3 -3
- package/src/e2e_p2p/p2p_network.ts +58 -40
- package/src/e2e_p2p/reqresp/utils.ts +51 -12
- package/src/e2e_p2p/shared.ts +60 -113
- package/src/e2e_token_contract/token_contract_test.ts +12 -2
- package/src/fixtures/dumps/epoch_proof_result.json +1 -1
- package/src/fixtures/e2e_prover_test.ts +15 -18
- package/src/fixtures/elu_monitor.ts +126 -0
- package/src/fixtures/fixtures.ts +83 -0
- package/src/fixtures/get_bb_config.ts +7 -6
- package/src/fixtures/ha_setup.ts +4 -2
- package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
- package/src/fixtures/setup.ts +175 -24
- package/src/fixtures/setup_p2p_test.ts +13 -9
- package/src/fixtures/token_utils.ts +1 -4
- package/src/fixtures/utils.ts +2 -0
- package/src/guides/up_quick_start.sh +0 -2
- package/src/install_legacy_contracts.cjs +9 -5
- package/src/legacy-jest-resolver.cjs +15 -4
- package/src/shared/cross_chain_test_harness.ts +14 -4
- package/src/shared/gas_portal_test_harness.ts +20 -10
- package/src/shared/jest_setup.ts +51 -1
- package/src/shared/submit-transactions.ts +1 -4
- package/src/shared/uniswap_l1_l2.ts +84 -40
- package/src/shared/wait_for_l1_to_l2_message.ts +23 -0
- package/src/simulators/lending_simulator.ts +27 -13
- package/src/simulators/token_simulator.ts +1 -1
- package/src/spartan/setup_test_wallets.ts +65 -40
- package/src/spartan/tx_metrics.ts +82 -24
- package/src/spartan/utils/config.ts +2 -0
- package/src/spartan/utils/index.ts +3 -0
- package/src/spartan/utils/nodes.ts +17 -12
- package/src/spartan/utils/pod_logs.ts +99 -0
- package/src/test-wallet/test_wallet.ts +49 -24
- package/src/test-wallet/utils.ts +3 -7
- package/src/test-wallet/wallet_worker_script.ts +5 -2
- package/src/test-wallet/worker_wallet.ts +7 -3
- package/src/test-wallet/worker_wallet_schema.ts +2 -2
|
@@ -8,7 +8,12 @@ import type { ExtendedViemWalletClient } from '@aztec/ethereum/types';
|
|
|
8
8
|
import { retryUntil } from '@aztec/foundation/retry';
|
|
9
9
|
import { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice';
|
|
10
10
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
11
|
-
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
11
|
+
import type { AztecNodeAdmin, AztecNodeDebug } from '@aztec/stdlib/interfaces/client';
|
|
12
|
+
|
|
13
|
+
import { waitForL1ToL2MessageSeen } from './wait_for_l1_to_l2_message.js';
|
|
14
|
+
|
|
15
|
+
/** Aztec node that may expose the debug mining API in local e2e setups. */
|
|
16
|
+
type MiningAztecNode = AztecNode & Partial<AztecNodeDebug>;
|
|
12
17
|
|
|
13
18
|
export interface IGasBridgingTestHarness {
|
|
14
19
|
getL1FeeJuiceBalance(address: EthAddress): Promise<bigint>;
|
|
@@ -19,7 +24,7 @@ export interface IGasBridgingTestHarness {
|
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
export interface FeeJuicePortalTestingHarnessFactoryConfig {
|
|
22
|
-
aztecNode:
|
|
27
|
+
aztecNode: MiningAztecNode;
|
|
23
28
|
aztecNodeAdmin?: AztecNodeAdmin;
|
|
24
29
|
l1Client: ExtendedViemWalletClient;
|
|
25
30
|
wallet: Wallet;
|
|
@@ -75,7 +80,7 @@ export class GasBridgingTestHarness implements IGasBridgingTestHarness {
|
|
|
75
80
|
|
|
76
81
|
constructor(
|
|
77
82
|
/** Aztec node */
|
|
78
|
-
public aztecNode:
|
|
83
|
+
public aztecNode: MiningAztecNode,
|
|
79
84
|
/** Aztec node admin interface */
|
|
80
85
|
public aztecNodeAdmin: AztecNodeAdmin | undefined,
|
|
81
86
|
/** Wallet. */
|
|
@@ -144,8 +149,7 @@ export class GasBridgingTestHarness implements IGasBridgingTestHarness {
|
|
|
144
149
|
await this.mintTokensOnL1();
|
|
145
150
|
const claim = await this.sendTokensToPortalPublic(bridgeAmount, owner);
|
|
146
151
|
|
|
147
|
-
|
|
148
|
-
await retryUntil(isSynced, `message ${claim.messageHash} sync`, 24, 1);
|
|
152
|
+
await waitForL1ToL2MessageSeen(this.aztecNode, Fr.fromHexString(claim.messageHash), { timeoutSeconds: 24 });
|
|
149
153
|
|
|
150
154
|
// Progress by 2 L2 blocks so that the l1ToL2Message added above will be available to use on L2.
|
|
151
155
|
await this.advanceL2Block();
|
|
@@ -163,6 +167,11 @@ export class GasBridgingTestHarness implements IGasBridgingTestHarness {
|
|
|
163
167
|
}
|
|
164
168
|
|
|
165
169
|
private async advanceL2Block() {
|
|
170
|
+
if (this.aztecNode.mineBlock) {
|
|
171
|
+
await this.aztecNode.mineBlock();
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
166
175
|
const initialBlockNumber = await this.aztecNode.getBlockNumber();
|
|
167
176
|
|
|
168
177
|
let minTxsPerBlock = undefined;
|
|
@@ -171,11 +180,12 @@ export class GasBridgingTestHarness implements IGasBridgingTestHarness {
|
|
|
171
180
|
await this.aztecNodeAdmin.setConfig({ minTxsPerBlock: 0 }); // Set to 0 to ensure we can advance the block
|
|
172
181
|
}
|
|
173
182
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
183
|
+
try {
|
|
184
|
+
await retryUntil(async () => (await this.aztecNode.getBlockNumber()) >= initialBlockNumber + 1);
|
|
185
|
+
} finally {
|
|
186
|
+
if (this.aztecNodeAdmin && minTxsPerBlock !== undefined) {
|
|
187
|
+
await this.aztecNodeAdmin.setConfig({ minTxsPerBlock });
|
|
188
|
+
}
|
|
178
189
|
}
|
|
179
190
|
}
|
|
180
191
|
}
|
|
181
|
-
// docs:end:cross_chain_test_harness
|
package/src/shared/jest_setup.ts
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import { createLogger } from '@aztec/aztec.js/log';
|
|
2
2
|
|
|
3
|
-
import { beforeEach, expect } from '@jest/globals';
|
|
3
|
+
import { afterAll, afterEach, beforeEach, expect } from '@jest/globals';
|
|
4
|
+
import { readlinkSync } from 'fs';
|
|
4
5
|
import { basename } from 'path';
|
|
5
6
|
|
|
7
|
+
import { EluMonitor } from '../fixtures/elu_monitor.js';
|
|
8
|
+
|
|
9
|
+
const eluMonitor = process.env.ELU_MONITOR_FILE
|
|
10
|
+
? new EluMonitor(process.env.ELU_MONITOR_FILE, Number(process.env.ELU_MONITOR_INTERVAL_MS) || undefined)
|
|
11
|
+
: undefined;
|
|
12
|
+
|
|
13
|
+
if (eluMonitor) {
|
|
14
|
+
process.on('exit', () => eluMonitor.stop());
|
|
15
|
+
}
|
|
16
|
+
|
|
6
17
|
beforeEach(() => {
|
|
7
18
|
const { testPath, currentTestName } = expect.getState();
|
|
8
19
|
if (!testPath || !currentTestName) {
|
|
@@ -10,4 +21,43 @@ beforeEach(() => {
|
|
|
10
21
|
}
|
|
11
22
|
const logger = createLogger(`e2e:${basename(testPath).replace('.test.ts', '')}`);
|
|
12
23
|
logger.info(`Running test: ${currentTestName}`);
|
|
24
|
+
eluMonitor?.startTest(currentTestName);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
eluMonitor?.stopTest();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Log leaked handles after all tests complete. This runs after test-level afterAll hooks,
|
|
32
|
+
// so any handles still alive at this point were not properly cleaned up during teardown.
|
|
33
|
+
// This diagnostic helps identify the source of exit hangs without masking them.
|
|
34
|
+
afterAll(() => {
|
|
35
|
+
const handles = (process as any)._getActiveHandles();
|
|
36
|
+
if (handles.length > 0) {
|
|
37
|
+
const details = handles.map((h: any) => {
|
|
38
|
+
const type = h?.constructor?.name ?? typeof h;
|
|
39
|
+
const fd = h?.fd ?? h?._handle?.fd ?? '?';
|
|
40
|
+
const destroyed = h?.destroyed ?? '?';
|
|
41
|
+
const hasRef = typeof h?.hasRef === 'function' ? h.hasRef() : '?';
|
|
42
|
+
const localAddr = h?.localAddress ?? '';
|
|
43
|
+
const remoteAddr = h?.remoteAddress ?? '';
|
|
44
|
+
const localPort = h?.localPort ?? '';
|
|
45
|
+
const remotePort = h?.remotePort ?? '';
|
|
46
|
+
const proto = Object.getPrototypeOf(h)?.constructor?.name ?? '?';
|
|
47
|
+
const keys = Object.keys(h).slice(0, 10).join(',');
|
|
48
|
+
let fdTarget = '';
|
|
49
|
+
if (typeof fd === 'number') {
|
|
50
|
+
try {
|
|
51
|
+
fdTarget = ` -> ${readlinkSync(`/proc/self/fd/${fd}`)}`;
|
|
52
|
+
} catch {
|
|
53
|
+
// ignore
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return ` ${type}(fd=${fd}, destroyed=${destroyed}, hasRef=${hasRef}${fdTarget}) proto=${proto} addr=${localAddr}:${localPort}->${remoteAddr}:${remotePort} keys=[${keys}]`;
|
|
57
|
+
});
|
|
58
|
+
process.stderr.write(
|
|
59
|
+
`\n[jest_setup] WARNING: ${handles.length} handle(s) still active after teardown:\n${details.join('\n')}\n` +
|
|
60
|
+
`These may prevent Jest from exiting. Investigate and fix the leak.\n\n`,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
13
63
|
});
|
|
@@ -19,10 +19,7 @@ export const submitTxsTo = async (
|
|
|
19
19
|
times(numTxs, async () => {
|
|
20
20
|
const accountManager = await wallet.createSchnorrAccount(Fr.random(), Fr.random(), GrumpkinScalar.random());
|
|
21
21
|
const deployMethod = await accountManager.getDeployMethod();
|
|
22
|
-
const { txHash } = await deployMethod.send({
|
|
23
|
-
from: submitter,
|
|
24
|
-
wait: NO_WAIT,
|
|
25
|
-
});
|
|
22
|
+
const { txHash } = await deployMethod.send({ from: submitter, wait: NO_WAIT });
|
|
26
23
|
|
|
27
24
|
logger.info(`Tx sent with hash ${txHash}`);
|
|
28
25
|
const receipt: TxReceipt = await wallet.getTxReceipt(txHash);
|
|
@@ -13,15 +13,19 @@ import type { ExtendedViemWalletClient } from '@aztec/ethereum/types';
|
|
|
13
13
|
import { extractEvent } from '@aztec/ethereum/utils';
|
|
14
14
|
import { EpochNumber } from '@aztec/foundation/branded-types';
|
|
15
15
|
import { sha256ToField } from '@aztec/foundation/crypto/sha256';
|
|
16
|
+
import { retryUntil } from '@aztec/foundation/retry';
|
|
16
17
|
import { InboxAbi, UniswapPortalAbi, UniswapPortalBytecode } from '@aztec/l1-artifacts';
|
|
17
18
|
import { UniswapContract } from '@aztec/noir-contracts.js/Uniswap';
|
|
18
19
|
import { computeL2ToL1MessageHash } from '@aztec/stdlib/hash';
|
|
19
|
-
import { computeL2ToL1MembershipWitness } from '@aztec/stdlib/messaging';
|
|
20
20
|
|
|
21
21
|
import { jest } from '@jest/globals';
|
|
22
22
|
import { type GetContractReturnType, getContract, parseEther, toFunctionSelector } from 'viem';
|
|
23
23
|
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
type EndToEndContext,
|
|
26
|
+
ensureAccountContractsPublished,
|
|
27
|
+
ensureAuthRegistryPublished,
|
|
28
|
+
} from '../fixtures/utils.js';
|
|
25
29
|
import type { TestWallet } from '../test-wallet/test_wallet.js';
|
|
26
30
|
import { CrossChainTestHarness } from './cross_chain_test_harness.js';
|
|
27
31
|
|
|
@@ -32,7 +36,7 @@ import { CrossChainTestHarness } from './cross_chain_test_harness.js';
|
|
|
32
36
|
// anvil --fork-url https://mainnet.infura.io/v3/9928b52099854248b3a096be07a6b23c --fork-block-number 17514288 --chain-id 31337
|
|
33
37
|
// For CI, this is configured in `run_tests.sh` and `docker-compose-images.yml`
|
|
34
38
|
|
|
35
|
-
const TIMEOUT =
|
|
39
|
+
const TIMEOUT = 15 * 60 * 1000;
|
|
36
40
|
|
|
37
41
|
export const uniswapL1L2TestSuite = (
|
|
38
42
|
setup: () => Promise<EndToEndContext>,
|
|
@@ -98,6 +102,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
98
102
|
ownerEthAddress = EthAddress.fromString((await l1Client.getAddresses())[0]);
|
|
99
103
|
|
|
100
104
|
await ensureAccountContractsPublished(wallet, [ownerAddress, sponsorAddress]);
|
|
105
|
+
await ensureAuthRegistryPublished(wallet, ownerAddress);
|
|
101
106
|
|
|
102
107
|
logger.info('Deploying DAI Portal, initializing and deploying l2 contract...');
|
|
103
108
|
daiCrossChainHarness = await CrossChainTestHarness.new(
|
|
@@ -154,7 +159,6 @@ export const uniswapL1L2TestSuite = (
|
|
|
154
159
|
await cleanup();
|
|
155
160
|
});
|
|
156
161
|
|
|
157
|
-
// docs:start:uniswap_private
|
|
158
162
|
it('should uniswap trade on L1 from L2 funds privately (swaps WETH -> DAI)', async () => {
|
|
159
163
|
const wethL1BeforeBalance = await wethCrossChainHarness.getL1BalanceOf(ownerEthAddress);
|
|
160
164
|
|
|
@@ -251,14 +255,13 @@ export const uniswapL1L2TestSuite = (
|
|
|
251
255
|
// ensure that uniswap contract didn't eat the funds.
|
|
252
256
|
await wethCrossChainHarness.expectPublicBalanceOnL2(uniswapL2Contract.address, 0n);
|
|
253
257
|
|
|
254
|
-
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
await cheatCodes.rollup.advanceToEpoch(EpochNumber(epoch + 1));
|
|
258
|
+
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch
|
|
259
|
+
// before we can ask the witness helper for a covering root.
|
|
260
|
+
const minedReceipt = await aztecNode.getTxReceipt(l2UniswapInteractionReceipt.txHash);
|
|
261
|
+
if (minedReceipt.epochNumber === undefined) {
|
|
262
|
+
throw new Error('L2 Uniswap interaction tx is not yet in an epoch');
|
|
263
|
+
}
|
|
264
|
+
await cheatCodes.rollup.advanceToEpoch(EpochNumber(minedReceipt.epochNumber + 1));
|
|
262
265
|
await waitForProven(aztecNode, l2UniswapInteractionReceipt, { provenTimeout: 300 });
|
|
263
266
|
|
|
264
267
|
// 5. Consume L2 to L1 message by calling uniswapPortal.swap_private()
|
|
@@ -266,11 +269,19 @@ export const uniswapL1L2TestSuite = (
|
|
|
266
269
|
const daiL1BalanceOfPortalBeforeSwap = await daiCrossChainHarness.getL1BalanceOf(
|
|
267
270
|
daiCrossChainHarness.tokenPortalAddress,
|
|
268
271
|
);
|
|
269
|
-
const
|
|
270
|
-
aztecNode,
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
272
|
+
const swapResult = await retryUntil(
|
|
273
|
+
() => aztecNode.getL2ToL1MembershipWitness(minedReceipt.txHash, swapPrivateLeaf),
|
|
274
|
+
'swap private l2 to l1 witness',
|
|
275
|
+
60,
|
|
276
|
+
1,
|
|
277
|
+
);
|
|
278
|
+
const { epochNumber: epoch, numCheckpointsInEpoch } = swapResult;
|
|
279
|
+
const withdrawResult = await retryUntil(
|
|
280
|
+
() => aztecNode.getL2ToL1MembershipWitness(minedReceipt.txHash, withdrawLeaf),
|
|
281
|
+
'withdraw l2 to l1 witness',
|
|
282
|
+
60,
|
|
283
|
+
1,
|
|
284
|
+
);
|
|
274
285
|
|
|
275
286
|
const swapPrivateL2MessageIndex = swapResult.leafIndex;
|
|
276
287
|
const swapPrivateSiblingPath = swapResult.siblingPath;
|
|
@@ -280,6 +291,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
280
291
|
|
|
281
292
|
const withdrawMessageMetadata = {
|
|
282
293
|
_epoch: BigInt(epoch),
|
|
294
|
+
_numCheckpointsInEpoch: BigInt(withdrawResult.numCheckpointsInEpoch),
|
|
283
295
|
_leafIndex: BigInt(withdrawL2MessageIndex),
|
|
284
296
|
_path: withdrawSiblingPath
|
|
285
297
|
.toBufferArray()
|
|
@@ -288,6 +300,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
288
300
|
|
|
289
301
|
const swapPrivateMessageMetadata = {
|
|
290
302
|
_epoch: BigInt(epoch),
|
|
303
|
+
_numCheckpointsInEpoch: BigInt(numCheckpointsInEpoch),
|
|
291
304
|
_leafIndex: BigInt(swapPrivateL2MessageIndex),
|
|
292
305
|
_path: swapPrivateSiblingPath
|
|
293
306
|
.toBufferArray()
|
|
@@ -345,10 +358,8 @@ export const uniswapL1L2TestSuite = (
|
|
|
345
358
|
logger.info('WETH balance after swap : ', wethL2BalanceAfterSwap.toString());
|
|
346
359
|
logger.info('DAI balance after swap : ', daiL2BalanceAfterSwap.toString());
|
|
347
360
|
});
|
|
348
|
-
// docs:end:uniswap_private
|
|
349
361
|
|
|
350
362
|
// TODO(#7463): reenable look into this failure https://github.com/AztecProtocol/aztec-packages/actions/runs/9912612912/job/27388320150?pr=7462
|
|
351
|
-
// // docs:start:uniswap_public
|
|
352
363
|
// it('should uniswap trade on L1 from L2 funds publicly (swaps WETH -> DAI)', async () => {
|
|
353
364
|
// const wethL1BeforeBalance = await wethCrossChainHarness.getL1BalanceOf(ownerEthAddress);
|
|
354
365
|
|
|
@@ -581,7 +592,6 @@ export const uniswapL1L2TestSuite = (
|
|
|
581
592
|
// logger.info('WETH balance after swap : ', wethL2BalanceAfterSwap.toString());
|
|
582
593
|
// logger.info('DAI balance after swap : ', daiL2BalanceAfterSwap.toString());
|
|
583
594
|
// });
|
|
584
|
-
// // docs:end:uniswap_public
|
|
585
595
|
|
|
586
596
|
// Edge cases for the private flow:
|
|
587
597
|
// note - tests for uniswapPortal.sol and minting asset on L2 are covered in other tests.
|
|
@@ -847,9 +857,31 @@ export const uniswapL1L2TestSuite = (
|
|
|
847
857
|
chainId: new Fr(l1Client.chain.id),
|
|
848
858
|
});
|
|
849
859
|
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
860
|
+
// ensure that user's funds were burnt
|
|
861
|
+
await wethCrossChainHarness.expectPrivateBalanceOnL2(ownerAddress, wethL2BalanceBeforeSwap - wethAmountToBridge);
|
|
862
|
+
|
|
863
|
+
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch
|
|
864
|
+
// before we can ask the witness helper for a covering root.
|
|
865
|
+
const minedReceipt = await aztecNode.getTxReceipt(withdrawReceipt.txHash);
|
|
866
|
+
if (minedReceipt.epochNumber === undefined) {
|
|
867
|
+
throw new Error('Withdraw tx is not yet in an epoch');
|
|
868
|
+
}
|
|
869
|
+
await cheatCodes.rollup.advanceToEpoch(EpochNumber(minedReceipt.epochNumber + 1));
|
|
870
|
+
await waitForProven(aztecNode, withdrawReceipt, { provenTimeout: 300 });
|
|
871
|
+
|
|
872
|
+
const swapResult = await retryUntil(
|
|
873
|
+
() => aztecNode.getL2ToL1MembershipWitness(minedReceipt.txHash, swapPrivateLeaf),
|
|
874
|
+
'swap private l2 to l1 witness',
|
|
875
|
+
60,
|
|
876
|
+
1,
|
|
877
|
+
);
|
|
878
|
+
const { epochNumber: epoch, numCheckpointsInEpoch } = swapResult;
|
|
879
|
+
const withdrawResult = await retryUntil(
|
|
880
|
+
() => aztecNode.getL2ToL1MembershipWitness(minedReceipt.txHash, withdrawLeaf),
|
|
881
|
+
'withdraw l2 to l1 witness',
|
|
882
|
+
60,
|
|
883
|
+
1,
|
|
884
|
+
);
|
|
853
885
|
|
|
854
886
|
const swapPrivateL2MessageIndex = swapResult.leafIndex;
|
|
855
887
|
const swapPrivateSiblingPath = swapResult.siblingPath;
|
|
@@ -859,6 +891,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
859
891
|
|
|
860
892
|
const withdrawMessageMetadata = {
|
|
861
893
|
_epoch: BigInt(epoch),
|
|
894
|
+
_numCheckpointsInEpoch: BigInt(withdrawResult.numCheckpointsInEpoch),
|
|
862
895
|
_leafIndex: BigInt(withdrawL2MessageIndex),
|
|
863
896
|
_path: withdrawSiblingPath
|
|
864
897
|
.toBufferArray()
|
|
@@ -867,19 +900,13 @@ export const uniswapL1L2TestSuite = (
|
|
|
867
900
|
|
|
868
901
|
const swapPrivateMessageMetadata = {
|
|
869
902
|
_epoch: BigInt(epoch),
|
|
903
|
+
_numCheckpointsInEpoch: BigInt(numCheckpointsInEpoch),
|
|
870
904
|
_leafIndex: BigInt(swapPrivateL2MessageIndex),
|
|
871
905
|
_path: swapPrivateSiblingPath
|
|
872
906
|
.toBufferArray()
|
|
873
907
|
.map((buf: Buffer) => `0x${buf.toString('hex')}`) as readonly `0x${string}`[],
|
|
874
908
|
};
|
|
875
909
|
|
|
876
|
-
// ensure that user's funds were burnt
|
|
877
|
-
await wethCrossChainHarness.expectPrivateBalanceOnL2(ownerAddress, wethL2BalanceBeforeSwap - wethAmountToBridge);
|
|
878
|
-
|
|
879
|
-
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch.
|
|
880
|
-
await cheatCodes.rollup.advanceToEpoch(EpochNumber(epoch + 1));
|
|
881
|
-
await waitForProven(aztecNode, withdrawReceipt, { provenTimeout: 300 });
|
|
882
|
-
|
|
883
910
|
// On L1 call swap_public!
|
|
884
911
|
logger.info('call swap_public on L1');
|
|
885
912
|
const swapArgs = [
|
|
@@ -979,9 +1006,31 @@ export const uniswapL1L2TestSuite = (
|
|
|
979
1006
|
chainId: new Fr(l1Client.chain.id),
|
|
980
1007
|
});
|
|
981
1008
|
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
1009
|
+
// check weth balance of owner on L2 (we first bridged `wethAmountToBridge` into L2 and now withdrew it!)
|
|
1010
|
+
await wethCrossChainHarness.expectPublicBalanceOnL2(ownerAddress, 0n);
|
|
1011
|
+
|
|
1012
|
+
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch
|
|
1013
|
+
// before we can ask the witness helper for a covering root.
|
|
1014
|
+
const minedReceipt = await aztecNode.getTxReceipt(withdrawReceipt.txHash);
|
|
1015
|
+
if (minedReceipt.epochNumber === undefined) {
|
|
1016
|
+
throw new Error('Withdraw tx is not yet in an epoch');
|
|
1017
|
+
}
|
|
1018
|
+
await cheatCodes.rollup.advanceToEpoch(EpochNumber(minedReceipt.epochNumber + 1));
|
|
1019
|
+
await waitForProven(aztecNode, withdrawReceipt, { provenTimeout: 300 });
|
|
1020
|
+
|
|
1021
|
+
const swapResult = await retryUntil(
|
|
1022
|
+
() => aztecNode.getL2ToL1MembershipWitness(minedReceipt.txHash, swapPublicLeaf),
|
|
1023
|
+
'swap public l2 to l1 witness',
|
|
1024
|
+
60,
|
|
1025
|
+
1,
|
|
1026
|
+
);
|
|
1027
|
+
const { epochNumber: epoch, numCheckpointsInEpoch } = swapResult;
|
|
1028
|
+
const withdrawResult = await retryUntil(
|
|
1029
|
+
() => aztecNode.getL2ToL1MembershipWitness(minedReceipt.txHash, withdrawLeaf),
|
|
1030
|
+
'withdraw l2 to l1 witness',
|
|
1031
|
+
60,
|
|
1032
|
+
1,
|
|
1033
|
+
);
|
|
985
1034
|
|
|
986
1035
|
const swapPublicL2MessageIndex = swapResult.leafIndex;
|
|
987
1036
|
const swapPublicSiblingPath = swapResult.siblingPath;
|
|
@@ -991,6 +1040,7 @@ export const uniswapL1L2TestSuite = (
|
|
|
991
1040
|
|
|
992
1041
|
const withdrawMessageMetadata = {
|
|
993
1042
|
_epoch: BigInt(epoch),
|
|
1043
|
+
_numCheckpointsInEpoch: BigInt(withdrawResult.numCheckpointsInEpoch),
|
|
994
1044
|
_leafIndex: BigInt(withdrawL2MessageIndex),
|
|
995
1045
|
_path: withdrawSiblingPath
|
|
996
1046
|
.toBufferArray()
|
|
@@ -999,19 +1049,13 @@ export const uniswapL1L2TestSuite = (
|
|
|
999
1049
|
|
|
1000
1050
|
const swapPublicMessageMetadata = {
|
|
1001
1051
|
_epoch: BigInt(epoch),
|
|
1052
|
+
_numCheckpointsInEpoch: BigInt(numCheckpointsInEpoch),
|
|
1002
1053
|
_leafIndex: BigInt(swapPublicL2MessageIndex),
|
|
1003
1054
|
_path: swapPublicSiblingPath
|
|
1004
1055
|
.toBufferArray()
|
|
1005
1056
|
.map((buf: Buffer) => `0x${buf.toString('hex')}`) as readonly `0x${string}`[],
|
|
1006
1057
|
};
|
|
1007
1058
|
|
|
1008
|
-
// check weth balance of owner on L2 (we first bridged `wethAmountToBridge` into L2 and now withdrew it!)
|
|
1009
|
-
await wethCrossChainHarness.expectPublicBalanceOnL2(ownerAddress, 0n);
|
|
1010
|
-
|
|
1011
|
-
// Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch.
|
|
1012
|
-
await cheatCodes.rollup.advanceToEpoch(EpochNumber(epoch + 1));
|
|
1013
|
-
await waitForProven(aztecNode, withdrawReceipt, { provenTimeout: 300 });
|
|
1014
|
-
|
|
1015
1059
|
// Call swap_private on L1
|
|
1016
1060
|
logger.info('Execute withdraw and swap on the uniswapPortal!');
|
|
1017
1061
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Fr } from '@aztec/aztec.js/fields';
|
|
2
|
+
import type { AztecNode } from '@aztec/aztec.js/node';
|
|
3
|
+
import { retryUntil } from '@aztec/foundation/retry';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Waits until the archiver has seen the L1 to L2 message and indexed it. Unlike
|
|
7
|
+
* {@link waitForL1ToL2MessageReady} from `@aztec/aztec.js/messaging`, this does not
|
|
8
|
+
* require the L2 chain to have advanced to the message's checkpoint — it only confirms
|
|
9
|
+
* the message has been picked up from L1. Use this in tests that explicitly produce L2
|
|
10
|
+
* blocks afterwards to make the message consumable.
|
|
11
|
+
*/
|
|
12
|
+
export function waitForL1ToL2MessageSeen(
|
|
13
|
+
node: Pick<AztecNode, 'getL1ToL2MessageCheckpoint'>,
|
|
14
|
+
l1ToL2MessageHash: Fr,
|
|
15
|
+
opts: { timeoutSeconds: number },
|
|
16
|
+
) {
|
|
17
|
+
return retryUntil(
|
|
18
|
+
async () => (await node.getL1ToL2MessageCheckpoint(l1ToL2MessageHash)) !== undefined,
|
|
19
|
+
`L1 to L2 message ${l1ToL2MessageHash.toString()} seen`,
|
|
20
|
+
opts.timeoutSeconds,
|
|
21
|
+
1,
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -7,6 +7,7 @@ import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
|
7
7
|
import { poseidon2Hash } from '@aztec/foundation/crypto/poseidon';
|
|
8
8
|
import type { TestDateProvider } from '@aztec/foundation/timer';
|
|
9
9
|
import type { LendingContract } from '@aztec/noir-contracts.js/Lending';
|
|
10
|
+
import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client';
|
|
10
11
|
|
|
11
12
|
import type { TokenSimulator } from './token_simulator.js';
|
|
12
13
|
|
|
@@ -92,15 +93,25 @@ export class LendingSimulator {
|
|
|
92
93
|
public stableCoin: TokenSimulator,
|
|
93
94
|
) {}
|
|
94
95
|
|
|
95
|
-
|
|
96
|
+
prepare() {
|
|
96
97
|
this.accumulator = BASE;
|
|
97
|
-
|
|
98
|
-
BigInt(await this.cc.eth.lastBlockTimestamp()) + BigInt(this.ethereumSlotDuration),
|
|
99
|
-
);
|
|
100
|
-
this.time = Number(await this.rollup.getTimestampForSlot(slot));
|
|
98
|
+
this.time = 0;
|
|
101
99
|
}
|
|
102
100
|
|
|
103
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Advances the simulator's accumulator and clock to match a block timestamp observed on chain.
|
|
103
|
+
* Call this BEFORE applying any accumulator-sensitive mutation (borrow/repay) so the mutation
|
|
104
|
+
* sees the same accumulator as the contract did during execution.
|
|
105
|
+
*/
|
|
106
|
+
observeBlockTimestamp(ts: number) {
|
|
107
|
+
const diff = ts - this.time;
|
|
108
|
+
if (diff > 0) {
|
|
109
|
+
this.accumulator = muldivDown(this.accumulator, computeMultiplier(this.rate, BigInt(diff)), BASE);
|
|
110
|
+
}
|
|
111
|
+
this.time = ts;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async progressSlots(diff: number, _dateProvider?: TestDateProvider, node?: AztecNode & AztecNodeDebug) {
|
|
104
115
|
if (diff <= 1) {
|
|
105
116
|
return;
|
|
106
117
|
}
|
|
@@ -108,16 +119,19 @@ export class LendingSimulator {
|
|
|
108
119
|
const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.lastBlockTimestamp()));
|
|
109
120
|
const targetSlot = SlotNumber(slot + diff);
|
|
110
121
|
const ts = Number(await this.rollup.getTimestampForSlot(targetSlot));
|
|
111
|
-
const timeDiff = ts - this.time;
|
|
112
|
-
this.time = ts;
|
|
113
122
|
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
123
|
+
// Queue-aware warp under AutomineSequencer: atomic warp + mineBlock that advances L2 time to the
|
|
124
|
+
// target slot. The cheat code routes through the AutomineSequencer queue when one is installed,
|
|
125
|
+
// and otherwise falls back to a manual warp + mineBlock loop.
|
|
126
|
+
if (node) {
|
|
127
|
+
await this.cc.warpL2TimeAtLeastTo(node, ts);
|
|
128
|
+
} else {
|
|
129
|
+
await this.cc.eth.warp(ts - this.ethereumSlotDuration);
|
|
118
130
|
}
|
|
131
|
+
|
|
132
|
+
// Mark the latest checkpoint as proven so the rollup does not reorg pending checkpoints when
|
|
133
|
+
// time jumps far enough forward to cross an unproven epoch boundary.
|
|
119
134
|
await this.cc.rollup.markAsProven(await this.rollup.getCheckpointNumber());
|
|
120
|
-
this.accumulator = muldivDown(this.accumulator, computeMultiplier(this.rate, BigInt(timeDiff)), BASE);
|
|
121
135
|
}
|
|
122
136
|
|
|
123
137
|
depositPrivate(from: AztecAddress, onBehalfOf: Fr, amount: bigint) {
|
|
@@ -110,7 +110,7 @@ export class TokenSimulator {
|
|
|
110
110
|
chunk(calls, 5).map(batch => new BatchCall(this.defaultWallet, batch).simulate({ from: this.defaultAddress })),
|
|
111
111
|
)
|
|
112
112
|
)
|
|
113
|
-
.
|
|
113
|
+
.flatMap(r => r.result)
|
|
114
114
|
.map(r => r.result);
|
|
115
115
|
expect(results[0]).toEqual(this.totalSupply);
|
|
116
116
|
|
|
@@ -6,14 +6,16 @@ import { L1FeeJuicePortalManager } from '@aztec/aztec.js/ethereum';
|
|
|
6
6
|
import { FeeJuicePaymentMethodWithClaim } from '@aztec/aztec.js/fee';
|
|
7
7
|
import { type FeePaymentMethod, SponsoredFeePaymentMethod } from '@aztec/aztec.js/fee';
|
|
8
8
|
import { Fr } from '@aztec/aztec.js/fields';
|
|
9
|
+
import { waitForL1ToL2MessageReady } from '@aztec/aztec.js/messaging';
|
|
9
10
|
import { type AztecNode, createAztecNodeClient, waitForTx } from '@aztec/aztec.js/node';
|
|
10
11
|
import type { Wallet } from '@aztec/aztec.js/wallet';
|
|
11
12
|
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
12
13
|
import { createExtendedL1Client } from '@aztec/ethereum/client';
|
|
13
14
|
import type { Logger } from '@aztec/foundation/log';
|
|
14
|
-
import { retryUntil } from '@aztec/foundation/retry';
|
|
15
|
+
import { makeBackoff, retry, retryUntil } from '@aztec/foundation/retry';
|
|
15
16
|
import { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
16
17
|
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
18
|
+
import { TxStatus } from '@aztec/stdlib/tx';
|
|
17
19
|
import { registerInitialLocalNetworkAccountsInWallet } from '@aztec/wallets/testing';
|
|
18
20
|
|
|
19
21
|
import { getACVMConfig } from '../fixtures/get_acvm_config.js';
|
|
@@ -138,38 +140,57 @@ async function deployAccountWithDiagnostics(
|
|
|
138
140
|
estimateGas?: boolean,
|
|
139
141
|
): Promise<void> {
|
|
140
142
|
const deployMethod = await account.getDeployMethod();
|
|
141
|
-
let
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
gasSettings = sim.estimatedGas;
|
|
147
|
-
logger.info(`${accountLabel} estimated gas: DA=${gasSettings.gasLimits.daGas} L2=${gasSettings.gasLimits.l2Gas}`);
|
|
148
|
-
}
|
|
149
|
-
const deployResult = await deployMethod.send({
|
|
150
|
-
from: NO_FROM,
|
|
151
|
-
fee: { paymentMethod, gasSettings },
|
|
152
|
-
wait: NO_WAIT,
|
|
153
|
-
});
|
|
154
|
-
txHash = deployResult.txHash;
|
|
155
|
-
await waitForTx(aztecNode, txHash, { timeout: 2400 });
|
|
156
|
-
logger.info(`${accountLabel} deployed at ${account.address}`);
|
|
157
|
-
} catch (error) {
|
|
158
|
-
const blockNumber = await aztecNode.getBlockNumber();
|
|
159
|
-
let receipt;
|
|
160
|
-
try {
|
|
161
|
-
receipt = await aztecNode.getTxReceipt(txHash);
|
|
162
|
-
} catch {
|
|
163
|
-
receipt = 'unavailable';
|
|
164
|
-
}
|
|
165
|
-
logger.error(`${accountLabel} deployment failed`, {
|
|
166
|
-
txHash: txHash.toString(),
|
|
167
|
-
receipt: JSON.stringify(receipt),
|
|
168
|
-
currentBlockNumber: blockNumber,
|
|
169
|
-
error: String(error),
|
|
170
|
-
});
|
|
171
|
-
throw error;
|
|
143
|
+
let gasSettings: any;
|
|
144
|
+
if (estimateGas) {
|
|
145
|
+
const sim = await deployMethod.simulate({ from: NO_FROM, fee: { paymentMethod } });
|
|
146
|
+
gasSettings = sim.estimatedGas;
|
|
147
|
+
logger.info(`${accountLabel} estimated gas: DA=${gasSettings.gasLimits.daGas} L2=${gasSettings.gasLimits.l2Gas}`);
|
|
172
148
|
}
|
|
149
|
+
|
|
150
|
+
// Track the tx hash across retries so we don't re-send when the previous tx is still pending.
|
|
151
|
+
let sentTxHash: { txHash: any } | undefined;
|
|
152
|
+
|
|
153
|
+
await retry(
|
|
154
|
+
async () => {
|
|
155
|
+
// Check if already deployed (handles case where previous attempt succeeded but waitForTx timed out)
|
|
156
|
+
const existing = await aztecNode.getContract(account.address);
|
|
157
|
+
if (existing) {
|
|
158
|
+
logger.info(`${accountLabel} already deployed at ${account.address}, skipping`);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// If we already sent a tx, check if it was dropped before deciding to re-send.
|
|
163
|
+
if (sentTxHash) {
|
|
164
|
+
const prevReceipt = await aztecNode.getTxReceipt(sentTxHash.txHash);
|
|
165
|
+
if (prevReceipt.isDropped()) {
|
|
166
|
+
logger.info(`${accountLabel} previous tx ${sentTxHash.txHash} was dropped, re-sending`);
|
|
167
|
+
sentTxHash = undefined;
|
|
168
|
+
} else {
|
|
169
|
+
logger.info(`${accountLabel} previous tx ${sentTxHash.txHash} still pending, waiting again...`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (!sentTxHash) {
|
|
174
|
+
const deployResult = await deployMethod.send({
|
|
175
|
+
from: NO_FROM,
|
|
176
|
+
fee: { paymentMethod, gasSettings },
|
|
177
|
+
wait: NO_WAIT,
|
|
178
|
+
});
|
|
179
|
+
sentTxHash = { txHash: deployResult.txHash };
|
|
180
|
+
logger.info(`${accountLabel} tx sent`, { txHash: sentTxHash.txHash.toString() });
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const receipt = await waitForTx(aztecNode, sentTxHash.txHash, { timeout: 600 });
|
|
184
|
+
if (receipt.isDropped()) {
|
|
185
|
+
sentTxHash = undefined;
|
|
186
|
+
throw new Error(`${accountLabel} tx was dropped, retrying...`);
|
|
187
|
+
}
|
|
188
|
+
logger.info(`${accountLabel} deployed at ${account.address}`);
|
|
189
|
+
},
|
|
190
|
+
`deploy ${accountLabel}`,
|
|
191
|
+
makeBackoff([1, 2, 4, 8, 16]),
|
|
192
|
+
logger,
|
|
193
|
+
);
|
|
173
194
|
}
|
|
174
195
|
|
|
175
196
|
async function deployAccountsInBatches(
|
|
@@ -313,9 +334,7 @@ async function bridgeL1FeeJuice(
|
|
|
313
334
|
const portal = await L1FeeJuicePortalManager.new(aztecNode, l1Client, log);
|
|
314
335
|
const claim = await portal.bridgeTokensPublic(recipient, amount, true /* mint */);
|
|
315
336
|
|
|
316
|
-
|
|
317
|
-
(await aztecNode.getL1ToL2MessageCheckpoint(Fr.fromHexString(claim.messageHash))) !== undefined;
|
|
318
|
-
await retryUntil(isSynced, `message ${claim.messageHash} sync`, 24, 0.5);
|
|
337
|
+
await waitForL1ToL2MessageReady(aztecNode, Fr.fromHexString(claim.messageHash), { timeoutSeconds: 24 });
|
|
319
338
|
|
|
320
339
|
log.info(`Created a claim for ${amount} L1 fee juice to ${recipient}.`, claim);
|
|
321
340
|
return claim;
|
|
@@ -346,14 +365,18 @@ async function deployTokenAndMint(
|
|
|
346
365
|
logger: Logger,
|
|
347
366
|
) {
|
|
348
367
|
logger.verbose(`Deploying TokenContract...`);
|
|
349
|
-
const {
|
|
350
|
-
|
|
351
|
-
|
|
368
|
+
const { contract: tokenContract } = await TokenContract.deploy(
|
|
369
|
+
wallet,
|
|
370
|
+
admin,
|
|
371
|
+
TOKEN_NAME,
|
|
372
|
+
TOKEN_SYMBOL,
|
|
373
|
+
TOKEN_DECIMALS,
|
|
374
|
+
).send({
|
|
352
375
|
from: admin,
|
|
353
376
|
fee: {
|
|
354
377
|
paymentMethod,
|
|
355
378
|
},
|
|
356
|
-
wait: { timeout: 600
|
|
379
|
+
wait: { timeout: 600 },
|
|
357
380
|
});
|
|
358
381
|
|
|
359
382
|
const tokenAddress = tokenContract.address;
|
|
@@ -404,7 +427,9 @@ export async function performTransfers({
|
|
|
404
427
|
|
|
405
428
|
const provenTxs = await Promise.all(txs);
|
|
406
429
|
|
|
407
|
-
|
|
430
|
+
// Wait only for the txs to be proposed, not checkpointed. This is enough to keep the chain
|
|
431
|
+
// loaded for the reorg scenario, and avoids each round blocking on the (slower) checkpoint lag.
|
|
432
|
+
await Promise.all(provenTxs.map(t => t.send({ wait: { timeout: 600, waitForStatus: TxStatus.PROPOSED } })));
|
|
408
433
|
|
|
409
434
|
logger.info(`Completed round ${i + 1} / ${rounds}`);
|
|
410
435
|
}
|