@aztec/end-to-end 0.0.1-commit.e3c1de76 → 0.0.1-commit.e57c76e
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 +3 -3
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.js +36 -39
- package/dest/bench/client_flows/config.d.ts +2 -2
- package/dest/bench/client_flows/config.d.ts.map +1 -1
- package/dest/bench/client_flows/config.js +18 -0
- package/dest/bench/utils.d.ts +1 -1
- package/dest/bench/utils.d.ts.map +1 -1
- package/dest/bench/utils.js +8 -3
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +8 -5
- 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 +36 -17
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +16 -5
- 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 +42 -9
- package/dest/e2e_deploy_contract/deploy_test.d.ts +4 -4
- 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 +33 -8
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +143 -44
- package/dest/e2e_fees/fees_test.d.ts +6 -3
- package/dest/e2e_fees/fees_test.d.ts.map +1 -1
- package/dest/e2e_fees/fees_test.js +50 -17
- 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 +6 -7
- 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 +14 -12
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +70 -34
- package/dest/e2e_p2p/reqresp/utils.d.ts +3 -3
- package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -1
- package/dest/e2e_p2p/reqresp/utils.js +67 -14
- package/dest/e2e_p2p/shared.d.ts +37 -8
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +91 -51
- package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts +2 -0
- package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts.map +1 -0
- package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.js +184 -0
- package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts +18 -0
- package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts.map +1 -0
- package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.js +120 -0
- package/dest/e2e_token_contract/token_contract_test.d.ts +6 -4
- package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
- package/dest/e2e_token_contract/token_contract_test.js +23 -11
- package/dest/fixtures/authwit_proxy.d.ts +15 -0
- package/dest/fixtures/authwit_proxy.d.ts.map +1 -0
- package/dest/fixtures/authwit_proxy.js +34 -0
- package/dest/fixtures/e2e_prover_test.d.ts +9 -8
- package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
- package/dest/fixtures/e2e_prover_test.js +39 -50
- 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 +74 -1
- package/dest/fixtures/fixtures.d.ts.map +1 -1
- package/dest/fixtures/fixtures.js +71 -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 +71 -0
- package/dest/fixtures/ha_setup.d.ts.map +1 -0
- package/dest/fixtures/ha_setup.js +116 -0
- package/dest/fixtures/index.d.ts +2 -1
- package/dest/fixtures/index.d.ts.map +1 -1
- package/dest/fixtures/index.js +1 -0
- 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 +86 -32
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +209 -169
- package/dest/fixtures/setup_p2p_test.d.ts +22 -10
- package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.js +23 -17
- package/dest/fixtures/token_utils.d.ts +2 -2
- package/dest/fixtures/token_utils.d.ts.map +1 -1
- package/dest/fixtures/token_utils.js +5 -7
- 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 +22 -18
- 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 +19 -10
- package/dest/shared/index.d.ts +2 -1
- package/dest/shared/index.d.ts.map +1 -1
- package/dest/shared/index.js +1 -0
- package/dest/shared/jest_setup.js +41 -1
- package/dest/shared/mock_state_view.d.ts +86 -0
- package/dest/shared/mock_state_view.d.ts.map +1 -0
- package/dest/shared/mock_state_view.js +186 -0
- package/dest/shared/submit-transactions.d.ts +2 -2
- package/dest/shared/submit-transactions.d.ts.map +1 -1
- package/dest/shared/submit-transactions.js +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 +57 -40
- 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 +26 -14
- package/dest/simulators/token_simulator.d.ts +1 -1
- package/dest/simulators/token_simulator.d.ts.map +1 -1
- package/dest/simulators/token_simulator.js +3 -24
- package/dest/spartan/setup_test_wallets.d.ts +12 -3
- package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
- package/dest/spartan/setup_test_wallets.js +108 -41
- 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/bot.d.ts +3 -2
- package/dest/spartan/utils/bot.d.ts.map +1 -1
- package/dest/spartan/utils/bot.js +2 -1
- package/dest/spartan/utils/config.d.ts +11 -28
- package/dest/spartan/utils/config.d.ts.map +1 -1
- package/dest/spartan/utils/config.js +4 -1
- package/dest/spartan/utils/index.d.ts +5 -3
- package/dest/spartan/utils/index.d.ts.map +1 -1
- package/dest/spartan/utils/index.js +5 -1
- package/dest/spartan/utils/k8s.d.ts +3 -1
- package/dest/spartan/utils/k8s.d.ts.map +1 -1
- package/dest/spartan/utils/k8s.js +6 -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/spartan/utils/scripts.d.ts +18 -4
- package/dest/spartan/utils/scripts.d.ts.map +1 -1
- package/dest/spartan/utils/scripts.js +19 -4
- package/dest/test-wallet/test_wallet.d.ts +85 -0
- package/dest/test-wallet/test_wallet.d.ts.map +1 -0
- package/dest/test-wallet/test_wallet.js +273 -0
- package/dest/test-wallet/utils.d.ts +41 -0
- package/dest/test-wallet/utils.d.ts.map +1 -0
- package/dest/test-wallet/utils.js +66 -0
- package/dest/test-wallet/wallet_worker_script.d.ts +2 -0
- package/dest/test-wallet/wallet_worker_script.d.ts.map +1 -0
- package/dest/test-wallet/wallet_worker_script.js +53 -0
- package/dest/test-wallet/worker_wallet.d.ts +53 -0
- package/dest/test-wallet/worker_wallet.d.ts.map +1 -0
- package/dest/test-wallet/worker_wallet.js +155 -0
- package/dest/test-wallet/worker_wallet_schema.d.ts +160 -0
- package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -0
- package/dest/test-wallet/worker_wallet_schema.js +22 -0
- package/package.json +52 -45
- package/src/bench/client_flows/benchmark.ts +19 -0
- package/src/bench/client_flows/client_flows_benchmark.ts +64 -49
- package/src/bench/client_flows/config.ts +9 -1
- package/src/bench/utils.ts +10 -4
- package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +52 -25
- package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +56 -19
- package/src/e2e_deploy_contract/deploy_test.ts +6 -5
- package/src/e2e_epochs/epochs_test.ts +166 -68
- package/src/e2e_fees/bridging_race.notest.ts +1 -1
- package/src/e2e_fees/fees_test.ts +57 -32
- package/src/e2e_nested_contract/nested_contract_test.ts +10 -6
- package/src/e2e_p2p/inactivity_slash_test.ts +8 -7
- package/src/e2e_p2p/p2p_network.ts +93 -49
- package/src/e2e_p2p/reqresp/utils.ts +84 -17
- package/src/e2e_p2p/shared.ts +109 -65
- package/src/e2e_storage_proof/fixtures/storage_proof.json +915 -0
- package/src/e2e_storage_proof/fixtures/storage_proof_fetcher.ts +190 -0
- package/src/e2e_storage_proof/fixtures/storage_proof_fixture.ts +173 -0
- package/src/e2e_token_contract/token_contract_test.ts +38 -11
- package/src/fixtures/authwit_proxy.ts +54 -0
- package/src/fixtures/dumps/epoch_proof_result.json +1 -1
- package/src/fixtures/e2e_prover_test.ts +49 -56
- package/src/fixtures/elu_monitor.ts +126 -0
- package/src/fixtures/fixtures.ts +93 -0
- package/src/fixtures/get_bb_config.ts +7 -6
- package/src/fixtures/ha_setup.ts +188 -0
- package/src/fixtures/index.ts +1 -0
- package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
- package/src/fixtures/setup.ts +272 -233
- package/src/fixtures/setup_p2p_test.ts +37 -32
- package/src/fixtures/token_utils.ts +3 -3
- 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 +3 -5
- package/src/install_legacy_contracts.cjs +75 -0
- package/src/legacy-jest-resolver.cjs +112 -0
- package/src/shared/cross_chain_test_harness.ts +27 -13
- package/src/shared/gas_portal_test_harness.ts +21 -11
- package/src/shared/index.ts +1 -0
- package/src/shared/jest_setup.ts +51 -1
- package/src/shared/mock_state_view.ts +188 -0
- package/src/shared/submit-transactions.ts +3 -2
- package/src/shared/uniswap_l1_l2.ts +103 -54
- package/src/shared/wait_for_l1_to_l2_message.ts +23 -0
- package/src/simulators/lending_simulator.ts +32 -14
- package/src/simulators/token_simulator.ts +6 -30
- package/src/spartan/setup_test_wallets.ts +146 -35
- package/src/spartan/tx_metrics.ts +82 -24
- package/src/spartan/utils/bot.ts +4 -1
- package/src/spartan/utils/config.ts +3 -0
- package/src/spartan/utils/index.ts +8 -1
- package/src/spartan/utils/k8s.ts +8 -0
- package/src/spartan/utils/nodes.ts +17 -12
- package/src/spartan/utils/pod_logs.ts +99 -0
- package/src/spartan/utils/scripts.ts +43 -7
- package/src/test-wallet/test_wallet.ts +376 -0
- package/src/test-wallet/utils.ts +108 -0
- package/src/test-wallet/wallet_worker_script.ts +63 -0
- package/src/test-wallet/worker_wallet.ts +218 -0
- package/src/test-wallet/worker_wallet_schema.ts +13 -0
|
@@ -4,7 +4,7 @@ import { waitForProven } from '@aztec/aztec.js/contracts';
|
|
|
4
4
|
import { type Logger, createLogger } from '@aztec/aztec.js/log';
|
|
5
5
|
import type { AztecNode } from '@aztec/aztec.js/node';
|
|
6
6
|
import type { TxReceipt } from '@aztec/aztec.js/tx';
|
|
7
|
-
import { CheatCodes } from '@aztec/aztec/testing';
|
|
7
|
+
import { CheatCodes, EpochTestSettler } from '@aztec/aztec/testing';
|
|
8
8
|
import { createExtendedL1Client } from '@aztec/ethereum/client';
|
|
9
9
|
import { InboxContract, OutboxContract, RollupContract } from '@aztec/ethereum/contracts';
|
|
10
10
|
import type {
|
|
@@ -12,30 +12,34 @@ import type {
|
|
|
12
12
|
DeployAztecL1ContractsReturnType,
|
|
13
13
|
} from '@aztec/ethereum/deploy-aztec-l1-contracts';
|
|
14
14
|
import { deployL1Contract } from '@aztec/ethereum/deploy-l1-contract';
|
|
15
|
+
import { pickL1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
15
16
|
import type { ExtendedViemWalletClient } from '@aztec/ethereum/types';
|
|
16
|
-
import {
|
|
17
|
+
import { EpochNumber } from '@aztec/foundation/branded-types';
|
|
17
18
|
import { sleep } from '@aztec/foundation/sleep';
|
|
18
19
|
import { TestERC20Abi, TestERC20Bytecode } from '@aztec/l1-artifacts';
|
|
19
20
|
import { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
20
21
|
import { TokenBridgeContract } from '@aztec/noir-contracts.js/TokenBridge';
|
|
22
|
+
import type { PXEConfig } from '@aztec/pxe/server';
|
|
21
23
|
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
22
|
-
import type { TestWallet } from '@aztec/test-wallet/server';
|
|
23
24
|
|
|
24
25
|
import { MNEMONIC } from '../fixtures/fixtures.js';
|
|
25
26
|
import {
|
|
26
27
|
type EndToEndContext,
|
|
27
28
|
type SetupOptions,
|
|
28
29
|
deployAccounts,
|
|
30
|
+
ensureAuthRegistryPublished,
|
|
29
31
|
publicDeployAccounts,
|
|
30
32
|
setup,
|
|
31
33
|
teardown,
|
|
32
34
|
} from '../fixtures/setup.js';
|
|
33
35
|
import { CrossChainTestHarness } from '../shared/cross_chain_test_harness.js';
|
|
36
|
+
import type { TestWallet } from '../test-wallet/test_wallet.js';
|
|
34
37
|
|
|
35
38
|
export class CrossChainMessagingTest {
|
|
36
39
|
private requireEpochProven: boolean;
|
|
37
40
|
private setupOptions: SetupOptions;
|
|
38
41
|
private deployL1ContractsArgs: Partial<DeployAztecL1ContractsArgs>;
|
|
42
|
+
private pxeOpts: Partial<PXEConfig>;
|
|
39
43
|
logger: Logger;
|
|
40
44
|
context!: EndToEndContext;
|
|
41
45
|
aztecNode!: AztecNode;
|
|
@@ -58,12 +62,23 @@ export class CrossChainMessagingTest {
|
|
|
58
62
|
outbox!: OutboxContract;
|
|
59
63
|
cheatCodes!: CheatCodes;
|
|
60
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Background loop that marks each completed epoch as proven on L1. Started in `applyBaseSetup`
|
|
67
|
+
* when the test runs without a real prover node, because the e2e fixture uses L1 interval mining
|
|
68
|
+
* and the AnvilTestWatcher's auto-prove loop only runs under L1 automine. Without this, L1's
|
|
69
|
+
* `aztecProofSubmissionEpochs` window expires mid-test and triggers a chain prune that drops
|
|
70
|
+
* in-flight wallet txs. Tests that intentionally pause proving (e.g. inbox drift tests) can
|
|
71
|
+
* stop it via `await t.epochTestSettler?.stop()`.
|
|
72
|
+
*/
|
|
73
|
+
epochTestSettler?: EpochTestSettler;
|
|
74
|
+
|
|
61
75
|
deployL1ContractsValues!: DeployAztecL1ContractsReturnType;
|
|
62
76
|
|
|
63
77
|
constructor(
|
|
64
78
|
testName: string,
|
|
65
79
|
opts: SetupOptions = {},
|
|
66
80
|
deployL1ContractsArgs: Partial<DeployAztecL1ContractsArgs> = {},
|
|
81
|
+
pxeOpts: Partial<PXEConfig> = {},
|
|
67
82
|
) {
|
|
68
83
|
this.logger = createLogger(`e2e:e2e_cross_chain_messaging:${testName}`);
|
|
69
84
|
this.setupOptions = opts;
|
|
@@ -71,24 +86,31 @@ export class CrossChainMessagingTest {
|
|
|
71
86
|
initialValidators: [],
|
|
72
87
|
...deployL1ContractsArgs,
|
|
73
88
|
};
|
|
89
|
+
this.pxeOpts = pxeOpts;
|
|
74
90
|
this.requireEpochProven = opts.startProverNode ?? false;
|
|
75
91
|
}
|
|
76
92
|
|
|
77
|
-
async setup() {
|
|
93
|
+
async setup(opts: Partial<SetupOptions> = {}, pxeOpts: Partial<PXEConfig> = {}) {
|
|
78
94
|
this.logger.info('Setting up cross chain messaging test');
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
95
|
+
// Recompute requireEpochProven from the merged options so per-call startProverNode is honored.
|
|
96
|
+
this.requireEpochProven = opts.startProverNode ?? this.setupOptions.startProverNode ?? false;
|
|
97
|
+
this.context = await setup(
|
|
98
|
+
0,
|
|
99
|
+
{
|
|
100
|
+
...this.setupOptions,
|
|
101
|
+
...opts,
|
|
102
|
+
fundSponsoredFPC: true,
|
|
103
|
+
skipAccountDeployment: true,
|
|
104
|
+
l1ContractsArgs: { ...this.deployL1ContractsArgs, ...opts.l1ContractsArgs },
|
|
105
|
+
},
|
|
106
|
+
{ ...this.pxeOpts, ...pxeOpts },
|
|
107
|
+
);
|
|
85
108
|
await this.applyBaseSetup();
|
|
86
109
|
}
|
|
87
110
|
|
|
88
111
|
async advanceToEpochProven(l2TxReceipt: TxReceipt): Promise<EpochNumber> {
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
);
|
|
112
|
+
const block = await this.aztecNode.getBlock(l2TxReceipt.blockNumber!);
|
|
113
|
+
const epoch = await this.rollup.getEpochNumberForCheckpoint(block!.checkpointNumber);
|
|
92
114
|
// Warp to the next epoch.
|
|
93
115
|
await this.cheatCodes.rollup.advanceToEpoch(EpochNumber(epoch + 1));
|
|
94
116
|
// Wait for the tx to be proven.
|
|
@@ -99,27 +121,41 @@ export class CrossChainMessagingTest {
|
|
|
99
121
|
|
|
100
122
|
async catchUpProvenChain() {
|
|
101
123
|
const bn = await this.aztecNode.getBlockNumber();
|
|
102
|
-
while ((await this.aztecNode.
|
|
124
|
+
while ((await this.aztecNode.getBlockNumber('proven')) < bn) {
|
|
103
125
|
await sleep(1000);
|
|
104
126
|
}
|
|
105
127
|
}
|
|
106
128
|
|
|
107
129
|
async teardown() {
|
|
130
|
+
await this.epochTestSettler?.stop();
|
|
108
131
|
await teardown(this.context);
|
|
109
132
|
}
|
|
110
133
|
|
|
111
134
|
async applyBaseSetup() {
|
|
112
135
|
// Set up base context fields
|
|
113
|
-
this.aztecNode = this.context.aztecNodeService
|
|
136
|
+
this.aztecNode = this.context.aztecNodeService;
|
|
114
137
|
this.wallet = this.context.wallet;
|
|
115
138
|
this.aztecNodeConfig = this.context.config;
|
|
116
139
|
this.cheatCodes = this.context.cheatCodes;
|
|
117
140
|
this.deployL1ContractsValues = this.context.deployL1ContractsValues;
|
|
118
|
-
this.aztecNodeAdmin = this.context.aztecNodeService
|
|
141
|
+
this.aztecNodeAdmin = this.context.aztecNodeService;
|
|
119
142
|
|
|
120
143
|
if (this.requireEpochProven) {
|
|
121
144
|
// Turn off the watcher to prevent it from keep marking blocks as proven.
|
|
122
|
-
this.context.watcher
|
|
145
|
+
this.context.watcher.setIsMarkingAsProven(false);
|
|
146
|
+
} else {
|
|
147
|
+
// When no real prover is running, the L1 proof window (aztecProofSubmissionEpochs) would
|
|
148
|
+
// otherwise expire mid-test and trigger a chain prune. The AnvilTestWatcher's auto-prove
|
|
149
|
+
// loop is dormant under L1 interval mining (it gates on `isAutoMining`), so start an
|
|
150
|
+
// EpochTestSettler to mark each completed epoch as proven on L1.
|
|
151
|
+
this.epochTestSettler = new EpochTestSettler(
|
|
152
|
+
this.context.ethCheatCodes,
|
|
153
|
+
this.context.deployL1ContractsValues.l1ContractAddresses.rollupAddress,
|
|
154
|
+
this.context.aztecNodeService.getBlockSource(),
|
|
155
|
+
this.logger.createChild('epoch-settler'),
|
|
156
|
+
{ pollingIntervalMs: 500 },
|
|
157
|
+
);
|
|
158
|
+
await this.epochTestSettler.start();
|
|
123
159
|
}
|
|
124
160
|
|
|
125
161
|
// Deploy 3 accounts
|
|
@@ -136,6 +172,7 @@ export class CrossChainMessagingTest {
|
|
|
136
172
|
// Set up cross chain messaging
|
|
137
173
|
this.logger.info('Applying e2e_cross_chain_messaging setup');
|
|
138
174
|
|
|
175
|
+
await ensureAuthRegistryPublished(this.wallet, this.ownerAddress);
|
|
139
176
|
// Create the token contract state.
|
|
140
177
|
this.logger.verbose(`Public deploy accounts...`);
|
|
141
178
|
await publicDeployAccounts(this.wallet, [this.ownerAddress, this.user1Address, this.user2Address]);
|
|
@@ -172,7 +209,7 @@ export class CrossChainMessagingTest {
|
|
|
172
209
|
const l1Client = createExtendedL1Client(this.aztecNodeConfig.l1RpcUrls, MNEMONIC);
|
|
173
210
|
this.l1Client = l1Client;
|
|
174
211
|
|
|
175
|
-
const l1Contracts = this.aztecNodeConfig
|
|
212
|
+
const l1Contracts = pickL1ContractAddresses(this.aztecNodeConfig);
|
|
176
213
|
this.rollup = new RollupContract(l1Client, l1Contracts.rollupAddress.toString());
|
|
177
214
|
this.inbox = new InboxContract(l1Client, l1Contracts.inboxAddress.toString());
|
|
178
215
|
this.outbox = new OutboxContract(l1Client, l1Contracts.outboxAddress.toString());
|
|
@@ -186,7 +223,7 @@ export class CrossChainMessagingTest {
|
|
|
186
223
|
tokenPortalAddress,
|
|
187
224
|
crossChainContext.underlying,
|
|
188
225
|
l1Client,
|
|
189
|
-
this.aztecNodeConfig
|
|
226
|
+
pickL1ContractAddresses(this.aztecNodeConfig),
|
|
190
227
|
this.wallet,
|
|
191
228
|
this.ownerAddress,
|
|
192
229
|
);
|
|
@@ -8,9 +8,9 @@ import type { AztecNode } from '@aztec/aztec.js/node';
|
|
|
8
8
|
import type { Wallet } from '@aztec/aztec.js/wallet';
|
|
9
9
|
import type { StatefulTestContract } from '@aztec/noir-test-contracts.js/StatefulTest';
|
|
10
10
|
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
11
|
-
import type { TestWallet } from '@aztec/test-wallet/server';
|
|
12
11
|
|
|
13
|
-
import { type EndToEndContext, deployAccounts, setup, teardown } from '../fixtures/setup.js';
|
|
12
|
+
import { type EndToEndContext, type SetupOptions, deployAccounts, setup, teardown } from '../fixtures/setup.js';
|
|
13
|
+
import type { TestWallet } from '../test-wallet/test_wallet.js';
|
|
14
14
|
|
|
15
15
|
export class DeployTest {
|
|
16
16
|
public context!: EndToEndContext;
|
|
@@ -24,15 +24,16 @@ export class DeployTest {
|
|
|
24
24
|
this.logger = createLogger(`e2e:e2e_deploy_contract:${testName}`);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
async setup() {
|
|
27
|
+
async setup(opts: Partial<SetupOptions> = {}) {
|
|
28
28
|
this.logger.info('Setting up test environment');
|
|
29
29
|
this.context = await setup(0, {
|
|
30
|
+
...opts,
|
|
30
31
|
fundSponsoredFPC: true,
|
|
31
32
|
skipAccountDeployment: true,
|
|
32
33
|
});
|
|
33
|
-
this.aztecNode = this.context.aztecNodeService
|
|
34
|
+
this.aztecNode = this.context.aztecNodeService;
|
|
34
35
|
this.wallet = this.context.wallet;
|
|
35
|
-
this.aztecNodeAdmin = this.context.aztecNodeService
|
|
36
|
+
this.aztecNodeAdmin = this.context.aztecNodeService;
|
|
36
37
|
await this.applyInitialAccount();
|
|
37
38
|
return this;
|
|
38
39
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import type { InitialAccountData } from '@aztec/accounts/testing';
|
|
2
|
+
import type { Archiver } from '@aztec/archiver';
|
|
1
3
|
import { type AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
|
|
4
|
+
import { getAccountContractAddress } from '@aztec/aztec.js/account';
|
|
2
5
|
import { getTimestampRangeForEpoch } from '@aztec/aztec.js/block';
|
|
3
6
|
import { getContractInstanceFromInstantiationParams } from '@aztec/aztec.js/contracts';
|
|
4
7
|
import { Fr } from '@aztec/aztec.js/fields';
|
|
@@ -9,7 +12,8 @@ import { EpochCache } from '@aztec/epoch-cache';
|
|
|
9
12
|
import { createExtendedL1Client } from '@aztec/ethereum/client';
|
|
10
13
|
import { DefaultL1ContractsConfig } from '@aztec/ethereum/config';
|
|
11
14
|
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
12
|
-
import {
|
|
15
|
+
import { Delayer, createDelayer, waitUntilL1Timestamp, wrapClientWithDelayer } from '@aztec/ethereum/l1-tx-utils';
|
|
16
|
+
import { ChainMonitor } from '@aztec/ethereum/test';
|
|
13
17
|
import type { ExtendedViemWalletClient } from '@aztec/ethereum/types';
|
|
14
18
|
import { BlockNumber, CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
|
|
15
19
|
import { SecretValue } from '@aztec/foundation/config';
|
|
@@ -20,24 +24,22 @@ import { sleep } from '@aztec/foundation/sleep';
|
|
|
20
24
|
import { SpamContract } from '@aztec/noir-test-contracts.js/Spam';
|
|
21
25
|
import { TestContract } from '@aztec/noir-test-contracts.js/Test';
|
|
22
26
|
import { getMockPubSubP2PServiceFactory } from '@aztec/p2p/test-helpers';
|
|
23
|
-
import {
|
|
24
|
-
import type { TestProverNode } from '@aztec/prover-node/test';
|
|
27
|
+
import type { ProverNodeConfig } from '@aztec/prover-node';
|
|
25
28
|
import type { PXEConfig } from '@aztec/pxe/config';
|
|
26
|
-
import {
|
|
27
|
-
type SequencerClient,
|
|
28
|
-
type SequencerEvents,
|
|
29
|
-
type SequencerPublisher,
|
|
30
|
-
SequencerState,
|
|
31
|
-
} from '@aztec/sequencer-client';
|
|
32
|
-
import type { TestSequencerClient } from '@aztec/sequencer-client/test';
|
|
29
|
+
import { type SequencerClient, type SequencerEvents, SequencerState } from '@aztec/sequencer-client';
|
|
33
30
|
import { type BlockParameter, EthAddress } from '@aztec/stdlib/block';
|
|
34
31
|
import { type L1RollupConstants, getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
35
32
|
import { tryStop } from '@aztec/stdlib/interfaces/server';
|
|
33
|
+
import type { SlashingProtectionDatabase } from '@aztec/validator-ha-signer/types';
|
|
36
34
|
|
|
37
35
|
import { join } from 'path';
|
|
38
36
|
import type { Hex } from 'viem';
|
|
39
37
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
40
38
|
|
|
39
|
+
import {
|
|
40
|
+
SCHNORR_HARDCODED_PRIVATE_KEY,
|
|
41
|
+
SchnorrHardcodedKeyAccountContract,
|
|
42
|
+
} from '../fixtures/schnorr_hardcoded_account_contract.js';
|
|
41
43
|
import {
|
|
42
44
|
type EndToEndContext,
|
|
43
45
|
type SetupOptions,
|
|
@@ -45,8 +47,9 @@ import {
|
|
|
45
47
|
getPrivateKeyFromIndex,
|
|
46
48
|
setup,
|
|
47
49
|
} from '../fixtures/utils.js';
|
|
50
|
+
import type { TestWallet } from '../test-wallet/test_wallet.js';
|
|
48
51
|
|
|
49
|
-
export const
|
|
52
|
+
export const WORLD_STATE_CHECKPOINT_HISTORY = 2;
|
|
50
53
|
export const WORLD_STATE_BLOCK_CHECK_INTERVAL = 50;
|
|
51
54
|
export const ARCHIVER_POLL_INTERVAL = 50;
|
|
52
55
|
export const DEFAULT_L1_BLOCK_TIME = process.env.CI ? 12 : 8;
|
|
@@ -55,6 +58,13 @@ export type EpochsTestOpts = Partial<SetupOptions> & {
|
|
|
55
58
|
numberOfAccounts?: number;
|
|
56
59
|
pxeOpts?: Partial<PXEConfig>;
|
|
57
60
|
aztecSlotDurationInL1Slots?: number;
|
|
61
|
+
/** Skip creating/registering the hardcoded account during setup (for tests that handle accounts themselves). */
|
|
62
|
+
skipHardcodedAccount?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Force the hardcoded-account fast-path even when an initial sequencer is running. Useful for
|
|
65
|
+
* tests with tight per-block gas budgets that can't fit a full account-deploy tx.
|
|
66
|
+
*/
|
|
67
|
+
useHardcodedAccount?: boolean;
|
|
58
68
|
};
|
|
59
69
|
|
|
60
70
|
export type TrackedSequencerEvent = {
|
|
@@ -81,7 +91,7 @@ export class EpochsTestContext {
|
|
|
81
91
|
public proverDelayer!: Delayer;
|
|
82
92
|
public sequencerDelayer!: Delayer;
|
|
83
93
|
|
|
84
|
-
public proverNodes:
|
|
94
|
+
public proverNodes: AztecNodeService[] = [];
|
|
85
95
|
public nodes: AztecNodeService[] = [];
|
|
86
96
|
|
|
87
97
|
public epochDuration!: number;
|
|
@@ -125,10 +135,20 @@ export class EpochsTestContext {
|
|
|
125
135
|
this.L1_BLOCK_TIME_IN_S = ethereumSlotDuration;
|
|
126
136
|
this.L2_SLOT_DURATION_IN_S = aztecSlotDuration;
|
|
127
137
|
|
|
138
|
+
// Auto-create a hardcoded account funded via genesis when:
|
|
139
|
+
// - skipInitialSequencer is set (no sequencer to deploy on-chain), or
|
|
140
|
+
// - useHardcodedAccount is explicitly requested (e.g. tight per-block gas budgets that
|
|
141
|
+
// can't fit a full account-deploy tx).
|
|
142
|
+
const useHardcodedAccount = (opts.skipInitialSequencer || opts.useHardcodedAccount) && !opts.skipHardcodedAccount;
|
|
143
|
+
let hardcodedAccountData: InitialAccountData | undefined;
|
|
144
|
+
if (useHardcodedAccount) {
|
|
145
|
+
hardcodedAccountData = await EpochsTestContext.getHardcodedAccountData(Fr.random(), Fr.random());
|
|
146
|
+
}
|
|
147
|
+
|
|
128
148
|
// Set up system without any account nor protocol contracts
|
|
129
149
|
// and with faster block times and shorter epochs.
|
|
130
150
|
const context = await setup(
|
|
131
|
-
opts.numberOfAccounts ?? 0,
|
|
151
|
+
useHardcodedAccount ? 0 : (opts.numberOfAccounts ?? 0),
|
|
132
152
|
{
|
|
133
153
|
automineL1Setup: true,
|
|
134
154
|
checkIntervalMs: 50,
|
|
@@ -143,15 +163,13 @@ export class EpochsTestContext {
|
|
|
143
163
|
realProofs: false,
|
|
144
164
|
startProverNode: true,
|
|
145
165
|
proverTestDelayMs: opts.proverTestDelayMs ?? 0,
|
|
146
|
-
// We use numeric incremental prover ids for simplicity, but we can switch to
|
|
147
|
-
// using the prover's eth address if the proverId is used for something in the rollup contract
|
|
148
|
-
// Use numeric EthAddress for deterministic prover id
|
|
149
166
|
proverId: EthAddress.fromNumber(1),
|
|
150
|
-
|
|
167
|
+
worldStateCheckpointHistory: WORLD_STATE_CHECKPOINT_HISTORY,
|
|
151
168
|
exitDelaySeconds: DefaultL1ContractsConfig.exitDelaySeconds,
|
|
152
|
-
|
|
169
|
+
slasherEnabled: false,
|
|
153
170
|
l1PublishingTime,
|
|
154
171
|
...opts,
|
|
172
|
+
...(hardcodedAccountData ? { initialFundedAccounts: [hardcodedAccountData], numberOfAccounts: 0 } : {}),
|
|
155
173
|
},
|
|
156
174
|
// Use checkpointed chain tip for PXE by default to avoid issues with blocks being dropped due to pruned anchor blocks.
|
|
157
175
|
// Can be overridden via opts.pxeOpts.
|
|
@@ -159,6 +177,11 @@ export class EpochsTestContext {
|
|
|
159
177
|
);
|
|
160
178
|
|
|
161
179
|
this.context = context;
|
|
180
|
+
|
|
181
|
+
// Register the hardcoded account in PXE (local only, no on-chain deployment needed).
|
|
182
|
+
if (hardcodedAccountData) {
|
|
183
|
+
await this.registerHardcodedAccount(hardcodedAccountData);
|
|
184
|
+
}
|
|
162
185
|
this.proverNodes = context.proverNode ? [context.proverNode] : [];
|
|
163
186
|
this.nodes = context.aztecNode ? [context.aztecNode as AztecNodeService] : [];
|
|
164
187
|
this.logger = context.logger;
|
|
@@ -169,17 +192,8 @@ export class EpochsTestContext {
|
|
|
169
192
|
// Loop that tracks L1 and L2 block numbers and logs whenever there's a new one.
|
|
170
193
|
this.monitor = new ChainMonitor(this.rollup, context.dateProvider, this.logger).start();
|
|
171
194
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
this.proverDelayer = context.proverNode
|
|
175
|
-
? (((context.proverNode as TestProverNode).publisher as ProverNodePublisher).l1TxUtils as DelayedTxUtils).delayer!
|
|
176
|
-
: undefined!;
|
|
177
|
-
this.sequencerDelayer = context.sequencer
|
|
178
|
-
? (
|
|
179
|
-
((context.sequencer as TestSequencerClient).sequencer.publisher as SequencerPublisher)
|
|
180
|
-
.l1TxUtils as DelayedTxUtils
|
|
181
|
-
).delayer!
|
|
182
|
-
: undefined!;
|
|
195
|
+
this.proverDelayer = context.proverDelayer!;
|
|
196
|
+
this.sequencerDelayer = context.sequencerDelayer!;
|
|
183
197
|
|
|
184
198
|
if ((context.proverNode && !this.proverDelayer) || (context.sequencer && !this.sequencerDelayer)) {
|
|
185
199
|
throw new Error(`Could not find prover or sequencer delayer`);
|
|
@@ -194,6 +208,8 @@ export class EpochsTestContext {
|
|
|
194
208
|
l1GenesisTime: await this.rollup.getL1GenesisTime(),
|
|
195
209
|
ethereumSlotDuration,
|
|
196
210
|
proofSubmissionEpochs: Number(await this.rollup.getProofSubmissionEpochs()),
|
|
211
|
+
targetCommitteeSize: await this.rollup.getTargetCommitteeSize(),
|
|
212
|
+
rollupManaLimit: Number(await this.rollup.getManaLimit()),
|
|
197
213
|
};
|
|
198
214
|
|
|
199
215
|
this.logger.info(
|
|
@@ -208,23 +224,64 @@ export class EpochsTestContext {
|
|
|
208
224
|
await this.context.teardown();
|
|
209
225
|
}
|
|
210
226
|
|
|
227
|
+
/**
|
|
228
|
+
* Computes InitialAccountData for a SchnorrHardcodedKeyAccountContract.
|
|
229
|
+
* This contract has a hardcoded signing key and no initializer, so it can be used without
|
|
230
|
+
* on-chain deployment. Pass the returned data in `initialFundedAccounts` so the address
|
|
231
|
+
* gets funded with fee juice in genesis.
|
|
232
|
+
*/
|
|
233
|
+
public static async getHardcodedAccountData(secret: Fr, salt: Fr): Promise<InitialAccountData> {
|
|
234
|
+
const contract = new SchnorrHardcodedKeyAccountContract();
|
|
235
|
+
const address = await getAccountContractAddress(contract, secret, salt);
|
|
236
|
+
const signingKey = SCHNORR_HARDCODED_PRIVATE_KEY;
|
|
237
|
+
return { secret, salt, signingKey, address };
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Registers a SchnorrHardcodedKeyAccountContract in PXE. The account must have been funded
|
|
242
|
+
* at genesis (via getHardcodedAccountData). No on-chain deployment or block mining needed.
|
|
243
|
+
*/
|
|
244
|
+
public async registerHardcodedAccount(accountData: InitialAccountData) {
|
|
245
|
+
const contract = new SchnorrHardcodedKeyAccountContract();
|
|
246
|
+
const wallet = this.context.wallet;
|
|
247
|
+
const accountManager = await (wallet as TestWallet).createAccount({
|
|
248
|
+
secret: accountData.secret,
|
|
249
|
+
salt: accountData.salt,
|
|
250
|
+
contract,
|
|
251
|
+
});
|
|
252
|
+
this.context.accounts = [accountManager.address];
|
|
253
|
+
return accountManager.address;
|
|
254
|
+
}
|
|
255
|
+
|
|
211
256
|
public async createProverNode(opts: { dontStart?: boolean } & Partial<ProverNodeConfig> = {}) {
|
|
212
257
|
this.logger.warn('Creating and syncing a simulated prover node...');
|
|
213
258
|
const proverNodePrivateKey = this.getNextPrivateKey();
|
|
214
259
|
const proverIndex = this.proverNodes.length + 1;
|
|
215
|
-
const
|
|
260
|
+
const { mockGossipSubNetwork } = this.context;
|
|
261
|
+
const { proverNode } = await withLoggerBindings({ actor: `prover-${proverIndex}` }, () =>
|
|
216
262
|
createAndSyncProverNode(
|
|
217
263
|
proverNodePrivateKey,
|
|
218
|
-
{ ...this.context.config },
|
|
219
264
|
{
|
|
220
|
-
|
|
265
|
+
...this.context.config,
|
|
266
|
+
p2pEnabled: this.context.config.p2pEnabled || mockGossipSubNetwork !== undefined,
|
|
221
267
|
proverId: EthAddress.fromNumber(proverIndex),
|
|
222
268
|
dontStart: opts.dontStart,
|
|
223
269
|
...opts,
|
|
224
270
|
},
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
271
|
+
{
|
|
272
|
+
dataDirectory: join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')),
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
dateProvider: this.context.dateProvider,
|
|
276
|
+
p2pClientDeps: {
|
|
277
|
+
p2pServiceFactory: mockGossipSubNetwork ? getMockPubSubP2PServiceFactory(mockGossipSubNetwork) : undefined,
|
|
278
|
+
rpcTxProviders: [this.context.aztecNode],
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
genesis: this.context.genesis,
|
|
283
|
+
dontStart: opts.dontStart,
|
|
284
|
+
},
|
|
228
285
|
),
|
|
229
286
|
);
|
|
230
287
|
this.proverNodes.push(proverNode);
|
|
@@ -238,14 +295,20 @@ export class EpochsTestContext {
|
|
|
238
295
|
|
|
239
296
|
public createValidatorNode(
|
|
240
297
|
privateKeys: `0x${string}`[],
|
|
241
|
-
opts: Partial<AztecNodeConfig> & {
|
|
298
|
+
opts: Partial<AztecNodeConfig> & {
|
|
299
|
+
dontStartSequencer?: boolean;
|
|
300
|
+
slashingProtectionDb?: SlashingProtectionDatabase;
|
|
301
|
+
} = {},
|
|
242
302
|
) {
|
|
243
303
|
this.logger.warn('Creating and syncing a validator node...');
|
|
244
304
|
return this.createNode({ ...opts, disableValidator: false, validatorPrivateKeys: new SecretValue(privateKeys) });
|
|
245
305
|
}
|
|
246
306
|
|
|
247
307
|
private async createNode(
|
|
248
|
-
opts: Partial<AztecNodeConfig> & {
|
|
308
|
+
opts: Partial<AztecNodeConfig> & {
|
|
309
|
+
dontStartSequencer?: boolean;
|
|
310
|
+
slashingProtectionDb?: SlashingProtectionDatabase;
|
|
311
|
+
} = {},
|
|
249
312
|
) {
|
|
250
313
|
const nodeIndex = this.nodes.length + 1;
|
|
251
314
|
const actorPrefix = opts.disableValidator ? 'node' : 'validator';
|
|
@@ -259,6 +322,7 @@ export class EpochsTestContext {
|
|
|
259
322
|
...resolvedConfig,
|
|
260
323
|
dataDirectory: join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')),
|
|
261
324
|
validatorPrivateKeys: opts.validatorPrivateKeys ?? new SecretValue([]),
|
|
325
|
+
nodeId: resolvedConfig.nodeId || `${actorPrefix}-${nodeIndex}`,
|
|
262
326
|
p2pEnabled,
|
|
263
327
|
p2pIp,
|
|
264
328
|
},
|
|
@@ -267,34 +331,15 @@ export class EpochsTestContext {
|
|
|
267
331
|
p2pClientDeps: {
|
|
268
332
|
p2pServiceFactory: mockGossipSubNetwork ? getMockPubSubP2PServiceFactory(mockGossipSubNetwork) : undefined,
|
|
269
333
|
},
|
|
334
|
+
slashingProtectionDb: opts.slashingProtectionDb,
|
|
270
335
|
},
|
|
271
336
|
{
|
|
272
|
-
|
|
337
|
+
genesis: this.context.genesis,
|
|
273
338
|
...opts,
|
|
274
339
|
},
|
|
275
340
|
),
|
|
276
341
|
);
|
|
277
342
|
|
|
278
|
-
// REFACTOR: We're getting too much into the internals of the sequencer here.
|
|
279
|
-
// We should have a single method for constructing an aztec node that returns a TestAztecNodeService
|
|
280
|
-
// which directly exposes the delayer and sets any test config.
|
|
281
|
-
if (opts.txDelayerMaxInclusionTimeIntoSlot !== undefined) {
|
|
282
|
-
this.logger.info(
|
|
283
|
-
`Setting tx delayer max inclusion time into slot to ${opts.txDelayerMaxInclusionTimeIntoSlot} seconds`,
|
|
284
|
-
);
|
|
285
|
-
// Here we reach into the sequencer and hook in a tx delayer. The problem is that the sequencer's l1 utils only uses a public client, not a wallet.
|
|
286
|
-
// The delayer needs a wallet (a client that can sign), so we have to create one here.
|
|
287
|
-
const l1Client = createExtendedL1Client(
|
|
288
|
-
resolvedConfig.l1RpcUrls!,
|
|
289
|
-
resolvedConfig.publisherPrivateKeys![0]!.getValue(),
|
|
290
|
-
);
|
|
291
|
-
const sequencer = node.getSequencer() as TestSequencerClient;
|
|
292
|
-
const publisher = sequencer.sequencer.publisher;
|
|
293
|
-
const delayed = DelayedTxUtils.fromL1TxUtils(publisher.l1TxUtils, this.L1_BLOCK_TIME_IN_S, l1Client);
|
|
294
|
-
delayed.delayer!.setMaxInclusionTimeIntoSlot(opts.txDelayerMaxInclusionTimeIntoSlot);
|
|
295
|
-
publisher.l1TxUtils = delayed;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
343
|
this.nodes.push(node);
|
|
299
344
|
return node;
|
|
300
345
|
}
|
|
@@ -346,7 +391,10 @@ export class EpochsTestContext {
|
|
|
346
391
|
this.logger.info(`Waiting until last slot of submission window for epoch ${epochNumber} at ${date}`, {
|
|
347
392
|
oneSlotBefore,
|
|
348
393
|
});
|
|
349
|
-
|
|
394
|
+
// Use a timeout that accounts for the full proof submission window
|
|
395
|
+
const proofSubmissionWindowDuration =
|
|
396
|
+
this.constants.proofSubmissionEpochs * this.epochDuration * this.L2_SLOT_DURATION_IN_S;
|
|
397
|
+
await waitUntilL1Timestamp(this.l1Client, oneSlotBefore, undefined, proofSubmissionWindowDuration * 2);
|
|
350
398
|
}
|
|
351
399
|
|
|
352
400
|
/** Waits for the aztec node to sync to the target block number. */
|
|
@@ -357,7 +405,7 @@ export class EpochsTestContext {
|
|
|
357
405
|
await sleep(waitTime);
|
|
358
406
|
const [syncState, tips] = await Promise.all([
|
|
359
407
|
this.context.aztecNode.getWorldStateSyncStatus(),
|
|
360
|
-
await this.context.aztecNode.
|
|
408
|
+
await this.context.aztecNode.getChainTips(),
|
|
361
409
|
]);
|
|
362
410
|
this.logger.info(`Wait for node synch ${blockNumber} ${type}`, { blockNumber, type, syncState, tips });
|
|
363
411
|
if (type === 'proven') {
|
|
@@ -398,15 +446,13 @@ export class EpochsTestContext {
|
|
|
398
446
|
|
|
399
447
|
/** Creates an L1 client using a fresh account with funds from anvil, with a tx delayer already set up. */
|
|
400
448
|
public async createL1Client() {
|
|
401
|
-
const
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
this.l1Client.chain,
|
|
406
|
-
),
|
|
407
|
-
this.context.dateProvider!,
|
|
408
|
-
{ ethereumSlotDuration: this.L1_BLOCK_TIME_IN_S },
|
|
449
|
+
const rawClient = createExtendedL1Client(
|
|
450
|
+
[...this.l1Client.chain.rpcUrls.default.http],
|
|
451
|
+
privateKeyToAccount(this.getNextPrivateKey()),
|
|
452
|
+
this.l1Client.chain,
|
|
409
453
|
);
|
|
454
|
+
const delayer = createDelayer(this.context.dateProvider, { ethereumSlotDuration: this.L1_BLOCK_TIME_IN_S }, {});
|
|
455
|
+
const client = wrapClientWithDelayer(rawClient, delayer);
|
|
410
456
|
expect(await client.getBalance({ address: client.account.address })).toBeGreaterThan(0n);
|
|
411
457
|
return { client, delayer };
|
|
412
458
|
}
|
|
@@ -423,9 +469,42 @@ export class EpochsTestContext {
|
|
|
423
469
|
expect(result).toBe(expectedSuccess);
|
|
424
470
|
}
|
|
425
471
|
|
|
472
|
+
/** Verifies at least one checkpoint has the target number of blocks (for MBPS validation). */
|
|
473
|
+
public async assertMultipleBlocksPerSlot(targetBlockCount: number) {
|
|
474
|
+
const archiver = (this.context.aztecNode as AztecNodeService).getBlockSource() as Archiver;
|
|
475
|
+
const checkpoints = await archiver.getCheckpoints({ from: CheckpointNumber(1), limit: 50 });
|
|
476
|
+
|
|
477
|
+
this.logger.warn(`Retrieved ${checkpoints.length} checkpoints from archiver`, {
|
|
478
|
+
checkpoints: checkpoints.map(pc => pc.checkpoint.getStats()),
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
let expectedBlockNumber = checkpoints[0].checkpoint.blocks[0].number;
|
|
482
|
+
let targetFound = false;
|
|
483
|
+
|
|
484
|
+
for (const checkpoint of checkpoints) {
|
|
485
|
+
const blockCount = checkpoint.checkpoint.blocks.length;
|
|
486
|
+
targetFound = targetFound || blockCount >= targetBlockCount;
|
|
487
|
+
|
|
488
|
+
this.logger.verbose(`Checkpoint ${checkpoint.checkpoint.number} has ${blockCount} blocks`, {
|
|
489
|
+
checkpoint: checkpoint.checkpoint.getStats(),
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
for (let i = 0; i < blockCount; i++) {
|
|
493
|
+
const block = checkpoint.checkpoint.blocks[i];
|
|
494
|
+
expect(block.indexWithinCheckpoint).toBe(i);
|
|
495
|
+
expect(block.checkpointNumber).toBe(checkpoint.checkpoint.number);
|
|
496
|
+
expect(block.number).toBe(expectedBlockNumber);
|
|
497
|
+
expectedBlockNumber++;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
expect(targetFound).toBe(true);
|
|
502
|
+
}
|
|
503
|
+
|
|
426
504
|
public watchSequencerEvents(
|
|
427
505
|
sequencers: SequencerClient[],
|
|
428
506
|
getMetadata: (i: number) => Record<string, any> = () => ({}),
|
|
507
|
+
additionalFailEventKeys: (keyof SequencerEvents)[] = [],
|
|
429
508
|
) {
|
|
430
509
|
const stateChanges: TrackedSequencerEvent[] = [];
|
|
431
510
|
const failEvents: TrackedSequencerEvent[] = [];
|
|
@@ -436,6 +515,11 @@ export class EpochsTestContext {
|
|
|
436
515
|
'block-build-failed',
|
|
437
516
|
'checkpoint-publish-failed',
|
|
438
517
|
'proposer-rollup-check-failed',
|
|
518
|
+
'checkpoint-error',
|
|
519
|
+
'checkpoint-publish-failed',
|
|
520
|
+
'header-validation-failed',
|
|
521
|
+
'pipelined-checkpoint-discarded',
|
|
522
|
+
...additionalFailEventKeys,
|
|
439
523
|
];
|
|
440
524
|
|
|
441
525
|
const makeEvent = (
|
|
@@ -465,6 +549,13 @@ export class EpochsTestContext {
|
|
|
465
549
|
});
|
|
466
550
|
failEventsKeys.forEach(eventName => {
|
|
467
551
|
sequencer.getSequencer().on(eventName, (args: Parameters<SequencerEvents[typeof eventName]>[0]) => {
|
|
552
|
+
// Skip benign block-build-failed events where the builder rejected the block because it
|
|
553
|
+
// could not collect enough valid txs. This is the same "not enough txs" case as
|
|
554
|
+
// block-tx-count-check-failed (which is already excluded above), just detected after we
|
|
555
|
+
// started processing txs rather than before.
|
|
556
|
+
if (eventName === 'block-build-failed' && (args as { reason?: string }).reason === 'Insufficient valid txs') {
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
468
559
|
const evt = makeEvent(i, eventName, args);
|
|
469
560
|
failEvents.push(evt);
|
|
470
561
|
this.logger.error(`Failed event ${eventName} from sequencer ${sequencerIndex}`, undefined, evt);
|
|
@@ -474,4 +565,11 @@ export class EpochsTestContext {
|
|
|
474
565
|
|
|
475
566
|
return { failEvents, stateChanges };
|
|
476
567
|
}
|
|
568
|
+
|
|
569
|
+
public assertNoFailuresFromSequencers(failEvents: TrackedSequencerEvent[]) {
|
|
570
|
+
if (failEvents.length > 0) {
|
|
571
|
+
this.logger.error(`Failed events from sequencers`, failEvents);
|
|
572
|
+
}
|
|
573
|
+
expect(failEvents).toEqual([]);
|
|
574
|
+
}
|
|
477
575
|
}
|
|
@@ -4,11 +4,11 @@ import type { Logger } from '@aztec/aztec.js/log';
|
|
|
4
4
|
import { Fq } from '@aztec/foundation/curves/bn254';
|
|
5
5
|
import { sleep } from '@aztec/foundation/sleep';
|
|
6
6
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
7
|
-
import type { TestWallet } from '@aztec/test-wallet/server';
|
|
8
7
|
|
|
9
8
|
import { jest } from '@jest/globals';
|
|
10
9
|
import type { Hex } from 'viem';
|
|
11
10
|
|
|
11
|
+
import type { TestWallet } from '../test-wallet/test_wallet.js';
|
|
12
12
|
import { FeesTest } from './fees_test.js';
|
|
13
13
|
|
|
14
14
|
jest.setTimeout(300_000);
|