@aztec/end-to-end 0.0.1-commit.b33fc05d0 → 0.0.1-commit.b3d3157a
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/README.md +27 -0
- 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 +27 -38
- 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 +5 -4
- 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 +14 -5
- 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 +25 -2
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +86 -13
- 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 +32 -6
- 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.d.ts +1 -1
- package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -1
- package/dest/e2e_p2p/inactivity_slash_test.js +4 -3
- package/dest/e2e_p2p/p2p_network.d.ts +10 -9
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +46 -27
- 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 +29 -13
- package/dest/e2e_p2p/shared.d.ts +23 -14
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +62 -57
- 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/authwit_proxy.d.ts +1 -1
- package/dest/fixtures/authwit_proxy.d.ts.map +1 -1
- package/dest/fixtures/authwit_proxy.js +4 -0
- 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/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 -11
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +157 -28
- 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/forward-compatibility/wallet_rpc_client.d.ts +7 -0
- package/dest/forward-compatibility/wallet_rpc_client.d.ts.map +1 -0
- package/dest/forward-compatibility/wallet_rpc_client.js +15 -0
- package/dest/forward-compatibility/wallet_service.d.ts +3 -0
- package/dest/forward-compatibility/wallet_service.d.ts.map +1 -0
- package/dest/forward-compatibility/wallet_service.js +109 -0
- package/dest/install_legacy_contracts.d.cts +10 -0
- package/dest/install_legacy_contracts.d.cts.map +1 -0
- package/dest/legacy-jest-resolver.d.cts +3 -0
- package/dest/legacy-jest-resolver.d.cts.map +1 -0
- 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/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 +24 -12
- 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 +72 -48
- 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 +73 -20
- package/dest/spartan/utils/config.d.ts +9 -35
- package/dest/spartan/utils/config.d.ts.map +1 -1
- package/dest/spartan/utils/nodes.js +2 -2
- package/dest/test-wallet/test_wallet.d.ts +25 -23
- package/dest/test-wallet/test_wallet.d.ts.map +1 -1
- package/dest/test-wallet/test_wallet.js +146 -87
- 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 +5 -4
- 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 +46 -42
- package/src/bench/client_flows/benchmark.ts +19 -0
- package/src/bench/client_flows/client_flows_benchmark.ts +64 -53
- package/src/bench/utils.ts +2 -1
- package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +24 -10
- 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 +98 -11
- 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 +4 -3
- package/src/e2e_p2p/p2p_network.ts +57 -39
- package/src/e2e_p2p/reqresp/utils.ts +30 -12
- package/src/e2e_p2p/shared.ts +60 -71
- package/src/e2e_token_contract/token_contract_test.ts +12 -2
- package/src/fixtures/authwit_proxy.ts +4 -0
- package/src/fixtures/e2e_prover_test.ts +15 -18
- 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 +186 -33
- 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/forward-compatibility/wallet_rpc_client.ts +14 -0
- package/src/forward-compatibility/wallet_service.ts +104 -0
- package/src/guides/up_quick_start.sh +0 -2
- package/src/install_legacy_contracts.cjs +75 -0
- package/src/legacy-jest-resolver.cjs +112 -0
- package/src/shared/cross_chain_test_harness.ts +14 -4
- package/src/shared/gas_portal_test_harness.ts +20 -10
- 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 +28 -12
- package/src/simulators/token_simulator.ts +1 -1
- package/src/spartan/setup_test_wallets.ts +69 -43
- package/src/spartan/tx_metrics.ts +81 -23
- package/src/spartan/utils/nodes.ts +2 -2
- package/src/test-wallet/test_wallet.ts +174 -104
- 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 +10 -5
- package/src/test-wallet/worker_wallet_schema.ts +2 -2
|
@@ -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,30 +93,45 @@ export class LendingSimulator {
|
|
|
92
93
|
public stableCoin: TokenSimulator,
|
|
93
94
|
) {}
|
|
94
95
|
|
|
95
|
-
|
|
96
|
+
prepare() {
|
|
96
97
|
this.accumulator = BASE;
|
|
97
|
-
|
|
98
|
-
this.time = Number(await this.rollup.getTimestampForSlot(slot));
|
|
98
|
+
this.time = 0;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
|
|
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) {
|
|
102
115
|
if (diff <= 1) {
|
|
103
116
|
return;
|
|
104
117
|
}
|
|
105
118
|
|
|
106
|
-
const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.
|
|
119
|
+
const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.lastBlockTimestamp()));
|
|
107
120
|
const targetSlot = SlotNumber(slot + diff);
|
|
108
121
|
const ts = Number(await this.rollup.getTimestampForSlot(targetSlot));
|
|
109
|
-
const timeDiff = ts - this.time;
|
|
110
|
-
this.time = ts;
|
|
111
122
|
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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);
|
|
116
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.
|
|
117
134
|
await this.cc.rollup.markAsProven(await this.rollup.getCheckpointNumber());
|
|
118
|
-
this.accumulator = muldivDown(this.accumulator, computeMultiplier(this.rate, BigInt(timeDiff)), BASE);
|
|
119
135
|
}
|
|
120
136
|
|
|
121
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
|
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import { generateSchnorrAccounts } from '@aztec/accounts/testing';
|
|
2
|
+
import { NO_FROM } from '@aztec/aztec.js/account';
|
|
2
3
|
import { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
3
4
|
import { NO_WAIT } from '@aztec/aztec.js/contracts';
|
|
4
5
|
import { L1FeeJuicePortalManager } from '@aztec/aztec.js/ethereum';
|
|
5
6
|
import { FeeJuicePaymentMethodWithClaim } from '@aztec/aztec.js/fee';
|
|
6
7
|
import { type FeePaymentMethod, SponsoredFeePaymentMethod } from '@aztec/aztec.js/fee';
|
|
7
8
|
import { Fr } from '@aztec/aztec.js/fields';
|
|
9
|
+
import { waitForL1ToL2MessageReady } from '@aztec/aztec.js/messaging';
|
|
8
10
|
import { type AztecNode, createAztecNodeClient, waitForTx } from '@aztec/aztec.js/node';
|
|
9
11
|
import type { Wallet } from '@aztec/aztec.js/wallet';
|
|
10
12
|
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
11
13
|
import { createExtendedL1Client } from '@aztec/ethereum/client';
|
|
12
14
|
import type { Logger } from '@aztec/foundation/log';
|
|
13
|
-
import { retryUntil } from '@aztec/foundation/retry';
|
|
15
|
+
import { makeBackoff, retry, retryUntil } from '@aztec/foundation/retry';
|
|
14
16
|
import { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
15
17
|
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
18
|
+
import { TxStatus } from '@aztec/stdlib/tx';
|
|
16
19
|
import { registerInitialLocalNetworkAccountsInWallet } from '@aztec/wallets/testing';
|
|
17
20
|
|
|
18
21
|
import { getACVMConfig } from '../fixtures/get_acvm_config.js';
|
|
@@ -89,7 +92,7 @@ export async function deploySponsoredTestAccountsWithTokens(
|
|
|
89
92
|
const paymentMethod = new SponsoredFeePaymentMethod(await getSponsoredFPCAddress());
|
|
90
93
|
const recipientDeployMethod = await recipientAccount.getDeployMethod();
|
|
91
94
|
await recipientDeployMethod.send({
|
|
92
|
-
from:
|
|
95
|
+
from: NO_FROM,
|
|
93
96
|
fee: { paymentMethod },
|
|
94
97
|
wait: { timeout: 2400 },
|
|
95
98
|
});
|
|
@@ -97,7 +100,7 @@ export async function deploySponsoredTestAccountsWithTokens(
|
|
|
97
100
|
fundedAccounts.map(async a => {
|
|
98
101
|
const deployMethod = await a.getDeployMethod();
|
|
99
102
|
await deployMethod.send({
|
|
100
|
-
from:
|
|
103
|
+
from: NO_FROM,
|
|
101
104
|
fee: { paymentMethod },
|
|
102
105
|
wait: { timeout: 2400 },
|
|
103
106
|
}); // increase timeout on purpose in order to account for two empty epochs
|
|
@@ -137,38 +140,57 @@ async function deployAccountWithDiagnostics(
|
|
|
137
140
|
estimateGas?: boolean,
|
|
138
141
|
): Promise<void> {
|
|
139
142
|
const deployMethod = await account.getDeployMethod();
|
|
140
|
-
let
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
gasSettings = sim.estimatedGas;
|
|
146
|
-
logger.info(`${accountLabel} estimated gas: DA=${gasSettings.gasLimits.daGas} L2=${gasSettings.gasLimits.l2Gas}`);
|
|
147
|
-
}
|
|
148
|
-
const deployResult = await deployMethod.send({
|
|
149
|
-
from: AztecAddress.ZERO,
|
|
150
|
-
fee: { paymentMethod, gasSettings },
|
|
151
|
-
wait: NO_WAIT,
|
|
152
|
-
});
|
|
153
|
-
txHash = deployResult.txHash;
|
|
154
|
-
await waitForTx(aztecNode, txHash, { timeout: 2400 });
|
|
155
|
-
logger.info(`${accountLabel} deployed at ${account.address}`);
|
|
156
|
-
} catch (error) {
|
|
157
|
-
const blockNumber = await aztecNode.getBlockNumber();
|
|
158
|
-
let receipt;
|
|
159
|
-
try {
|
|
160
|
-
receipt = await aztecNode.getTxReceipt(txHash);
|
|
161
|
-
} catch {
|
|
162
|
-
receipt = 'unavailable';
|
|
163
|
-
}
|
|
164
|
-
logger.error(`${accountLabel} deployment failed`, {
|
|
165
|
-
txHash: txHash.toString(),
|
|
166
|
-
receipt: JSON.stringify(receipt),
|
|
167
|
-
currentBlockNumber: blockNumber,
|
|
168
|
-
error: String(error),
|
|
169
|
-
});
|
|
170
|
-
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}`);
|
|
171
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
|
+
);
|
|
172
194
|
}
|
|
173
195
|
|
|
174
196
|
async function deployAccountsInBatches(
|
|
@@ -269,7 +291,7 @@ export async function deployTestAccountsWithTokens(
|
|
|
269
291
|
fundedAccounts.map(async (a, i) => {
|
|
270
292
|
const paymentMethod = new FeeJuicePaymentMethodWithClaim(a.address, claims[i]);
|
|
271
293
|
const deployMethod = await a.getDeployMethod();
|
|
272
|
-
await deployMethod.send({ from:
|
|
294
|
+
await deployMethod.send({ from: NO_FROM, fee: { paymentMethod } });
|
|
273
295
|
logger.info(`Account deployed at ${a.address}`);
|
|
274
296
|
}),
|
|
275
297
|
);
|
|
@@ -312,9 +334,7 @@ async function bridgeL1FeeJuice(
|
|
|
312
334
|
const portal = await L1FeeJuicePortalManager.new(aztecNode, l1Client, log);
|
|
313
335
|
const claim = await portal.bridgeTokensPublic(recipient, amount, true /* mint */);
|
|
314
336
|
|
|
315
|
-
|
|
316
|
-
(await aztecNode.getL1ToL2MessageCheckpoint(Fr.fromHexString(claim.messageHash))) !== undefined;
|
|
317
|
-
await retryUntil(isSynced, `message ${claim.messageHash} sync`, 24, 0.5);
|
|
337
|
+
await waitForL1ToL2MessageReady(aztecNode, Fr.fromHexString(claim.messageHash), { timeoutSeconds: 24 });
|
|
318
338
|
|
|
319
339
|
log.info(`Created a claim for ${amount} L1 fee juice to ${recipient}.`, claim);
|
|
320
340
|
return claim;
|
|
@@ -345,14 +365,18 @@ async function deployTokenAndMint(
|
|
|
345
365
|
logger: Logger,
|
|
346
366
|
) {
|
|
347
367
|
logger.verbose(`Deploying TokenContract...`);
|
|
348
|
-
const {
|
|
349
|
-
|
|
350
|
-
|
|
368
|
+
const { contract: tokenContract } = await TokenContract.deploy(
|
|
369
|
+
wallet,
|
|
370
|
+
admin,
|
|
371
|
+
TOKEN_NAME,
|
|
372
|
+
TOKEN_SYMBOL,
|
|
373
|
+
TOKEN_DECIMALS,
|
|
374
|
+
).send({
|
|
351
375
|
from: admin,
|
|
352
376
|
fee: {
|
|
353
377
|
paymentMethod,
|
|
354
378
|
},
|
|
355
|
-
wait: { timeout: 600
|
|
379
|
+
wait: { timeout: 600 },
|
|
356
380
|
});
|
|
357
381
|
|
|
358
382
|
const tokenAddress = tokenContract.address;
|
|
@@ -403,7 +427,9 @@ export async function performTransfers({
|
|
|
403
427
|
|
|
404
428
|
const provenTxs = await Promise.all(txs);
|
|
405
429
|
|
|
406
|
-
|
|
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 } })));
|
|
407
433
|
|
|
408
434
|
logger.info(`Completed round ${i + 1} / ${rounds}`);
|
|
409
435
|
}
|