@aztec/end-to-end 0.0.1-commit.4d3c002 → 0.0.1-commit.4d9804df
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 +217 -14
- package/dest/automine/automine_test_context.d.ts +85 -0
- package/dest/automine/automine_test_context.d.ts.map +1 -0
- package/dest/automine/automine_test_context.js +98 -0
- package/dest/automine/contracts/fixtures/storage_proof_fetcher.d.ts +2 -0
- package/dest/automine/contracts/fixtures/storage_proof_fetcher.d.ts.map +1 -0
- package/dest/{e2e_storage_proof → automine/contracts}/fixtures/storage_proof_fixture.d.ts +1 -1
- package/dest/automine/contracts/fixtures/storage_proof_fixture.d.ts.map +1 -0
- package/dest/automine/delivery/interactive_handshake_responder.d.ts +48 -0
- package/dest/automine/delivery/interactive_handshake_responder.d.ts.map +1 -0
- package/dest/automine/delivery/interactive_handshake_responder.js +76 -0
- package/dest/automine/delivery/onchain_delivery_harness.d.ts +19 -0
- package/dest/automine/delivery/onchain_delivery_harness.d.ts.map +1 -0
- package/dest/automine/delivery/onchain_delivery_harness.js +141 -0
- package/dest/automine/token/blacklist_token_contract_test.d.ts +49 -0
- package/dest/automine/token/blacklist_token_contract_test.d.ts.map +1 -0
- package/dest/{e2e_blacklist_token_contract → automine/token}/blacklist_token_contract_test.js +23 -36
- package/dest/automine/token/token_contract_test.d.ts +40 -0
- package/dest/automine/token/token_contract_test.d.ts.map +1 -0
- package/dest/{e2e_token_contract → automine/token}/token_contract_test.js +24 -39
- package/dest/automine/token/token_test_helpers.d.ts +73 -0
- package/dest/automine/token/token_test_helpers.d.ts.map +1 -0
- package/dest/automine/token/token_test_helpers.js +97 -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 +19 -0
- package/dest/bench/client_flows/client_flows_benchmark.d.ts +5 -5
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.js +45 -29
- package/dest/bench/client_flows/data_extractor.js +1 -0
- package/dest/bench/utils.d.ts +3 -3
- package/dest/bench/utils.d.ts.map +1 -1
- package/dest/bench/utils.js +97 -6
- package/dest/composed/ha/ha_full_setup.d.ts +77 -0
- package/dest/composed/ha/ha_full_setup.d.ts.map +1 -0
- package/dest/composed/ha/ha_full_setup.js +383 -0
- package/dest/composed/web3signer/multi_validator_keystore_utils.d.ts +12 -0
- package/dest/composed/web3signer/multi_validator_keystore_utils.d.ts.map +1 -0
- 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 +12 -9
- package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
- package/dest/fixtures/e2e_prover_test.js +50 -30
- package/dest/fixtures/fixtures.d.ts +79 -1
- package/dest/fixtures/fixtures.d.ts.map +1 -1
- package/dest/fixtures/fixtures.js +80 -0
- package/dest/fixtures/ha_setup.d.ts +4 -4
- package/dest/fixtures/ha_setup.d.ts.map +1 -1
- package/dest/fixtures/ha_setup.js +5 -2
- 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 +71 -41
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +277 -198
- 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 +11 -11
- package/dest/fixtures/timing.d.ts +42 -0
- package/dest/fixtures/timing.d.ts.map +1 -0
- package/dest/fixtures/timing.js +72 -0
- package/dest/fixtures/token_utils.d.ts +22 -4
- package/dest/fixtures/token_utils.d.ts.map +1 -1
- package/dest/fixtures/token_utils.js +21 -1
- package/dest/fixtures/utils.d.ts +2 -2
- package/dest/fixtures/utils.d.ts.map +1 -1
- package/dest/fixtures/utils.js +1 -1
- package/dest/fixtures/wait_helpers.d.ts +135 -0
- package/dest/fixtures/wait_helpers.d.ts.map +1 -0
- package/dest/fixtures/wait_helpers.js +154 -0
- 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/multi-node/block-production/setup.d.ts +97 -0
- package/dest/multi-node/block-production/setup.d.ts.map +1 -0
- package/dest/multi-node/block-production/setup.js +158 -0
- package/dest/multi-node/governance/setup.d.ts +67 -0
- package/dest/multi-node/governance/setup.d.ts.map +1 -0
- package/dest/multi-node/governance/setup.js +126 -0
- package/dest/multi-node/multi_node_test_context.d.ts +212 -0
- package/dest/multi-node/multi_node_test_context.d.ts.map +1 -0
- package/dest/multi-node/multi_node_test_context.js +347 -0
- package/dest/multi-node/slashing/inactivity_setup.d.ts +27 -0
- package/dest/multi-node/slashing/inactivity_setup.d.ts.map +1 -0
- package/dest/multi-node/slashing/inactivity_setup.js +111 -0
- package/dest/multi-node/slashing/setup.d.ts +167 -0
- package/dest/multi-node/slashing/setup.d.ts.map +1 -0
- package/dest/multi-node/slashing/setup.js +275 -0
- package/dest/{e2e_p2p → p2p}/p2p_network.d.ts +19 -10
- package/dest/p2p/p2p_network.d.ts.map +1 -0
- package/dest/{e2e_p2p → p2p}/p2p_network.js +81 -38
- package/dest/p2p/reqresp/utils.d.ts +19 -0
- package/dest/p2p/reqresp/utils.d.ts.map +1 -0
- package/dest/{e2e_p2p → p2p}/reqresp/utils.js +32 -29
- package/dest/p2p/shared.d.ts +72 -0
- package/dest/p2p/shared.d.ts.map +1 -0
- package/dest/p2p/shared.js +212 -0
- package/dest/shared/cross_chain_test_harness.d.ts +6 -4
- package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
- package/dest/shared/cross_chain_test_harness.js +25 -20
- 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 +24 -12
- package/dest/shared/submit-transactions.d.ts +1 -1
- package/dest/shared/submit-transactions.d.ts.map +1 -1
- package/dest/shared/submit-transactions.js +12 -5
- package/dest/shared/timing_env.d.js +5 -0
- package/dest/shared/timing_env.js +365 -0
- 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 -37
- 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/single-node/cross-chain/cross_chain_messaging_test.d.ts +75 -0
- package/dest/single-node/cross-chain/cross_chain_messaging_test.d.ts.map +1 -0
- package/dest/single-node/cross-chain/cross_chain_messaging_test.js +209 -0
- package/dest/single-node/cross-chain/message_test_helpers.d.ts +38 -0
- package/dest/single-node/cross-chain/message_test_helpers.d.ts.map +1 -0
- package/dest/single-node/cross-chain/message_test_helpers.js +70 -0
- package/dest/{e2e_fees → single-node/fees}/bridging_race.notest.d.ts +1 -1
- package/dest/single-node/fees/bridging_race.notest.d.ts.map +1 -0
- package/dest/{e2e_fees → single-node/fees}/bridging_race.notest.js +17 -4
- package/dest/single-node/fees/fees_test.d.ts +93 -0
- package/dest/single-node/fees/fees_test.d.ts.map +1 -0
- package/dest/{e2e_fees → single-node/fees}/fees_test.js +78 -59
- package/dest/single-node/l1-reorgs/setup.d.ts +42 -0
- package/dest/single-node/l1-reorgs/setup.d.ts.map +1 -0
- package/dest/single-node/l1-reorgs/setup.js +57 -0
- package/dest/single-node/partial-proofs/setup.d.ts +5 -0
- package/dest/single-node/partial-proofs/setup.d.ts.map +1 -0
- package/dest/single-node/partial-proofs/setup.js +5 -0
- package/dest/single-node/proving/setup.d.ts +5 -0
- package/dest/single-node/proving/setup.d.ts.map +1 -0
- package/dest/single-node/proving/setup.js +5 -0
- package/dest/single-node/recovery/setup.d.ts +5 -0
- package/dest/single-node/recovery/setup.d.ts.map +1 -0
- package/dest/single-node/recovery/setup.js +5 -0
- package/dest/single-node/setup.d.ts +49 -0
- package/dest/single-node/setup.d.ts.map +1 -0
- package/dest/single-node/setup.js +56 -0
- package/dest/single-node/single_node_test_context.d.ts +360 -0
- package/dest/single-node/single_node_test_context.d.ts.map +1 -0
- package/dest/single-node/single_node_test_context.js +833 -0
- 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 +28 -12
- package/dest/spartan/tx_metrics.d.ts +27 -4
- package/dest/spartan/tx_metrics.d.ts.map +1 -1
- package/dest/spartan/tx_metrics.js +105 -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 +39 -10
- package/dest/test-wallet/test_wallet.d.ts.map +1 -1
- package/dest/test-wallet/test_wallet.js +166 -59
- package/dest/test-wallet/utils.d.ts +38 -3
- package/dest/test-wallet/utils.d.ts.map +1 -1
- package/dest/test-wallet/utils.js +65 -10
- package/dest/test-wallet/wallet_worker_script.js +12 -4
- package/dest/test-wallet/worker_wallet.d.ts +9 -8
- package/dest/test-wallet/worker_wallet.d.ts.map +1 -1
- package/dest/test-wallet/worker_wallet.js +10 -4
- package/dest/test-wallet/worker_wallet_schema.d.ts +3 -273
- package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -1
- package/dest/test-wallet/worker_wallet_schema.js +15 -2
- package/package.json +47 -42
- package/src/automine/README.md +60 -0
- package/src/automine/automine_test_context.ts +153 -0
- package/src/automine/delivery/interactive_handshake_responder.ts +125 -0
- package/src/automine/delivery/onchain_delivery_harness.ts +213 -0
- package/src/{e2e_blacklist_token_contract → automine/token}/blacklist_token_contract_test.ts +24 -47
- package/src/{e2e_token_contract → automine/token}/token_contract_test.ts +25 -48
- package/src/automine/token/token_test_helpers.ts +138 -0
- package/src/bench/client_flows/benchmark.ts +21 -0
- package/src/bench/client_flows/client_flows_benchmark.ts +77 -56
- package/src/bench/client_flows/data_extractor.ts +1 -0
- package/src/bench/utils.ts +110 -6
- package/src/composed/ha/ha_full_setup.ts +466 -0
- package/src/fixtures/authwit_proxy.ts +4 -0
- package/src/fixtures/e2e_prover_test.ts +64 -48
- package/src/fixtures/fixtures.ts +100 -0
- package/src/fixtures/ha_setup.ts +11 -5
- package/src/fixtures/index.ts +1 -0
- package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
- package/src/fixtures/setup.ts +336 -255
- package/src/fixtures/setup_p2p_test.ts +15 -11
- package/src/fixtures/timing.ts +97 -0
- package/src/fixtures/token_utils.ts +39 -4
- package/src/fixtures/utils.ts +2 -3
- package/src/fixtures/wait_helpers.ts +333 -0
- package/src/forward-compatibility/wallet_rpc_client.ts +14 -0
- package/src/forward-compatibility/wallet_service.ts +106 -0
- package/src/guides/up_quick_start.sh +5 -2
- package/src/infra/README.md +12 -0
- package/src/install_legacy_contracts.cjs +75 -0
- package/src/legacy-jest-resolver.cjs +112 -0
- package/src/multi-node/README.md +95 -0
- package/src/multi-node/block-production/setup.ts +272 -0
- package/src/multi-node/governance/setup.ts +172 -0
- package/src/multi-node/multi_node_test_context.ts +447 -0
- package/src/multi-node/slashing/inactivity_setup.ts +139 -0
- package/src/multi-node/slashing/setup.ts +433 -0
- package/src/p2p/README.md +78 -0
- package/src/{e2e_p2p → p2p}/p2p_network.ts +92 -49
- package/src/{e2e_p2p → p2p}/reqresp/utils.ts +35 -28
- package/src/p2p/shared.ts +329 -0
- package/src/shared/cross_chain_test_harness.ts +35 -14
- package/src/shared/gas_portal_test_harness.ts +32 -14
- package/src/shared/submit-transactions.ts +13 -5
- package/src/shared/timing_env.d.mts +39 -0
- package/src/shared/timing_env.mjs +363 -0
- package/src/shared/uniswap_l1_l2.ts +80 -43
- package/src/shared/wait_for_l1_to_l2_message.ts +23 -0
- package/src/simulators/lending_simulator.ts +28 -14
- package/src/single-node/README.md +60 -0
- package/src/single-node/cross-chain/cross_chain_messaging_test.ts +302 -0
- package/src/single-node/cross-chain/message_test_helpers.ts +125 -0
- package/src/{e2e_fees → single-node/fees}/bridging_race.notest.ts +19 -5
- package/src/{e2e_fees → single-node/fees}/fees_test.ts +103 -66
- package/src/single-node/l1-reorgs/setup.ts +93 -0
- package/src/single-node/partial-proofs/setup.ts +8 -0
- package/src/single-node/proving/setup.ts +15 -0
- package/src/single-node/recovery/setup.ts +8 -0
- package/src/single-node/setup.ts +63 -0
- package/src/single-node/single_node_test_context.ts +1041 -0
- package/src/spartan/setup_test_wallets.ts +30 -13
- package/src/spartan/tx_metrics.ts +107 -23
- package/src/spartan/utils/nodes.ts +2 -2
- package/src/test-wallet/test_wallet.ts +185 -60
- package/src/test-wallet/utils.ts +104 -11
- package/src/test-wallet/wallet_worker_script.ts +11 -5
- package/src/test-wallet/worker_wallet.ts +19 -16
- package/src/test-wallet/worker_wallet_schema.ts +4 -3
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +0 -55
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +0 -1
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +0 -47
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +0 -1
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +0 -129
- package/dest/e2e_deploy_contract/deploy_test.d.ts +0 -37
- package/dest/e2e_deploy_contract/deploy_test.d.ts.map +0 -1
- package/dest/e2e_deploy_contract/deploy_test.js +0 -50
- package/dest/e2e_epochs/epochs_test.d.ts +0 -104
- package/dest/e2e_epochs/epochs_test.d.ts.map +0 -1
- package/dest/e2e_epochs/epochs_test.js +0 -389
- package/dest/e2e_fees/bridging_race.notest.d.ts.map +0 -1
- package/dest/e2e_fees/fees_test.d.ts +0 -88
- package/dest/e2e_fees/fees_test.d.ts.map +0 -1
- package/dest/e2e_l1_publisher/write_json.d.ts +0 -11
- package/dest/e2e_l1_publisher/write_json.d.ts.map +0 -1
- package/dest/e2e_l1_publisher/write_json.js +0 -56
- package/dest/e2e_multi_validator/utils.d.ts +0 -12
- package/dest/e2e_multi_validator/utils.d.ts.map +0 -1
- package/dest/e2e_nested_contract/nested_contract_test.d.ts +0 -26
- package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +0 -1
- package/dest/e2e_nested_contract/nested_contract_test.js +0 -54
- package/dest/e2e_p2p/inactivity_slash_test.d.ts +0 -31
- package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +0 -1
- package/dest/e2e_p2p/inactivity_slash_test.js +0 -136
- package/dest/e2e_p2p/p2p_network.d.ts.map +0 -1
- package/dest/e2e_p2p/reqresp/utils.d.ts +0 -22
- package/dest/e2e_p2p/reqresp/utils.d.ts.map +0 -1
- package/dest/e2e_p2p/shared.d.ts +0 -66
- package/dest/e2e_p2p/shared.d.ts.map +0 -1
- package/dest/e2e_p2p/shared.js +0 -212
- package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts +0 -2
- package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts.map +0 -1
- package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts.map +0 -1
- package/dest/e2e_token_contract/token_contract_test.d.ts +0 -44
- package/dest/e2e_token_contract/token_contract_test.d.ts.map +0 -1
- package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +0 -193
- package/src/e2e_deploy_contract/deploy_test.ts +0 -85
- package/src/e2e_epochs/epochs_test.ts +0 -499
- package/src/e2e_l1_publisher/write_json.ts +0 -77
- package/src/e2e_nested_contract/nested_contract_test.ts +0 -75
- package/src/e2e_p2p/inactivity_slash_test.ts +0 -179
- package/src/e2e_p2p/shared.ts +0 -343
- /package/dest/{e2e_storage_proof → automine/contracts}/fixtures/storage_proof_fetcher.js +0 -0
- /package/dest/{e2e_storage_proof → automine/contracts}/fixtures/storage_proof_fixture.js +0 -0
- /package/dest/{e2e_multi_validator/utils.js → composed/web3signer/multi_validator_keystore_utils.js} +0 -0
- /package/src/{e2e_storage_proof → automine/contracts}/fixtures/storage_proof.json +0 -0
- /package/src/{e2e_storage_proof → automine/contracts}/fixtures/storage_proof_fetcher.ts +0 -0
- /package/src/{e2e_storage_proof → automine/contracts}/fixtures/storage_proof_fixture.ts +0 -0
- /package/src/{e2e_multi_validator/utils.ts → composed/web3signer/multi_validator_keystore_utils.ts} +0 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import type { InitialAccountData } from '@aztec/accounts/testing';
|
|
2
|
+
import type { Archiver } from '@aztec/archiver';
|
|
3
|
+
import type { AztecNodeService } from '@aztec/aztec-node';
|
|
4
|
+
import type { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
5
|
+
import { NO_WAIT, getContractInstanceFromInstantiationParams } from '@aztec/aztec.js/contracts';
|
|
6
|
+
import { Fr } from '@aztec/aztec.js/fields';
|
|
7
|
+
import type { Logger } from '@aztec/aztec.js/log';
|
|
8
|
+
import { TxHash } from '@aztec/aztec.js/tx';
|
|
9
|
+
import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
10
|
+
import { timesAsync } from '@aztec/foundation/collection';
|
|
11
|
+
import { Signature } from '@aztec/foundation/eth-signature';
|
|
12
|
+
import { retryUntil } from '@aztec/foundation/retry';
|
|
13
|
+
import type { SpamContract } from '@aztec/noir-test-contracts.js/Spam';
|
|
14
|
+
import { TestContract, TestContractArtifact } from '@aztec/noir-test-contracts.js/Test';
|
|
15
|
+
import { getPXEConfig, getPXEConfig as getRpcConfig } from '@aztec/pxe/server';
|
|
16
|
+
import type { SequencerClient } from '@aztec/sequencer-client';
|
|
17
|
+
import { CheckpointAttestation, ConsensusPayload, type TopicType } from '@aztec/stdlib/p2p';
|
|
18
|
+
|
|
19
|
+
import { expect } from '@jest/globals';
|
|
20
|
+
|
|
21
|
+
import { shouldCollectMetrics } from '../fixtures/fixtures.js';
|
|
22
|
+
import { SchnorrHardcodedKeyAccountContract } from '../fixtures/schnorr_hardcoded_account_contract.js';
|
|
23
|
+
import { createNodes } from '../fixtures/setup_p2p_test.js';
|
|
24
|
+
import { waitForTxs } from '../fixtures/wait_helpers.js';
|
|
25
|
+
import { type AlertConfig, GrafanaClient } from '../quality_of_service/grafana_client.js';
|
|
26
|
+
import { submitTxsTo } from '../shared/submit-transactions.js';
|
|
27
|
+
import { TestWallet } from '../test-wallet/test_wallet.js';
|
|
28
|
+
import { type ProvenTx, proveInteraction } from '../test-wallet/utils.js';
|
|
29
|
+
import { type P2PNetworkTest, WAIT_FOR_TX_TIMEOUT } from './p2p_network.js';
|
|
30
|
+
|
|
31
|
+
/** One published checkpoint as returned by the archiver, including its attestations. */
|
|
32
|
+
type PublishedCheckpoint = Awaited<ReturnType<Archiver['getCheckpoints']>>[number];
|
|
33
|
+
|
|
34
|
+
// submits a set of transactions to the provided Private eXecution Environment (PXE)
|
|
35
|
+
export const submitComplexTxsTo = async (
|
|
36
|
+
logger: Logger,
|
|
37
|
+
from: AztecAddress,
|
|
38
|
+
spamContract: SpamContract,
|
|
39
|
+
numTxs: number,
|
|
40
|
+
opts: { callPublic?: boolean } = {},
|
|
41
|
+
) => {
|
|
42
|
+
const txs: TxHash[] = [];
|
|
43
|
+
|
|
44
|
+
const seed = 1234n;
|
|
45
|
+
const spamCount = 15;
|
|
46
|
+
for (let i = 0; i < numTxs; i++) {
|
|
47
|
+
const method = spamContract.methods.spam(seed + BigInt(i * spamCount), spamCount, !!opts.callPublic);
|
|
48
|
+
const { txHash } = await method.send({ from, wait: NO_WAIT });
|
|
49
|
+
logger.info(`Tx sent with hash ${txHash.toString()}`);
|
|
50
|
+
txs.push(txHash);
|
|
51
|
+
}
|
|
52
|
+
return txs;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// creates a wallet and submit a given number of transactions through it.
|
|
56
|
+
export const submitTransactions = async (
|
|
57
|
+
logger: Logger,
|
|
58
|
+
node: AztecNodeService,
|
|
59
|
+
numTxs: number,
|
|
60
|
+
fundedAccount: InitialAccountData,
|
|
61
|
+
): Promise<TxHash[]> => {
|
|
62
|
+
const rpcConfig = getRpcConfig();
|
|
63
|
+
rpcConfig.proverEnabled = false;
|
|
64
|
+
const wallet = await TestWallet.create(
|
|
65
|
+
node,
|
|
66
|
+
// Use checkpointed chain tip to avoid anchoring on provisional blocks that the archiver can prune
|
|
67
|
+
// when their slot ends without a checkpoint landing on L1.
|
|
68
|
+
{ ...getPXEConfig(), proverEnabled: false, syncChainTip: 'checkpointed' },
|
|
69
|
+
{ loggerActorLabel: 'pxe-tx' },
|
|
70
|
+
);
|
|
71
|
+
const contract = new SchnorrHardcodedKeyAccountContract();
|
|
72
|
+
const fundedAccountManager = await wallet.createAccount({
|
|
73
|
+
secret: fundedAccount.secret,
|
|
74
|
+
salt: fundedAccount.salt,
|
|
75
|
+
contract,
|
|
76
|
+
});
|
|
77
|
+
return submitTxsTo(wallet, fundedAccountManager.address, numTxs, logger);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export async function prepareTransactions(
|
|
81
|
+
logger: Logger,
|
|
82
|
+
node: AztecNodeService,
|
|
83
|
+
numTxs: number,
|
|
84
|
+
fundedAccount: InitialAccountData,
|
|
85
|
+
): Promise<ProvenTx[]> {
|
|
86
|
+
const rpcConfig = getRpcConfig();
|
|
87
|
+
rpcConfig.proverEnabled = false;
|
|
88
|
+
|
|
89
|
+
const wallet = await TestWallet.create(
|
|
90
|
+
node,
|
|
91
|
+
{ ...getPXEConfig(), proverEnabled: false, syncChainTip: 'checkpointed' },
|
|
92
|
+
{ loggerActorLabel: 'pxe-tx' },
|
|
93
|
+
);
|
|
94
|
+
const accountContract = new SchnorrHardcodedKeyAccountContract();
|
|
95
|
+
const fundedAccountManager = await wallet.createAccount({
|
|
96
|
+
secret: fundedAccount.secret,
|
|
97
|
+
salt: fundedAccount.salt,
|
|
98
|
+
contract: accountContract,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const testContractInstance = await getContractInstanceFromInstantiationParams(TestContractArtifact, {
|
|
102
|
+
salt: Fr.random(),
|
|
103
|
+
});
|
|
104
|
+
await wallet.registerContract(testContractInstance, TestContractArtifact);
|
|
105
|
+
const contract = TestContract.at(testContractInstance.address, wallet);
|
|
106
|
+
|
|
107
|
+
return timesAsync(numTxs, async () => {
|
|
108
|
+
const tx = await proveInteraction(wallet, contract.methods.emit_nullifier(Fr.random()), {
|
|
109
|
+
from: fundedAccountManager.address,
|
|
110
|
+
});
|
|
111
|
+
logger.info(`Tx prepared with hash ${tx.getTxHash()}`);
|
|
112
|
+
return tx;
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const CHECK_ALERTS = process.env.CHECK_ALERTS === 'true';
|
|
117
|
+
|
|
118
|
+
const qosAlerts: AlertConfig[] = [
|
|
119
|
+
{
|
|
120
|
+
alert: 'SequencerTimeToCollectAttestations',
|
|
121
|
+
expr: 'aztec_sequencer_time_to_collect_attestations > 3500',
|
|
122
|
+
labels: { severity: 'error' },
|
|
123
|
+
for: '10m',
|
|
124
|
+
annotations: {},
|
|
125
|
+
},
|
|
126
|
+
];
|
|
127
|
+
|
|
128
|
+
/** Runs the shared p2p QoS Grafana alert check when CHECK_ALERTS=true; a no-op otherwise. */
|
|
129
|
+
export async function maybeCheckQosAlerts(logger: Logger): Promise<void> {
|
|
130
|
+
if (CHECK_ALERTS) {
|
|
131
|
+
const checker = new GrafanaClient(logger);
|
|
132
|
+
await checker.runAlertCheck(qosAlerts);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** Waits until every node's synced block number reaches the initial node's current tip. */
|
|
137
|
+
export async function waitForNodesToSync(t: P2PNetworkTest, nodes: AztecNodeService[]): Promise<void> {
|
|
138
|
+
const targetBlock = await t.ctx.aztecNode.getBlockNumber();
|
|
139
|
+
t.logger.warn(`Waiting for all nodes to sync to block number ${targetBlock}`);
|
|
140
|
+
await retryUntil(
|
|
141
|
+
async () => {
|
|
142
|
+
const blockNumbers = await Promise.all(nodes.map(node => node.getBlockNumber()));
|
|
143
|
+
const checkpointNumber = (await t.monitor.run()).checkpointNumber;
|
|
144
|
+
t.logger.info(`Current block numbers ${blockNumbers} (checkpoint number on L1 is ${checkpointNumber})`);
|
|
145
|
+
return blockNumbers.every(bn => bn >= targetBlock);
|
|
146
|
+
},
|
|
147
|
+
`nodes to sync to block number ${targetBlock}`,
|
|
148
|
+
30,
|
|
149
|
+
0.5,
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** Reads the published checkpoint containing the block that mined the given tx. */
|
|
154
|
+
export async function getPublishedCheckpointForTx(
|
|
155
|
+
node: AztecNodeService,
|
|
156
|
+
txHash: TxHash,
|
|
157
|
+
): Promise<PublishedCheckpoint> {
|
|
158
|
+
const receipt = await node.getTxReceipt(txHash);
|
|
159
|
+
const blockNumber = receipt.blockNumber!;
|
|
160
|
+
const dataStore = node.getBlockSource() as Archiver;
|
|
161
|
+
const blockData = await dataStore.getBlockData({ number: BlockNumber(blockNumber) });
|
|
162
|
+
const [publishedCheckpoint] = await dataStore.getCheckpoints({ from: blockData!.checkpointNumber, limit: 1 });
|
|
163
|
+
return publishedCheckpoint;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Polls until the archiver has indexed the first published checkpoint, then returns it. */
|
|
167
|
+
export async function waitForFirstPublishedCheckpoint(
|
|
168
|
+
t: P2PNetworkTest,
|
|
169
|
+
nodes: AztecNodeService[],
|
|
170
|
+
timeoutSeconds = 120,
|
|
171
|
+
): Promise<PublishedCheckpoint> {
|
|
172
|
+
const dataStore = nodes[0].getBlockSource() as Archiver;
|
|
173
|
+
t.logger.warn('Waiting for first checkpoint to be published and indexed by the archiver');
|
|
174
|
+
return await retryUntil(
|
|
175
|
+
async () => {
|
|
176
|
+
const blockNumbers = await Promise.all(nodes.map(node => node.getBlockNumber()));
|
|
177
|
+
const checkpointNumber = (await t.monitor.run()).checkpointNumber;
|
|
178
|
+
t.logger.info(`Current block numbers ${blockNumbers} (checkpoint number on L1 is ${checkpointNumber})`);
|
|
179
|
+
const [checkpoint] = await dataStore.getCheckpoints({ from: CheckpointNumber(1), limit: 1 });
|
|
180
|
+
return checkpoint;
|
|
181
|
+
},
|
|
182
|
+
'published checkpoint to be indexed',
|
|
183
|
+
timeoutSeconds,
|
|
184
|
+
1,
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Recovers the attestation signers from a published checkpoint and asserts each one belongs to the
|
|
190
|
+
* validator set formed by the given nodes. Returns the recovered signer addresses so callers can add
|
|
191
|
+
* scenario-specific assertions (e.g. an exact signer count).
|
|
192
|
+
*/
|
|
193
|
+
export async function verifyAttestationSigners(
|
|
194
|
+
t: P2PNetworkTest,
|
|
195
|
+
nodes: AztecNodeService[],
|
|
196
|
+
publishedCheckpoint: PublishedCheckpoint,
|
|
197
|
+
): Promise<string[]> {
|
|
198
|
+
const signatureContext = {
|
|
199
|
+
chainId: t.ctx.aztecNodeConfig.l1ChainId,
|
|
200
|
+
rollupAddress: t.ctx.deployL1ContractsValues.l1ContractAddresses.rollupAddress,
|
|
201
|
+
};
|
|
202
|
+
const payload = ConsensusPayload.fromCheckpoint(publishedCheckpoint.checkpoint, signatureContext);
|
|
203
|
+
const attestations = publishedCheckpoint.attestations
|
|
204
|
+
.filter(a => !a.signature.isEmpty())
|
|
205
|
+
.map(a => new CheckpointAttestation(payload, a.signature, Signature.empty()));
|
|
206
|
+
const signers = await Promise.all(attestations.map(att => att.getSender()!.toString()));
|
|
207
|
+
t.logger.info(`Attestation signers`, { signers });
|
|
208
|
+
|
|
209
|
+
// Check that the signers found are part of the proposer nodes to ensure the archiver fetched them right
|
|
210
|
+
const validatorAddresses = nodes.flatMap(node =>
|
|
211
|
+
(node.getSequencer() as SequencerClient).validatorAddresses?.map(a => a.toString()),
|
|
212
|
+
);
|
|
213
|
+
t.logger.info(`Validator addresses`, { addresses: validatorAddresses });
|
|
214
|
+
for (const signer of signers) {
|
|
215
|
+
expect(validatorAddresses).toContain(signer);
|
|
216
|
+
}
|
|
217
|
+
return signers;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** Options that parameterize {@link runGossipScenario}. */
|
|
221
|
+
export interface GossipScenarioOptions {
|
|
222
|
+
/** The initialized P2P network test (setup() + validator registration already done). */
|
|
223
|
+
t: P2PNetworkTest;
|
|
224
|
+
/** Number of validator nodes forming the committee. */
|
|
225
|
+
numValidators: number;
|
|
226
|
+
/** Base UDP port for the validator nodes. */
|
|
227
|
+
bootNodePort: number;
|
|
228
|
+
/** Transactions submitted per validator node; 0 skips tx submission entirely (e.g. the oracle test). */
|
|
229
|
+
txsPerNode: number;
|
|
230
|
+
/** Submit tx batches sequentially instead of concurrently. */
|
|
231
|
+
submitSequentially?: boolean;
|
|
232
|
+
/** Overrides for the P2P mesh-connectivity wait; unset fields fall back to waitForP2PMeshConnectivity defaults. */
|
|
233
|
+
mesh?: {
|
|
234
|
+
expectedNodeCount?: number;
|
|
235
|
+
timeoutSeconds?: number;
|
|
236
|
+
checkIntervalSeconds?: number;
|
|
237
|
+
topics?: TopicType[];
|
|
238
|
+
minMeshPeerCount?: number;
|
|
239
|
+
};
|
|
240
|
+
/** Which published checkpoint the attestation signers are read from (defaults to the first tx's block). */
|
|
241
|
+
checkpointSource?: 'first-tx' | 'first-published';
|
|
242
|
+
/** Runs after validator registration but before the validator nodes are created. */
|
|
243
|
+
beforeCreateNodes?: () => Promise<void>;
|
|
244
|
+
/** Creates extra non-validator nodes (prover/monitor) once the validator nodes exist. */
|
|
245
|
+
createExtraNodes?: (nodes: AztecNodeService[]) => Promise<void>;
|
|
246
|
+
/** Runs after the account is registered but before txs are submitted (sync waits, checkpoint waits, sleeps). */
|
|
247
|
+
beforeSubmit?: (nodes: AztecNodeService[]) => Promise<void>;
|
|
248
|
+
/** Scenario-specific verification run after attestation-signer verification (proven block, price convergence). */
|
|
249
|
+
afterVerify?: (nodes: AztecNodeService[]) => Promise<void>;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Shared skeleton for the p2p gossip tests: create the validator nodes and any extra nodes, wait for
|
|
254
|
+
* the mesh to form, register the account, optionally submit and mine txs, then verify the attestation
|
|
255
|
+
* signers of a published checkpoint. Each varying part (validator registration, extra nodes, pre-submit
|
|
256
|
+
* waits, scenario-specific verification) is supplied via the callbacks in {@link GossipScenarioOptions}.
|
|
257
|
+
* Returns the validator nodes so the caller can track them for teardown.
|
|
258
|
+
*/
|
|
259
|
+
export async function runGossipScenario(opts: GossipScenarioOptions): Promise<AztecNodeService[]> {
|
|
260
|
+
const { t, numValidators, bootNodePort, txsPerNode } = opts;
|
|
261
|
+
|
|
262
|
+
if (!t.bootstrapNodeEnr) {
|
|
263
|
+
throw new Error('Bootstrap node ENR is not available');
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
await opts.beforeCreateNodes?.();
|
|
267
|
+
|
|
268
|
+
t.logger.info('Creating validator nodes');
|
|
269
|
+
const nodes = await createNodes(
|
|
270
|
+
t.ctx.aztecNodeConfig,
|
|
271
|
+
t.ctx.dateProvider,
|
|
272
|
+
t.bootstrapNodeEnr,
|
|
273
|
+
numValidators,
|
|
274
|
+
bootNodePort,
|
|
275
|
+
t.genesis,
|
|
276
|
+
t.dataDirFor('validator'),
|
|
277
|
+
shouldCollectMetrics(),
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
await opts.createExtraNodes?.(nodes);
|
|
281
|
+
|
|
282
|
+
t.logger.info('Waiting for nodes to connect');
|
|
283
|
+
await t.waitForP2PMeshConnectivity(
|
|
284
|
+
nodes,
|
|
285
|
+
opts.mesh?.expectedNodeCount ?? numValidators,
|
|
286
|
+
opts.mesh?.timeoutSeconds,
|
|
287
|
+
opts.mesh?.checkIntervalSeconds,
|
|
288
|
+
opts.mesh?.topics,
|
|
289
|
+
opts.mesh?.minMeshPeerCount,
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
// We need to create the nodes before we setup the account, because those nodes form the committee
|
|
293
|
+
// and blocks cannot be built without them (targetCommitteeSize is set to the number of nodes).
|
|
294
|
+
await t.setupAccount();
|
|
295
|
+
|
|
296
|
+
await opts.beforeSubmit?.(nodes);
|
|
297
|
+
|
|
298
|
+
let firstTxHash: TxHash | undefined;
|
|
299
|
+
if (txsPerNode > 0) {
|
|
300
|
+
t.logger.info('Submitting transactions');
|
|
301
|
+
const submitOne = (node: AztecNodeService) => submitTransactions(t.logger, node, txsPerNode, t.fundedAccount);
|
|
302
|
+
// Each submitTransactions call builds its own wallet/PXE, so submissions are independent. When run
|
|
303
|
+
// concurrently, Promise.all preserves node order so submitted[i] stays aligned with nodes[i].
|
|
304
|
+
const submitted: TxHash[][] = [];
|
|
305
|
+
if (opts.submitSequentially) {
|
|
306
|
+
for (const node of nodes) {
|
|
307
|
+
submitted.push(await submitOne(node));
|
|
308
|
+
}
|
|
309
|
+
} else {
|
|
310
|
+
submitted.push(...(await Promise.all(nodes.map(submitOne))));
|
|
311
|
+
}
|
|
312
|
+
firstTxHash = submitted[0][0];
|
|
313
|
+
|
|
314
|
+
t.logger.info('Waiting for transactions to be mined');
|
|
315
|
+
await waitForTxs(nodes[0], submitted.flat(), { timeout: WAIT_FOR_TX_TIMEOUT });
|
|
316
|
+
t.logger.info('All transactions mined');
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const publishedCheckpoint =
|
|
320
|
+
opts.checkpointSource === 'first-published'
|
|
321
|
+
? await waitForFirstPublishedCheckpoint(t, nodes)
|
|
322
|
+
: await getPublishedCheckpointForTx(nodes[0], firstTxHash!);
|
|
323
|
+
|
|
324
|
+
await verifyAttestationSigners(t, nodes, publishedCheckpoint);
|
|
325
|
+
|
|
326
|
+
await opts.afterVerify?.(nodes);
|
|
327
|
+
|
|
328
|
+
return nodes;
|
|
329
|
+
}
|
|
@@ -13,18 +13,20 @@ import type { AztecNode } from '@aztec/aztec.js/node';
|
|
|
13
13
|
import type { SiblingPath } from '@aztec/aztec.js/trees';
|
|
14
14
|
import type { TxReceipt } from '@aztec/aztec.js/tx';
|
|
15
15
|
import type { Wallet } from '@aztec/aztec.js/wallet';
|
|
16
|
+
import { OutboxContract } from '@aztec/ethereum/contracts';
|
|
16
17
|
import { deployL1Contract } from '@aztec/ethereum/deploy-l1-contract';
|
|
17
18
|
import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
18
19
|
import type { ExtendedViemWalletClient } from '@aztec/ethereum/types';
|
|
19
20
|
import { EpochNumber } from '@aztec/foundation/branded-types';
|
|
20
|
-
import { retryUntil } from '@aztec/foundation/retry';
|
|
21
21
|
import { TestERC20Abi, TokenPortalAbi, TokenPortalBytecode } from '@aztec/l1-artifacts';
|
|
22
22
|
import { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
23
23
|
import { TokenBridgeContract } from '@aztec/noir-contracts.js/TokenBridge';
|
|
24
24
|
|
|
25
25
|
import { type Hex, getContract } from 'viem';
|
|
26
26
|
|
|
27
|
+
import { testSpan } from '../fixtures/timing.js';
|
|
27
28
|
import { mintTokensToPrivate } from '../fixtures/token_utils.js';
|
|
29
|
+
import { waitForL1ToL2MessageSeen } from './wait_for_l1_to_l2_message.js';
|
|
28
30
|
|
|
29
31
|
/**
|
|
30
32
|
* Deploy L1 token and portal, initialize portal, deploy a non native l2 token contract, its L2 bridge contract and attach is to the portal.
|
|
@@ -42,6 +44,7 @@ export async function deployAndInitializeTokenAndBridgeContracts(
|
|
|
42
44
|
rollupRegistryAddress: EthAddress,
|
|
43
45
|
owner: AztecAddress,
|
|
44
46
|
underlyingERC20Address: EthAddress,
|
|
47
|
+
predeployedTokenPortalAddress?: EthAddress,
|
|
45
48
|
): Promise<{
|
|
46
49
|
/**
|
|
47
50
|
* The L2 token contract instance.
|
|
@@ -64,8 +67,9 @@ export async function deployAndInitializeTokenAndBridgeContracts(
|
|
|
64
67
|
*/
|
|
65
68
|
underlyingERC20: any;
|
|
66
69
|
}> {
|
|
67
|
-
//
|
|
68
|
-
const
|
|
70
|
+
// Deploy the token portal, unless it was already deployed before the node started (under automine).
|
|
71
|
+
const tokenPortalAddress =
|
|
72
|
+
predeployedTokenPortalAddress ?? (await deployL1Contract(l1Client, TokenPortalAbi, TokenPortalBytecode)).address;
|
|
69
73
|
const tokenPortal = getContract({
|
|
70
74
|
address: tokenPortalAddress.toString(),
|
|
71
75
|
abi: TokenPortalAbi,
|
|
@@ -73,14 +77,18 @@ export async function deployAndInitializeTokenAndBridgeContracts(
|
|
|
73
77
|
});
|
|
74
78
|
|
|
75
79
|
// deploy l2 token
|
|
76
|
-
const { contract: token } = await
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
const { contract: token } = await testSpan('deploy:token', () =>
|
|
81
|
+
TokenContract.deploy(wallet, owner, 'TokenName', 'TokenSymbol', 18).send({
|
|
82
|
+
from: owner,
|
|
83
|
+
}),
|
|
84
|
+
);
|
|
79
85
|
|
|
80
86
|
// deploy l2 token bridge and attach to the portal
|
|
81
|
-
const { contract: bridge } = await
|
|
82
|
-
|
|
83
|
-
|
|
87
|
+
const { contract: bridge } = await testSpan('deploy:bridge', () =>
|
|
88
|
+
TokenBridgeContract.deploy(wallet, token.address, tokenPortalAddress).send({
|
|
89
|
+
from: owner,
|
|
90
|
+
}),
|
|
91
|
+
);
|
|
84
92
|
|
|
85
93
|
if ((await token.methods.get_admin().simulate({ from: owner })).result !== owner.toBigInt()) {
|
|
86
94
|
throw new Error(`Token admin is not ${owner}`);
|
|
@@ -134,6 +142,7 @@ export class CrossChainTestHarness {
|
|
|
134
142
|
ownerAddress: AztecAddress,
|
|
135
143
|
logger: Logger,
|
|
136
144
|
underlyingERC20Address: EthAddress,
|
|
145
|
+
predeployedTokenPortalAddress?: EthAddress,
|
|
137
146
|
): Promise<CrossChainTestHarness> {
|
|
138
147
|
const ethAccount = EthAddress.fromString((await l1Client.getAddresses())[0]);
|
|
139
148
|
const l1ContractAddresses = (await aztecNode.getNodeInfo()).l1ContractAddresses;
|
|
@@ -146,6 +155,7 @@ export class CrossChainTestHarness {
|
|
|
146
155
|
l1ContractAddresses.registryAddress,
|
|
147
156
|
ownerAddress,
|
|
148
157
|
underlyingERC20Address,
|
|
158
|
+
predeployedTokenPortalAddress,
|
|
149
159
|
);
|
|
150
160
|
logger.info('Deployed and initialized token, portal and its bridge.');
|
|
151
161
|
|
|
@@ -166,6 +176,7 @@ export class CrossChainTestHarness {
|
|
|
166
176
|
|
|
167
177
|
private readonly l1TokenManager: L1TokenManager;
|
|
168
178
|
private readonly l1TokenPortalManager: L1TokenPortalManager;
|
|
179
|
+
public readonly outboxContract: OutboxContract;
|
|
169
180
|
|
|
170
181
|
constructor(
|
|
171
182
|
/** Aztec node instance. */
|
|
@@ -206,6 +217,7 @@ export class CrossChainTestHarness {
|
|
|
206
217
|
this.logger,
|
|
207
218
|
);
|
|
208
219
|
this.l1TokenManager = this.l1TokenPortalManager.getTokenManager();
|
|
220
|
+
this.outboxContract = new OutboxContract(this.l1Client, this.l1ContractAddresses.outboxAddress);
|
|
209
221
|
}
|
|
210
222
|
|
|
211
223
|
async mintTokensOnL1(amount: bigint) {
|
|
@@ -234,11 +246,13 @@ export class CrossChainTestHarness {
|
|
|
234
246
|
|
|
235
247
|
async mintTokensPublicOnL2(amount: bigint) {
|
|
236
248
|
this.logger.info('Minting tokens on L2 publicly');
|
|
237
|
-
await
|
|
249
|
+
await testSpan('tx:mint', () =>
|
|
250
|
+
this.l2Token.methods.mint_to_public(this.ownerAddress, amount).send({ from: this.ownerAddress }),
|
|
251
|
+
);
|
|
238
252
|
}
|
|
239
253
|
|
|
240
254
|
async mintTokensPrivateOnL2(amount: bigint) {
|
|
241
|
-
await mintTokensToPrivate(this.l2Token, this.ownerAddress, this.ownerAddress, amount);
|
|
255
|
+
await testSpan('tx:mint', () => mintTokensToPrivate(this.l2Token, this.ownerAddress, this.ownerAddress, amount));
|
|
242
256
|
}
|
|
243
257
|
|
|
244
258
|
async sendL2PublicTransfer(transferAmount: bigint, receiverAddress: AztecAddress) {
|
|
@@ -319,10 +333,18 @@ export class CrossChainTestHarness {
|
|
|
319
333
|
withdrawFundsFromBridgeOnL1(
|
|
320
334
|
amount: bigint,
|
|
321
335
|
epochNumber: EpochNumber,
|
|
336
|
+
numCheckpointsInEpoch: number,
|
|
322
337
|
messageIndex: bigint,
|
|
323
338
|
siblingPath: SiblingPath<number>,
|
|
324
339
|
) {
|
|
325
|
-
return this.l1TokenPortalManager.withdrawFunds(
|
|
340
|
+
return this.l1TokenPortalManager.withdrawFunds(
|
|
341
|
+
amount,
|
|
342
|
+
this.ethAccount,
|
|
343
|
+
epochNumber,
|
|
344
|
+
numCheckpointsInEpoch,
|
|
345
|
+
messageIndex,
|
|
346
|
+
siblingPath,
|
|
347
|
+
);
|
|
326
348
|
}
|
|
327
349
|
|
|
328
350
|
async transferToPrivateOnL2(shieldAmount: bigint) {
|
|
@@ -346,8 +368,7 @@ export class CrossChainTestHarness {
|
|
|
346
368
|
*/
|
|
347
369
|
async makeMessageConsumable(msgHash: Fr | Hex) {
|
|
348
370
|
const frMsgHash = typeof msgHash === 'string' ? Fr.fromHexString(msgHash) : msgHash;
|
|
349
|
-
|
|
350
|
-
await retryUntil(async () => await this.aztecNode.isL1ToL2MessageSynced(frMsgHash), 'message sync', 10);
|
|
371
|
+
await waitForL1ToL2MessageSeen(this.aztecNode, frMsgHash, { timeoutSeconds: 10 });
|
|
351
372
|
|
|
352
373
|
await this.mintTokensPublicOnL2(0n);
|
|
353
374
|
await this.mintTokensPublicOnL2(0n);
|
|
@@ -8,7 +8,13 @@ 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 { testSpan } from '../fixtures/timing.js';
|
|
14
|
+
import { waitForL1ToL2MessageSeen } from './wait_for_l1_to_l2_message.js';
|
|
15
|
+
|
|
16
|
+
/** Aztec node that may expose the debug mining API in local e2e setups. */
|
|
17
|
+
type MiningAztecNode = AztecNode & Partial<AztecNodeDebug>;
|
|
12
18
|
|
|
13
19
|
export interface IGasBridgingTestHarness {
|
|
14
20
|
getL1FeeJuiceBalance(address: EthAddress): Promise<bigint>;
|
|
@@ -19,7 +25,7 @@ export interface IGasBridgingTestHarness {
|
|
|
19
25
|
}
|
|
20
26
|
|
|
21
27
|
export interface FeeJuicePortalTestingHarnessFactoryConfig {
|
|
22
|
-
aztecNode:
|
|
28
|
+
aztecNode: MiningAztecNode;
|
|
23
29
|
aztecNodeAdmin?: AztecNodeAdmin;
|
|
24
30
|
l1Client: ExtendedViemWalletClient;
|
|
25
31
|
wallet: Wallet;
|
|
@@ -75,7 +81,7 @@ export class GasBridgingTestHarness implements IGasBridgingTestHarness {
|
|
|
75
81
|
|
|
76
82
|
constructor(
|
|
77
83
|
/** Aztec node */
|
|
78
|
-
public aztecNode:
|
|
84
|
+
public aztecNode: MiningAztecNode,
|
|
79
85
|
/** Aztec node admin interface */
|
|
80
86
|
public aztecNodeAdmin: AztecNodeAdmin | undefined,
|
|
81
87
|
/** Wallet. */
|
|
@@ -144,8 +150,7 @@ export class GasBridgingTestHarness implements IGasBridgingTestHarness {
|
|
|
144
150
|
await this.mintTokensOnL1();
|
|
145
151
|
const claim = await this.sendTokensToPortalPublic(bridgeAmount, owner);
|
|
146
152
|
|
|
147
|
-
|
|
148
|
-
await retryUntil(isSynced, `message ${claim.messageHash} sync`, 24, 1);
|
|
153
|
+
await waitForL1ToL2MessageSeen(this.aztecNode, Fr.fromHexString(claim.messageHash), { timeoutSeconds: 24 });
|
|
149
154
|
|
|
150
155
|
// Progress by 2 L2 blocks so that the l1ToL2Message added above will be available to use on L2.
|
|
151
156
|
await this.advanceL2Block();
|
|
@@ -155,14 +160,21 @@ export class GasBridgingTestHarness implements IGasBridgingTestHarness {
|
|
|
155
160
|
}
|
|
156
161
|
|
|
157
162
|
async bridgeFromL1ToL2(owner: AztecAddress, claimer: AztecAddress) {
|
|
158
|
-
|
|
159
|
-
|
|
163
|
+
await testSpan('setup:bridge', async () => {
|
|
164
|
+
// Prepare the tokens on the L1 side
|
|
165
|
+
const claim = await this.prepareTokensOnL1(owner);
|
|
160
166
|
|
|
161
|
-
|
|
162
|
-
|
|
167
|
+
// Consume L1 -> L2 message and claim tokens privately on L2
|
|
168
|
+
await this.consumeMessageOnAztecAndClaimPrivately(owner, claimer, claim);
|
|
169
|
+
});
|
|
163
170
|
}
|
|
164
171
|
|
|
165
172
|
private async advanceL2Block() {
|
|
173
|
+
if (this.aztecNode.mineBlock) {
|
|
174
|
+
await this.aztecNode.mineBlock();
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
166
178
|
const initialBlockNumber = await this.aztecNode.getBlockNumber();
|
|
167
179
|
|
|
168
180
|
let minTxsPerBlock = undefined;
|
|
@@ -171,11 +183,17 @@ export class GasBridgingTestHarness implements IGasBridgingTestHarness {
|
|
|
171
183
|
await this.aztecNodeAdmin.setConfig({ minTxsPerBlock: 0 }); // Set to 0 to ensure we can advance the block
|
|
172
184
|
}
|
|
173
185
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
186
|
+
try {
|
|
187
|
+
await retryUntil(
|
|
188
|
+
async () => (await this.aztecNode.getBlockNumber()) >= initialBlockNumber + 1,
|
|
189
|
+
'gas portal block advance',
|
|
190
|
+
0,
|
|
191
|
+
0.25,
|
|
192
|
+
);
|
|
193
|
+
} finally {
|
|
194
|
+
if (this.aztecNodeAdmin && minTxsPerBlock !== undefined) {
|
|
195
|
+
await this.aztecNodeAdmin.setConfig({ minTxsPerBlock });
|
|
196
|
+
}
|
|
178
197
|
}
|
|
179
198
|
}
|
|
180
199
|
}
|
|
181
|
-
// docs:end:cross_chain_test_harness
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
2
|
-
import { NO_WAIT } from '@aztec/aztec.js/contracts';
|
|
3
|
-
import { Fr
|
|
2
|
+
import { NO_WAIT, getContractInstanceFromInstantiationParams } from '@aztec/aztec.js/contracts';
|
|
3
|
+
import { Fr } from '@aztec/aztec.js/fields';
|
|
4
4
|
import type { Logger } from '@aztec/aztec.js/log';
|
|
5
5
|
import { TxHash, type TxReceipt, TxStatus } from '@aztec/aztec.js/tx';
|
|
6
6
|
import { times } from '@aztec/foundation/collection';
|
|
7
|
+
import { TestContract, TestContractArtifact } from '@aztec/noir-test-contracts.js/Test';
|
|
7
8
|
|
|
8
9
|
import type { TestWallet } from '../test-wallet/test_wallet.js';
|
|
9
10
|
|
|
@@ -14,12 +15,19 @@ export const submitTxsTo = async (
|
|
|
14
15
|
numTxs: number,
|
|
15
16
|
logger: Logger,
|
|
16
17
|
): Promise<TxHash[]> => {
|
|
18
|
+
// Register (without deploying) a single TestContract instance to source cheap throwaway txs from.
|
|
19
|
+
// emit_nullifier is #[noinitcheck], so it runs on a register-only instance — this avoids a full
|
|
20
|
+
// account-contract deployment per tx, which is all these callers were paying for a mined/gossiped tx.
|
|
21
|
+
const testContractInstance = await getContractInstanceFromInstantiationParams(TestContractArtifact, {
|
|
22
|
+
salt: Fr.random(),
|
|
23
|
+
});
|
|
24
|
+
await wallet.registerContract(testContractInstance, TestContractArtifact);
|
|
25
|
+
const contract = TestContract.at(testContractInstance.address, wallet);
|
|
26
|
+
|
|
17
27
|
const txHashes: TxHash[] = [];
|
|
18
28
|
await Promise.all(
|
|
19
29
|
times(numTxs, async () => {
|
|
20
|
-
const
|
|
21
|
-
const deployMethod = await accountManager.getDeployMethod();
|
|
22
|
-
const { txHash } = await deployMethod.send({ from: submitter, wait: NO_WAIT });
|
|
30
|
+
const { txHash } = await contract.methods.emit_nullifier(Fr.random()).send({ from: submitter, wait: NO_WAIT });
|
|
23
31
|
|
|
24
32
|
logger.info(`Tx sent with hash ${txHash}`);
|
|
25
33
|
const receipt: TxReceipt = await wallet.getTxReceipt(txHash);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** A single recorded span occurrence on the shared `performance.now()` clock. */
|
|
2
|
+
export type TimingSpan = {
|
|
3
|
+
/** Full name of the test running when the span started, or `null` during a beforeAll/afterAll hook. */
|
|
4
|
+
owner?: string | null;
|
|
5
|
+
/** Stable `category:label` tag. */
|
|
6
|
+
name?: string;
|
|
7
|
+
/** Clock value at span start. */
|
|
8
|
+
start: number;
|
|
9
|
+
/** Clock value at span end. */
|
|
10
|
+
end: number;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** Aggregate of one tag's occurrences. */
|
|
14
|
+
export type SpanAggregate = {
|
|
15
|
+
count: number;
|
|
16
|
+
totalMs: number;
|
|
17
|
+
busyMs: number;
|
|
18
|
+
maxMs: number;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Aggregates a list of `{ start, end }` spans of one tag into `{ count, totalMs, busyMs, maxMs }`.
|
|
23
|
+
* Does not mutate the input array.
|
|
24
|
+
*/
|
|
25
|
+
export function aggregateSpans(spans: TimingSpan[]): SpanAggregate;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Groups `spans` by owner then tag, attaches a `spans` aggregate map to the matching record (or
|
|
29
|
+
* `suiteRecord` for `null`-owner spans), derives back-compat `setupFnMs` / `teardownFnMs`, drops spans
|
|
30
|
+
* whose owner matches no record, and returns the raw per-occurrence list (empty unless `emitSpanLines`).
|
|
31
|
+
*/
|
|
32
|
+
export function foldSpansInto(
|
|
33
|
+
spans: TimingSpan[],
|
|
34
|
+
options: {
|
|
35
|
+
recordsByName: Map<string, Record<string, unknown>>;
|
|
36
|
+
suiteRecord: Record<string, unknown>;
|
|
37
|
+
emitSpanLines?: boolean;
|
|
38
|
+
},
|
|
39
|
+
): { owner: string | null; name: string; ms: number }[];
|