@aztec/end-to-end 0.0.1-commit.993d240 → 0.0.1-commit.9a89641
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 +215 -27
- 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 +18 -40
- 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 +22 -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 +1 -1
- package/dest/bench/client_flows/benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/benchmark.js +3 -1
- 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 +34 -25
- 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 +95 -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/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 +48 -28
- package/dest/fixtures/fixtures.d.ts +20 -14
- package/dest/fixtures/fixtures.d.ts.map +1 -1
- package/dest/fixtures/fixtures.js +27 -15
- package/dest/fixtures/get_acvm_config.d.ts +1 -1
- package/dest/fixtures/get_acvm_config.d.ts.map +1 -1
- package/dest/fixtures/get_acvm_config.js +2 -2
- 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 +2 -2
- package/dest/fixtures/ha_setup.d.ts +3 -3
- package/dest/fixtures/ha_setup.d.ts.map +1 -1
- package/dest/fixtures/ha_setup.js +4 -1
- 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/setup.d.ts +52 -40
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +207 -221
- package/dest/fixtures/setup_p2p_test.d.ts +1 -1
- package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.js +3 -3
- package/dest/fixtures/standard_contracts_genesis.d.ts +16 -0
- package/dest/fixtures/standard_contracts_genesis.d.ts.map +1 -0
- package/dest/fixtures/standard_contracts_genesis.js +25 -0
- 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_service.js +3 -3
- 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 +10 -2
- package/dest/p2p/p2p_network.d.ts.map +1 -0
- package/dest/{e2e_p2p → p2p}/p2p_network.js +41 -16
- 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 +6 -19
- 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 +3 -3
- package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
- package/dest/shared/cross_chain_test_harness.js +24 -16
- package/dest/shared/gas_portal_test_harness.d.ts +2 -2
- package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
- package/dest/shared/gas_portal_test_harness.js +10 -8
- 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 +8 -19
- package/dest/shared/wait_for_l1_to_l2_message.js +1 -1
- package/dest/simulators/lending_simulator.js +1 -1
- 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 +95 -0
- package/dest/single-node/fees/fees_test.d.ts.map +1 -0
- package/dest/{e2e_fees → single-node/fees}/fees_test.js +129 -66
- 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 +374 -0
- package/dest/single-node/single_node_test_context.d.ts.map +1 -0
- package/dest/single-node/single_node_test_context.js +847 -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 +24 -10
- package/dest/spartan/tx_metrics.d.ts +10 -1
- package/dest/spartan/tx_metrics.d.ts.map +1 -1
- package/dest/spartan/tx_metrics.js +32 -0
- package/dest/test-wallet/test_wallet.d.ts +23 -3
- package/dest/test-wallet/test_wallet.d.ts.map +1 -1
- package/dest/test-wallet/test_wallet.js +56 -9
- package/dest/test-wallet/utils.d.ts +36 -1
- package/dest/test-wallet/utils.d.ts.map +1 -1
- package/dest/test-wallet/utils.js +64 -4
- package/dest/test-wallet/wallet_worker_script.js +10 -2
- package/dest/test-wallet/worker_wallet.d.ts +5 -5
- package/dest/test-wallet/worker_wallet.d.ts.map +1 -1
- package/dest/test-wallet/worker_wallet.js +6 -4
- package/dest/test-wallet/worker_wallet_schema.d.ts +3 -159
- package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -1
- package/dest/test-wallet/worker_wallet_schema.js +2 -1
- package/package.json +41 -41
- 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 +20 -57
- package/src/{e2e_token_contract → automine/token}/token_contract_test.ts +24 -57
- package/src/automine/token/token_test_helpers.ts +138 -0
- package/src/bench/client_flows/benchmark.ts +3 -1
- package/src/bench/client_flows/client_flows_benchmark.ts +48 -32
- package/src/bench/client_flows/data_extractor.ts +1 -0
- package/src/bench/utils.ts +109 -6
- package/src/composed/ha/ha_full_setup.ts +466 -0
- package/src/fixtures/e2e_prover_test.ts +60 -47
- package/src/fixtures/fixtures.ts +29 -15
- package/src/fixtures/get_acvm_config.ts +2 -8
- package/src/fixtures/get_bb_config.ts +1 -2
- package/src/fixtures/ha_setup.ts +7 -3
- package/src/fixtures/index.ts +1 -0
- package/src/fixtures/setup.ts +255 -281
- package/src/fixtures/setup_p2p_test.ts +3 -3
- package/src/fixtures/standard_contracts_genesis.ts +28 -0
- package/src/fixtures/timing.ts +97 -0
- package/src/fixtures/token_utils.ts +39 -4
- package/src/fixtures/utils.ts +0 -3
- package/src/fixtures/wait_helpers.ts +333 -0
- package/src/forward-compatibility/wallet_service.ts +6 -4
- package/src/guides/up_quick_start.sh +5 -0
- package/src/infra/README.md +12 -0
- package/src/multi-node/README.md +96 -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 +40 -13
- package/src/{e2e_p2p → p2p}/reqresp/utils.ts +7 -18
- package/src/p2p/shared.ts +329 -0
- package/src/shared/cross_chain_test_harness.ts +22 -13
- package/src/shared/gas_portal_test_harness.ts +15 -8
- 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 +38 -21
- package/src/shared/wait_for_l1_to_l2_message.ts +1 -1
- package/src/simulators/lending_simulator.ts +1 -1
- package/src/single-node/README.md +66 -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 +146 -76
- 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 +1058 -0
- package/src/spartan/setup_test_wallets.ts +28 -10
- package/src/spartan/tx_metrics.ts +26 -0
- package/src/test-wallet/test_wallet.ts +60 -10
- package/src/test-wallet/utils.ts +102 -5
- package/src/test-wallet/wallet_worker_script.ts +9 -3
- package/src/test-wallet/worker_wallet.ts +11 -13
- package/src/test-wallet/worker_wallet_schema.ts +3 -2
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +0 -56
- 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 -58
- 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 -161
- 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 -51
- package/dest/e2e_epochs/epochs_test.d.ts +0 -125
- package/dest/e2e_epochs/epochs_test.d.ts.map +0 -1
- package/dest/e2e_epochs/epochs_test.js +0 -460
- package/dest/e2e_fees/bridging_race.notest.d.ts.map +0 -1
- package/dest/e2e_fees/fees_test.d.ts +0 -91
- 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 -55
- 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 -138
- 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 -64
- package/dest/e2e_p2p/shared.d.ts.map +0 -1
- package/dest/e2e_p2p/shared.js +0 -204
- 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 -231
- package/src/e2e_deploy_contract/deploy_test.ts +0 -86
- package/src/e2e_epochs/epochs_test.ts +0 -575
- package/src/e2e_l1_publisher/write_json.ts +0 -77
- package/src/e2e_nested_contract/nested_contract_test.ts +0 -77
- package/src/e2e_p2p/inactivity_slash_test.ts +0 -181
- package/src/e2e_p2p/shared.ts +0 -318
- /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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
2
|
-
import {
|
|
2
|
+
import { createLogger } from '@aztec/aztec.js/log';
|
|
3
3
|
import type { AztecNode } from '@aztec/aztec.js/node';
|
|
4
4
|
import { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
5
5
|
import { GenericProxyContract } from '@aztec/noir-test-contracts.js/GenericProxy';
|
|
@@ -7,27 +7,23 @@ import { InvalidAccountContract } from '@aztec/noir-test-contracts.js/InvalidAcc
|
|
|
7
7
|
|
|
8
8
|
import { jest } from '@jest/globals';
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
ensureAuthRegistryPublished,
|
|
15
|
-
publicDeployAccounts,
|
|
16
|
-
setup,
|
|
17
|
-
teardown,
|
|
18
|
-
} from '../fixtures/setup.js';
|
|
19
|
-
import { mintTokensToPrivate } from '../fixtures/token_utils.js';
|
|
20
|
-
import { TokenSimulator } from '../simulators/token_simulator.js';
|
|
21
|
-
import type { TestWallet } from '../test-wallet/test_wallet.js';
|
|
10
|
+
import { ensureAuthRegistryPublished } from '../../fixtures/setup.js';
|
|
11
|
+
import { mintTokensToPrivate } from '../../fixtures/token_utils.js';
|
|
12
|
+
import { TokenSimulator } from '../../simulators/token_simulator.js';
|
|
13
|
+
import { AutomineTestContext, type AutomineTestOpts } from '../automine_test_context.js';
|
|
22
14
|
|
|
23
15
|
const { METRICS_PORT: metricsPort } = process.env;
|
|
24
16
|
|
|
25
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Token-domain harness over the automine topology: extends {@link AutomineTestContext} with a
|
|
19
|
+
* {@link TokenSimulator}, the USDC Token deploy plus a bad-account and authwit proxy, and an optional
|
|
20
|
+
* mint. Base setup is opt-in via {@link applyBaseSnapshots} (run during `setup()`); {@link applyMint}
|
|
21
|
+
* is called explicitly after `setup()`.
|
|
22
|
+
*/
|
|
23
|
+
export class TokenContractTest extends AutomineTestContext {
|
|
26
24
|
static TOKEN_NAME = 'USDC';
|
|
27
25
|
static TOKEN_SYMBOL = 'USD';
|
|
28
26
|
static TOKEN_DECIMALS = 18n;
|
|
29
|
-
context!: EndToEndContext;
|
|
30
|
-
logger: Logger;
|
|
31
27
|
metricsPort?: number;
|
|
32
28
|
asset!: TokenContract;
|
|
33
29
|
tokenSim!: TokenSimulator;
|
|
@@ -35,16 +31,16 @@ export class TokenContractTest {
|
|
|
35
31
|
|
|
36
32
|
badAccount!: InvalidAccountContract;
|
|
37
33
|
authwitProxy!: GenericProxyContract;
|
|
38
|
-
wallet!: TestWallet;
|
|
39
34
|
adminAddress!: AztecAddress;
|
|
40
|
-
|
|
35
|
+
otherAddress!: AztecAddress;
|
|
41
36
|
account2Address!: AztecAddress;
|
|
42
37
|
|
|
43
38
|
private shouldApplyBaseSetup = false;
|
|
44
|
-
private
|
|
39
|
+
private testName: string;
|
|
45
40
|
|
|
46
41
|
constructor(testName: string) {
|
|
47
|
-
|
|
42
|
+
super();
|
|
43
|
+
this.testName = testName;
|
|
48
44
|
this.metricsPort = metricsPort ? parseInt(metricsPort) : undefined;
|
|
49
45
|
}
|
|
50
46
|
|
|
@@ -56,14 +52,6 @@ export class TokenContractTest {
|
|
|
56
52
|
this.shouldApplyBaseSetup = true;
|
|
57
53
|
}
|
|
58
54
|
|
|
59
|
-
/**
|
|
60
|
-
* Registers that mint should be applied during setup().
|
|
61
|
-
* Call this before setup() to mint tokens to the admin account.
|
|
62
|
-
*/
|
|
63
|
-
applyMintSnapshot() {
|
|
64
|
-
this.shouldApplyMint = true;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
55
|
/**
|
|
68
56
|
* Applies base setup: deploys 3 accounts, publicly deploys accounts, token contract and a "bad account".
|
|
69
57
|
*/
|
|
@@ -71,23 +59,12 @@ export class TokenContractTest {
|
|
|
71
59
|
// Adding a timeout of 2 minutes in here such that it is propagated to the underlying tests
|
|
72
60
|
jest.setTimeout(120_000);
|
|
73
61
|
|
|
74
|
-
this.logger.info('Applying base setup - deploying 3 accounts');
|
|
75
|
-
const { deployedAccounts } = await deployAccounts(
|
|
76
|
-
3,
|
|
77
|
-
this.logger,
|
|
78
|
-
)({
|
|
79
|
-
wallet: this.context.wallet,
|
|
80
|
-
initialFundedAccounts: this.context.initialFundedAccounts,
|
|
81
|
-
});
|
|
82
|
-
|
|
83
62
|
this.node = this.context.aztecNodeService;
|
|
84
63
|
this.wallet = this.context.wallet;
|
|
85
|
-
[this.adminAddress, this.
|
|
64
|
+
[this.adminAddress, this.otherAddress, this.account2Address] = this.context.accounts;
|
|
86
65
|
|
|
87
66
|
this.logger.info('Applying base setup - deploying token contract');
|
|
88
67
|
await ensureAuthRegistryPublished(this.wallet, this.adminAddress);
|
|
89
|
-
this.logger.verbose(`Public deploy accounts...`);
|
|
90
|
-
await publicDeployAccounts(this.wallet, [this.adminAddress, this.account1Address]);
|
|
91
68
|
|
|
92
69
|
this.logger.verbose(`Deploying TokenContract...`);
|
|
93
70
|
({ contract: this.asset } = await TokenContract.deploy(
|
|
@@ -116,7 +93,7 @@ export class TokenContractTest {
|
|
|
116
93
|
|
|
117
94
|
this.tokenSim = new TokenSimulator(this.asset, this.wallet, this.adminAddress, this.logger, [
|
|
118
95
|
this.adminAddress,
|
|
119
|
-
this.
|
|
96
|
+
this.otherAddress,
|
|
120
97
|
]);
|
|
121
98
|
|
|
122
99
|
expect((await this.asset.methods.get_admin().simulate({ from: this.adminAddress })).result).toBe(
|
|
@@ -124,28 +101,18 @@ export class TokenContractTest {
|
|
|
124
101
|
);
|
|
125
102
|
}
|
|
126
103
|
|
|
127
|
-
async setup(opts:
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
fundSponsoredFPC: true,
|
|
132
|
-
skipAccountDeployment: true,
|
|
133
|
-
});
|
|
104
|
+
override async setup(opts: AutomineTestOpts = {}) {
|
|
105
|
+
await super.setup({ numberOfAccounts: 3, metricsPort: this.metricsPort, ...opts });
|
|
106
|
+
// hydrateFromContext repoints `this.logger` at the context logger; restore the harness-named one.
|
|
107
|
+
this.logger = createLogger(`e2e:automine:token:${this.testName}`);
|
|
134
108
|
|
|
135
109
|
if (this.shouldApplyBaseSetup) {
|
|
136
110
|
await this.applyBaseSetup();
|
|
137
111
|
}
|
|
138
|
-
|
|
139
|
-
if (this.shouldApplyMint) {
|
|
140
|
-
await this.applyMint();
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
async teardown() {
|
|
145
|
-
await teardown(this.context);
|
|
146
112
|
}
|
|
147
113
|
|
|
148
|
-
private
|
|
114
|
+
/** Mints an initial public and private balance to the admin account. Call after {@link setup}. */
|
|
115
|
+
async applyMint() {
|
|
149
116
|
this.logger.info('Applying mint setup');
|
|
150
117
|
const { asset, adminAddress, tokenSim } = this;
|
|
151
118
|
const amount = 10000n;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
2
|
+
import type { ContractFunctionInteraction } from '@aztec/aztec.js/contracts';
|
|
3
|
+
import type { Logger } from '@aztec/aztec.js/log';
|
|
4
|
+
import type { Wallet } from '@aztec/aztec.js/wallet';
|
|
5
|
+
import { AMMContract } from '@aztec/noir-contracts.js/AMM';
|
|
6
|
+
import type { GenericProxyContract } from '@aztec/noir-test-contracts.js/GenericProxy';
|
|
7
|
+
|
|
8
|
+
import { sendThroughAuthwitProxy } from '../../fixtures/authwit_proxy.js';
|
|
9
|
+
import { DUPLICATE_NULLIFIER_ERROR } from '../../fixtures/fixtures.js';
|
|
10
|
+
import { type AnyTokenContract, mintTokensToPrivate } from '../../fixtures/token_utils.js';
|
|
11
|
+
import type { TestWallet } from '../../test-wallet/test_wallet.js';
|
|
12
|
+
|
|
13
|
+
/** Whether an amount / balance is read from the private or public balance of the token. */
|
|
14
|
+
export type BalanceKind = 'private' | 'public';
|
|
15
|
+
|
|
16
|
+
/** The invalid-authwit-nonce assertion the contract raises when `from == msg_sender` but nonce != 0. */
|
|
17
|
+
export const INVALID_AUTHWIT_NONCE_ERROR =
|
|
18
|
+
"Assertion failed: Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero";
|
|
19
|
+
|
|
20
|
+
/** Minimal token shape needed to read balances — satisfied structurally by Token/TestToken/TokenBlacklist. */
|
|
21
|
+
export interface BalanceReadable {
|
|
22
|
+
methods: {
|
|
23
|
+
balance_of_private(owner: AztecAddress): { simulate(opts: { from: AztecAddress }): Promise<{ result: bigint }> };
|
|
24
|
+
balance_of_public(owner: AztecAddress): { simulate(opts: { from: AztecAddress }): Promise<{ result: bigint }> };
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Reads the private or public balance of an account, simulating from that account's own scope. */
|
|
29
|
+
export async function balanceOf(asset: BalanceReadable, kind: BalanceKind, account: AztecAddress): Promise<bigint> {
|
|
30
|
+
const interaction =
|
|
31
|
+
kind === 'private' ? asset.methods.balance_of_private(account) : asset.methods.balance_of_public(account);
|
|
32
|
+
return (await interaction.simulate({ from: account })).result;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Returns half of an account's balance, asserting it is non-zero so the operation under test is meaningful. */
|
|
36
|
+
export async function halfBalanceOf(asset: BalanceReadable, kind: BalanceKind, owner: AztecAddress): Promise<bigint> {
|
|
37
|
+
const amount = (await balanceOf(asset, kind, owner)) / 2n;
|
|
38
|
+
expect(amount).toBeGreaterThan(0n);
|
|
39
|
+
return amount;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Returns an amount just above an account's balance (balance + delta), asserting it is non-zero. */
|
|
43
|
+
export async function amountAboveBalance(
|
|
44
|
+
asset: BalanceReadable,
|
|
45
|
+
kind: BalanceKind,
|
|
46
|
+
owner: AztecAddress,
|
|
47
|
+
delta = 1n,
|
|
48
|
+
): Promise<bigint> {
|
|
49
|
+
const amount = (await balanceOf(asset, kind, owner)) + delta;
|
|
50
|
+
expect(amount).toBeGreaterThan(0n);
|
|
51
|
+
return amount;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Grants a public authwit for `caller` to run `action` on behalf of `owner`, executes it from `caller`,
|
|
56
|
+
* then asserts a replay of the same call reverts as unauthorized (the authwit is single-use).
|
|
57
|
+
*
|
|
58
|
+
* `onExecuted` runs after the successful execution (before the replay attempt) so callers can update
|
|
59
|
+
* their {@link TokenSimulator} to match the state change the executed action produced.
|
|
60
|
+
*/
|
|
61
|
+
export async function assertPublicAuthwitReplayRejected(
|
|
62
|
+
wallet: TestWallet,
|
|
63
|
+
owner: AztecAddress,
|
|
64
|
+
action: ContractFunctionInteraction,
|
|
65
|
+
caller: AztecAddress,
|
|
66
|
+
onExecuted?: () => void,
|
|
67
|
+
): Promise<void> {
|
|
68
|
+
const grant = await wallet.setPublicAuthWit(owner, { caller, action }, true);
|
|
69
|
+
await grant.send();
|
|
70
|
+
|
|
71
|
+
await action.send({ from: caller });
|
|
72
|
+
onExecuted?.();
|
|
73
|
+
|
|
74
|
+
await expect(action.simulate({ from: caller })).rejects.toThrow(/unauthorized/);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Creates a private authwit for `owner`, executes `action` through the authwit proxy (so `msg_sender`
|
|
79
|
+
* differs from the note owner), then asserts a replay reverts with a duplicate-nullifier error.
|
|
80
|
+
*
|
|
81
|
+
* `onExecuted` runs after the successful execution (before the replay attempt) so callers can update
|
|
82
|
+
* their {@link TokenSimulator} to match the state change the executed action produced.
|
|
83
|
+
*/
|
|
84
|
+
export async function assertAuthwitProxyReplayRejected(
|
|
85
|
+
proxy: GenericProxyContract,
|
|
86
|
+
wallet: TestWallet,
|
|
87
|
+
owner: AztecAddress,
|
|
88
|
+
action: ContractFunctionInteraction,
|
|
89
|
+
onExecuted?: () => void,
|
|
90
|
+
): Promise<void> {
|
|
91
|
+
const witness = await wallet.createAuthWit(owner, { caller: proxy.address, action });
|
|
92
|
+
|
|
93
|
+
await sendThroughAuthwitProxy(proxy, action, { from: owner, authWitnesses: [witness] });
|
|
94
|
+
onExecuted?.();
|
|
95
|
+
|
|
96
|
+
await expect(sendThroughAuthwitProxy(proxy, action, { from: owner, authWitnesses: [witness] })).rejects.toThrow(
|
|
97
|
+
DUPLICATE_NULLIFIER_ERROR,
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Deploys an {@link AMMContract} over three freshly deployed tokens (token0, token1, and the liquidity
|
|
103
|
+
* token), makes the AMM the liquidity token's minter, and mints `initialBalance` of token0 and token1 to
|
|
104
|
+
* each liquidity provider plus token0 to the swapper. `deploy` selects the token flavour (Token vs
|
|
105
|
+
* TestToken), so the concrete token type flows through to the caller.
|
|
106
|
+
*/
|
|
107
|
+
export async function deployAmmWithTokens<T extends AnyTokenContract>(
|
|
108
|
+
wallet: Wallet,
|
|
109
|
+
admin: AztecAddress,
|
|
110
|
+
deploy: (wallet: Wallet, admin: AztecAddress, initialBalance: bigint, logger: Logger) => Promise<{ contract: T }>,
|
|
111
|
+
opts: { liquidityProviders: AztecAddress[]; swapper: AztecAddress; initialBalance: bigint; logger: Logger },
|
|
112
|
+
): Promise<{ token0: T; token1: T; liquidityToken: T; amm: AMMContract }> {
|
|
113
|
+
const { liquidityProviders, swapper, initialBalance, logger } = opts;
|
|
114
|
+
|
|
115
|
+
const { contract: token0 } = await deploy(wallet, admin, 0n, logger);
|
|
116
|
+
const { contract: token1 } = await deploy(wallet, admin, 0n, logger);
|
|
117
|
+
const { contract: liquidityToken } = await deploy(wallet, admin, 0n, logger);
|
|
118
|
+
|
|
119
|
+
const { contract: amm } = await AMMContract.deploy(
|
|
120
|
+
wallet,
|
|
121
|
+
token0.address,
|
|
122
|
+
token1.address,
|
|
123
|
+
liquidityToken.address,
|
|
124
|
+
).send({ from: admin });
|
|
125
|
+
|
|
126
|
+
// TODO(#9480): consider deploying the token by some factory when the AMM is deployed, and making the AMM be the
|
|
127
|
+
// minter there.
|
|
128
|
+
await liquidityToken.methods.set_minter(amm.address, true).send({ from: admin });
|
|
129
|
+
|
|
130
|
+
for (const lp of liquidityProviders) {
|
|
131
|
+
await mintTokensToPrivate(token0, admin, lp, initialBalance);
|
|
132
|
+
await mintTokensToPrivate(token1, admin, lp, initialBalance);
|
|
133
|
+
}
|
|
134
|
+
// Note that the swapper only holds token0, not token1.
|
|
135
|
+
await mintTokensToPrivate(token0, admin, swapper, initialBalance);
|
|
136
|
+
|
|
137
|
+
return { token0, token1, liquidityToken, amm };
|
|
138
|
+
}
|
|
@@ -336,7 +336,9 @@ export function convertProfileToGHBenchmark(benchmark: ClientFlowBenchmark): Git
|
|
|
336
336
|
*/
|
|
337
337
|
export function expectedExecutionSteps(apps: number): number {
|
|
338
338
|
const kernels = Math.ceil(apps / MAX_APPS_PER_KERNEL);
|
|
339
|
-
|
|
339
|
+
// The final reset and tail are proved as a single circuit (reset_tail or reset_tail_to_public),
|
|
340
|
+
// so they share one execution step.
|
|
341
|
+
return apps + kernels + 1 /* reset+tail */ + 1 /* hiding */;
|
|
340
342
|
}
|
|
341
343
|
|
|
342
344
|
export async function captureProfile(
|
|
@@ -4,6 +4,7 @@ import { FeeJuicePaymentMethodWithClaim } from '@aztec/aztec.js/fee';
|
|
|
4
4
|
import { type FeePaymentMethod, PrivateFeePaymentMethod, SponsoredFeePaymentMethod } from '@aztec/aztec.js/fee';
|
|
5
5
|
import { type Logger, createLogger } from '@aztec/aztec.js/log';
|
|
6
6
|
import type { AztecNode } from '@aztec/aztec.js/node';
|
|
7
|
+
import { FeeJuiceContract } from '@aztec/aztec.js/protocol';
|
|
7
8
|
import type { Wallet } from '@aztec/aztec.js/wallet';
|
|
8
9
|
import { CheatCodes, getTokenAllowedSetupFunctions } from '@aztec/aztec/testing';
|
|
9
10
|
import { createExtendedL1Client } from '@aztec/ethereum/client';
|
|
@@ -13,23 +14,26 @@ import { deployL1Contract } from '@aztec/ethereum/deploy-l1-contract';
|
|
|
13
14
|
import { ChainMonitor } from '@aztec/ethereum/test';
|
|
14
15
|
import { randomBytes } from '@aztec/foundation/crypto/random';
|
|
15
16
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
17
|
+
import { GrumpkinScalar } from '@aztec/foundation/curves/grumpkin';
|
|
16
18
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
17
19
|
import { TestERC20Abi } from '@aztec/l1-artifacts/TestERC20Abi';
|
|
18
20
|
import { TestERC20Bytecode } from '@aztec/l1-artifacts/TestERC20Bytecode';
|
|
19
21
|
import { AMMContract } from '@aztec/noir-contracts.js/AMM';
|
|
20
22
|
import { FPCContract } from '@aztec/noir-contracts.js/FPC';
|
|
21
|
-
import { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice';
|
|
22
23
|
import { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC';
|
|
23
|
-
import {
|
|
24
|
-
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
25
|
-
import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice';
|
|
24
|
+
import { TestTokenContract as BananaCoin, TestTokenContract } from '@aztec/noir-test-contracts.js/TestToken';
|
|
26
25
|
import { type PXEConfig, getPXEConfig } from '@aztec/pxe/server';
|
|
27
26
|
import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
28
|
-
import { GasSettings } from '@aztec/stdlib/gas';
|
|
29
|
-
import {
|
|
27
|
+
import { Gas, GasSettings } from '@aztec/stdlib/gas';
|
|
28
|
+
import { AppTaggingSecretKind } from '@aztec/stdlib/logs';
|
|
30
29
|
|
|
31
|
-
import {
|
|
32
|
-
|
|
30
|
+
import {
|
|
31
|
+
AUTOMINE_E2E_OPTS,
|
|
32
|
+
L1_DIRECT_WRITE_ACCOUNT_INDEX,
|
|
33
|
+
MNEMONIC,
|
|
34
|
+
getPaddedMaxFeesPerGas,
|
|
35
|
+
} from '../../fixtures/fixtures.js';
|
|
36
|
+
import { type EndToEndContext, type SetupOptions, setup, teardown } from '../../fixtures/setup.js';
|
|
33
37
|
import { mintTokensToPrivate } from '../../fixtures/token_utils.js';
|
|
34
38
|
import { setupSponsoredFPC } from '../../fixtures/utils.js';
|
|
35
39
|
import { CrossChainTestHarness } from '../../shared/cross_chain_test_harness.js';
|
|
@@ -71,13 +75,13 @@ export class ClientFlowsBenchmark {
|
|
|
71
75
|
public bananaFPC!: FPCContract;
|
|
72
76
|
public bananaFPCInstance!: ContractInstanceWithAddress;
|
|
73
77
|
// Random asset we want to trade
|
|
74
|
-
public candyBarCoin!:
|
|
78
|
+
public candyBarCoin!: TestTokenContract;
|
|
75
79
|
public candyBarCoinInstance!: ContractInstanceWithAddress;
|
|
76
80
|
// AMM contract
|
|
77
81
|
public amm!: AMMContract;
|
|
78
82
|
public ammInstance!: ContractInstanceWithAddress;
|
|
79
83
|
// Liquidity token for AMM
|
|
80
|
-
public liquidityToken!:
|
|
84
|
+
public liquidityToken!: TestTokenContract;
|
|
81
85
|
public liquidityTokenInstance!: ContractInstanceWithAddress;
|
|
82
86
|
// Sponsored FPC contract
|
|
83
87
|
public sponsoredFPC!: SponsoredFPCContract;
|
|
@@ -134,11 +138,11 @@ export class ClientFlowsBenchmark {
|
|
|
134
138
|
async setup() {
|
|
135
139
|
this.logger.info('Setting up subsystems from fresh');
|
|
136
140
|
// Token allowlist entries are test-only: FPC-based fee payment with custom tokens won't work on mainnet alpha.
|
|
137
|
-
|
|
138
|
-
|
|
141
|
+
// BananaCoin is the codegen'd TestToken here, so the allowlist must key on its class, not canonical Token's.
|
|
142
|
+
const tokenAllowList = await getTokenAllowedSetupFunctions(BananaCoin.artifact);
|
|
143
|
+
this.context = await setup(2, {
|
|
139
144
|
...this.setupOptions,
|
|
140
145
|
fundSponsoredFPC: true,
|
|
141
|
-
skipAccountDeployment: true,
|
|
142
146
|
l1ContractsArgs: this.setupOptions,
|
|
143
147
|
txPublicSetupAllowListExtend: [...(this.setupOptions.txPublicSetupAllowListExtend ?? []), ...tokenAllowList],
|
|
144
148
|
});
|
|
@@ -186,7 +190,7 @@ export class ClientFlowsBenchmark {
|
|
|
186
190
|
|
|
187
191
|
let benchysPrivateSigningKey;
|
|
188
192
|
if (type === 'schnorr') {
|
|
189
|
-
benchysPrivateSigningKey =
|
|
193
|
+
benchysPrivateSigningKey = GrumpkinScalar.random();
|
|
190
194
|
return wallet.createSchnorrAccount(benchysSecret, salt, benchysPrivateSigningKey);
|
|
191
195
|
} else if (type === 'ecdsar1') {
|
|
192
196
|
benchysPrivateSigningKey = randomBytes(32);
|
|
@@ -203,15 +207,7 @@ export class ClientFlowsBenchmark {
|
|
|
203
207
|
|
|
204
208
|
async applyInitialAccounts() {
|
|
205
209
|
this.logger.info('Applying initial accounts setup');
|
|
206
|
-
const
|
|
207
|
-
2,
|
|
208
|
-
this.logger,
|
|
209
|
-
)({
|
|
210
|
-
wallet: this.context.wallet,
|
|
211
|
-
initialFundedAccounts: this.context.initialFundedAccounts,
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
const [{ address: adminAddress }, { address: sequencerAddress }] = deployedAccounts;
|
|
210
|
+
const [adminAddress, sequencerAddress] = this.context.accounts;
|
|
215
211
|
|
|
216
212
|
this.adminWallet = this.context.wallet;
|
|
217
213
|
this.aztecNode = this.context.aztecNodeService;
|
|
@@ -220,8 +216,7 @@ export class ClientFlowsBenchmark {
|
|
|
220
216
|
this.adminAddress = adminAddress;
|
|
221
217
|
this.sequencerAddress = sequencerAddress;
|
|
222
218
|
|
|
223
|
-
|
|
224
|
-
this.feeJuiceContract = FeeJuiceContract.at(canonicalFeeJuice.address, this.adminWallet);
|
|
219
|
+
this.feeJuiceContract = FeeJuiceContract.withWallet(this.adminWallet);
|
|
225
220
|
this.coinbase = EthAddress.random();
|
|
226
221
|
|
|
227
222
|
const userPXEConfig = getPXEConfig();
|
|
@@ -234,17 +229,38 @@ export class ClientFlowsBenchmark {
|
|
|
234
229
|
loggers: {
|
|
235
230
|
prover: this.proxyLogger.createLogger('pxe:bb:wasm:bundle:proxied'),
|
|
236
231
|
},
|
|
232
|
+
// The benchmark measures steady-state app cost, not first-send discovery cost. Reproduce the pre-handshake-default
|
|
233
|
+
// behavior of unconstrained delivery: derive the tagging secret from the (sender, recipient) key pair via ECDH
|
|
234
|
+
// instead of taking the current default (a non-interactive handshake, which injects two extra private app
|
|
235
|
+
// executions and a nullifier per cold chain). Constrained delivery is unaffected: the Noir circuit rejects
|
|
236
|
+
// address-derived for constrained, so the hook falls through to a handshake there.
|
|
237
|
+
hooks: {
|
|
238
|
+
resolveTaggingSecretStrategy: ({ deliveryMode }) =>
|
|
239
|
+
Promise.resolve(
|
|
240
|
+
deliveryMode === AppTaggingSecretKind.UNCONSTRAINED
|
|
241
|
+
? { type: 'address-derived' }
|
|
242
|
+
: { type: 'non-interactive-handshake' },
|
|
243
|
+
),
|
|
244
|
+
},
|
|
237
245
|
});
|
|
238
246
|
}
|
|
239
247
|
|
|
240
248
|
async applySetupFeeJuice() {
|
|
241
249
|
this.logger.info('Applying fee juice setup');
|
|
242
|
-
this.feeJuiceContract = FeeJuiceContract.
|
|
250
|
+
this.feeJuiceContract = FeeJuiceContract.withWallet(this.adminWallet);
|
|
243
251
|
|
|
244
252
|
this.feeJuiceBridgeTestHarness = await FeeJuicePortalTestingHarnessFactory.create({
|
|
245
253
|
aztecNode: this.context.aztecNodeService,
|
|
246
254
|
aztecNodeAdmin: this.context.aztecNodeService,
|
|
247
|
-
|
|
255
|
+
// Bridge from a dedicated L1 account so its direct writes don't race the sequencer publisher's
|
|
256
|
+
// txs on the deployer account (see L1_DIRECT_WRITE_ACCOUNT_INDEX).
|
|
257
|
+
l1Client: createExtendedL1Client(
|
|
258
|
+
this.context.config.l1RpcUrls,
|
|
259
|
+
MNEMONIC,
|
|
260
|
+
undefined,
|
|
261
|
+
undefined,
|
|
262
|
+
L1_DIRECT_WRITE_ACCOUNT_INDEX,
|
|
263
|
+
),
|
|
248
264
|
wallet: this.adminWallet,
|
|
249
265
|
logger: this.logger,
|
|
250
266
|
});
|
|
@@ -268,7 +284,7 @@ export class ClientFlowsBenchmark {
|
|
|
268
284
|
|
|
269
285
|
async applyDeployCandyBarToken() {
|
|
270
286
|
this.logger.info('Applying candy bar token deployment');
|
|
271
|
-
const { contract: candyBarCoin, instance: candyBarCoinInstance } = await
|
|
287
|
+
const { contract: candyBarCoin, instance: candyBarCoinInstance } = await TestTokenContract.deploy(
|
|
272
288
|
this.adminWallet,
|
|
273
289
|
this.adminAddress,
|
|
274
290
|
'CBC',
|
|
@@ -338,7 +354,6 @@ export class ClientFlowsBenchmark {
|
|
|
338
354
|
|
|
339
355
|
public async createAndFundBenchmarkingAccountOnUserWallet(accountType: AccountType) {
|
|
340
356
|
const benchysAccountManager = await this.createBenchmarkingAccountManager(this.adminWallet, accountType);
|
|
341
|
-
const benchysAccount = await benchysAccountManager.getAccount();
|
|
342
357
|
const benchysAddress = benchysAccountManager.address;
|
|
343
358
|
const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(benchysAddress);
|
|
344
359
|
const behchysDeployMethod = await benchysAccountManager.getDeployMethod();
|
|
@@ -348,7 +363,7 @@ export class ClientFlowsBenchmark {
|
|
|
348
363
|
});
|
|
349
364
|
// Register benchy on the user's Wallet, where we're going to be interacting from
|
|
350
365
|
const accountManager = await this.userWallet.createAccount({
|
|
351
|
-
secret:
|
|
366
|
+
secret: benchysAccountManager.getSecretKey(),
|
|
352
367
|
salt: new Fr(benchysAccountManager.getInstance().salt),
|
|
353
368
|
contract: benchysAccountManager.getAccountContract(),
|
|
354
369
|
});
|
|
@@ -357,7 +372,7 @@ export class ClientFlowsBenchmark {
|
|
|
357
372
|
|
|
358
373
|
public async applyDeployAmm() {
|
|
359
374
|
this.logger.info('Applying AMM deployment');
|
|
360
|
-
const { contract: liquidityToken, instance: liquidityTokenInstance } = await
|
|
375
|
+
const { contract: liquidityToken, instance: liquidityTokenInstance } = await TestTokenContract.deploy(
|
|
361
376
|
this.adminWallet,
|
|
362
377
|
this.adminAddress,
|
|
363
378
|
'LPT',
|
|
@@ -389,7 +404,8 @@ export class ClientFlowsBenchmark {
|
|
|
389
404
|
// The private fee paying method assembled on the app side requires knowledge of the maximum
|
|
390
405
|
// fee the user is willing to pay
|
|
391
406
|
const maxFeesPerGas = await getPaddedMaxFeesPerGas(this.aztecNode);
|
|
392
|
-
const
|
|
407
|
+
const gasLimits = Gas.from((await this.aztecNode.getNodeInfo()).txsLimits.gas);
|
|
408
|
+
const gasSettings = GasSettings.fallback({ gasLimits, maxFeesPerGas });
|
|
393
409
|
return new PrivateFeePaymentMethod(this.bananaFPC.address, sender, wallet, gasSettings);
|
|
394
410
|
}
|
|
395
411
|
|
package/src/bench/utils.ts
CHANGED
|
@@ -2,8 +2,10 @@ import type { AztecNodeService } from '@aztec/aztec-node';
|
|
|
2
2
|
import { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
3
3
|
import { BatchCall, NO_WAIT, type WaitOpts } from '@aztec/aztec.js/contracts';
|
|
4
4
|
import { waitForTx } from '@aztec/aztec.js/node';
|
|
5
|
+
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
5
6
|
import { mean, stdDev, times } from '@aztec/foundation/collection';
|
|
6
7
|
import { BenchmarkingContract } from '@aztec/noir-test-contracts.js/Benchmarking';
|
|
8
|
+
import { type Sequencer, type SequencerEvents, SequencerState } from '@aztec/sequencer-client';
|
|
7
9
|
import type { TxHash } from '@aztec/stdlib/tx';
|
|
8
10
|
import type { MetricDefinition } from '@aztec/telemetry-client';
|
|
9
11
|
import type { BenchmarkDataPoint, BenchmarkMetricsType, BenchmarkTelemetryClient } from '@aztec/telemetry-client/bench';
|
|
@@ -14,8 +16,13 @@ import path from 'path';
|
|
|
14
16
|
import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js';
|
|
15
17
|
import { type EndToEndContext, type SetupOptions, setup } from '../fixtures/utils.js';
|
|
16
18
|
|
|
19
|
+
const MAX_BENCH_WAIT_BLOCKS = 6;
|
|
20
|
+
const BENCH_FINAL_WAIT_TIMEOUT_SECONDS = 10;
|
|
21
|
+
const SEQUENCER_IDLE_TIMEOUT_MS = 60_000;
|
|
22
|
+
const DEFAULT_L1_PUBLISHING_TIME_SECONDS = 12;
|
|
23
|
+
|
|
17
24
|
/**
|
|
18
|
-
* Setup for benchmarks. Initializes a remote node with a
|
|
25
|
+
* Setup for benchmarks. Initializes a remote node with a funded hardcoded account and deploys a benchmark contract.
|
|
19
26
|
*/
|
|
20
27
|
export async function benchmarkSetup(
|
|
21
28
|
opts: Partial<SetupOptions> & {
|
|
@@ -24,11 +31,19 @@ export async function benchmarkSetup(
|
|
|
24
31
|
benchOutput?: string;
|
|
25
32
|
},
|
|
26
33
|
) {
|
|
27
|
-
const context = await setup(1, {
|
|
28
|
-
|
|
29
|
-
|
|
34
|
+
const context = await setup(1, {
|
|
35
|
+
...PIPELINING_SETUP_OPTS,
|
|
36
|
+
...opts,
|
|
37
|
+
telemetryConfig: { benchmark: true },
|
|
38
|
+
});
|
|
39
|
+
const [defaultAccountAddress] = context.accounts;
|
|
40
|
+
const sequencer = getSequencerClient(context);
|
|
41
|
+
await waitForSequencerIdle(sequencer.getSequencer());
|
|
42
|
+
const deployment = BenchmarkingContract.deploy(context.wallet);
|
|
43
|
+
const { txHash } = await deployment.send({ from: defaultAccountAddress, wait: NO_WAIT });
|
|
44
|
+
await waitTxs([txHash], context);
|
|
45
|
+
const contract = await deployment.register();
|
|
30
46
|
context.logger.info(`Deployed benchmarking contract at ${contract.address}`);
|
|
31
|
-
const sequencer = (context.aztecNode as AztecNodeService).getSequencer()!;
|
|
32
47
|
const telemetry = context.telemetryClient as BenchmarkTelemetryClient;
|
|
33
48
|
context.logger.warn(`Cleared benchmark data points from setup`);
|
|
34
49
|
telemetry.clear();
|
|
@@ -49,6 +64,14 @@ export async function benchmarkSetup(
|
|
|
49
64
|
return { telemetry, context, contract, sequencer };
|
|
50
65
|
}
|
|
51
66
|
|
|
67
|
+
function getSequencerClient(context: EndToEndContext) {
|
|
68
|
+
const sequencer = (context.aztecNode as AztecNodeService).getSequencer();
|
|
69
|
+
if (!sequencer) {
|
|
70
|
+
throw new Error('Benchmark setup requires a local sequencer');
|
|
71
|
+
}
|
|
72
|
+
return sequencer;
|
|
73
|
+
}
|
|
74
|
+
|
|
52
75
|
type MetricFilter = {
|
|
53
76
|
source: MetricDefinition;
|
|
54
77
|
transform: (value: number) => number;
|
|
@@ -160,10 +183,90 @@ export async function sendTxs(
|
|
|
160
183
|
|
|
161
184
|
export async function waitTxs(txs: TxHash[], context: EndToEndContext, txWaitOpts?: WaitOpts) {
|
|
162
185
|
context.logger.info(`Awaiting ${txs.length} txs to be mined`);
|
|
163
|
-
await
|
|
186
|
+
await waitTxsWithBlockMining(txs, context, txWaitOpts);
|
|
164
187
|
context.logger.info(`${txs.length} txs have been mined`);
|
|
165
188
|
}
|
|
166
189
|
|
|
190
|
+
async function waitTxsWithBlockMining(txs: TxHash[], context: EndToEndContext, txWaitOpts?: WaitOpts) {
|
|
191
|
+
const sequencer = getSequencerClient(context).getSequencer();
|
|
192
|
+
for (let attempt = 0; attempt <= MAX_BENCH_WAIT_BLOCKS; attempt++) {
|
|
193
|
+
if (await haveAllTxsMined(txs, context, txWaitOpts)) {
|
|
194
|
+
await waitForSequencerIdle(sequencer);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
await waitForSequencerIdle(sequencer);
|
|
198
|
+
context.logger.info('Mining next benchmark block while waiting for txs', {
|
|
199
|
+
attempt,
|
|
200
|
+
txs: txs.length,
|
|
201
|
+
});
|
|
202
|
+
await mineNextBenchmarkBlock(context, sequencer);
|
|
203
|
+
}
|
|
204
|
+
await Promise.all(
|
|
205
|
+
txs.map(txHash =>
|
|
206
|
+
waitForTx(context.aztecNode, txHash, {
|
|
207
|
+
...txWaitOpts,
|
|
208
|
+
timeout: txWaitOpts?.timeout ?? BENCH_FINAL_WAIT_TIMEOUT_SECONDS,
|
|
209
|
+
}),
|
|
210
|
+
),
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async function haveAllTxsMined(txs: TxHash[], context: EndToEndContext, txWaitOpts?: WaitOpts): Promise<boolean> {
|
|
215
|
+
const receipts = await Promise.all(txs.map(txHash => context.aztecNode.getTxReceipt(txHash)));
|
|
216
|
+
for (const receipt of receipts) {
|
|
217
|
+
if (receipt.isDropped()) {
|
|
218
|
+
throw new Error(`Transaction ${receipt.txHash.toString()} was dropped. Reason: ${receipt.error ?? 'unknown'}`);
|
|
219
|
+
}
|
|
220
|
+
if (!receipt.isMined()) {
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
if (!receipt.hasExecutionSucceeded() && !txWaitOpts?.dontThrowOnRevert) {
|
|
224
|
+
throw new Error(
|
|
225
|
+
`Transaction ${receipt.txHash.toString()} reverted: ${receipt.executionResult}. Reason: ${
|
|
226
|
+
receipt.error ?? 'unknown'
|
|
227
|
+
}`,
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return true;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async function mineNextBenchmarkBlock(context: EndToEndContext, sequencer: Sequencer) {
|
|
235
|
+
const l1PublishingTime = BigInt(context.config.l1PublishingTime ?? DEFAULT_L1_PUBLISHING_TIME_SECONDS);
|
|
236
|
+
const currentTimestamp = BigInt(await context.cheatCodes.eth.lastBlockTimestamp());
|
|
237
|
+
let targetSlot = SlotNumber((await context.cheatCodes.rollup.getSlot()) + 1);
|
|
238
|
+
let targetTimestamp = await context.cheatCodes.rollup.getTimestampForSlot(targetSlot);
|
|
239
|
+
while (targetTimestamp - l1PublishingTime - 1n <= currentTimestamp) {
|
|
240
|
+
targetSlot = SlotNumber(targetSlot + 1);
|
|
241
|
+
targetTimestamp = await context.cheatCodes.rollup.getTimestampForSlot(targetSlot);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const triggerTimestamp = targetTimestamp - l1PublishingTime - 1n;
|
|
245
|
+
await context.cheatCodes.eth.warp(triggerTimestamp, { resetBlockInterval: true });
|
|
246
|
+
await context.aztecNode.mineBlock();
|
|
247
|
+
await waitForSequencerIdle(sequencer);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function waitForSequencerIdle(sequencer: Sequencer, timeout = SEQUENCER_IDLE_TIMEOUT_MS): Promise<void> {
|
|
251
|
+
if (sequencer.status().state === SequencerState.IDLE) {
|
|
252
|
+
return Promise.resolve();
|
|
253
|
+
}
|
|
254
|
+
return new Promise((resolve, reject) => {
|
|
255
|
+
const timer = setTimeout(() => {
|
|
256
|
+
sequencer.off('state-changed', handler);
|
|
257
|
+
reject(new Error('Timeout waiting for sequencer IDLE state'));
|
|
258
|
+
}, timeout);
|
|
259
|
+
const handler = (args: Parameters<SequencerEvents['state-changed']>[0]) => {
|
|
260
|
+
if (args.newState === SequencerState.IDLE) {
|
|
261
|
+
clearTimeout(timer);
|
|
262
|
+
sequencer.off('state-changed', handler);
|
|
263
|
+
resolve();
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
sequencer.on('state-changed', handler);
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
|
|
167
270
|
function randomBytesAsBigInts(length: number): bigint[] {
|
|
168
271
|
return [...Array(length)].map(_ => BigInt(Math.floor(Math.random() * 255)));
|
|
169
272
|
}
|