@aztec/end-to-end 0.0.1-commit.e3c1de76 → 0.0.1-commit.e57c76e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -0
- package/dest/bench/client_flows/benchmark.d.ts +15 -1
- package/dest/bench/client_flows/benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/benchmark.js +17 -0
- package/dest/bench/client_flows/client_flows_benchmark.d.ts +3 -3
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.js +36 -39
- package/dest/bench/client_flows/config.d.ts +2 -2
- package/dest/bench/client_flows/config.d.ts.map +1 -1
- package/dest/bench/client_flows/config.js +18 -0
- package/dest/bench/utils.d.ts +1 -1
- package/dest/bench/utils.d.ts.map +1 -1
- package/dest/bench/utils.js +8 -3
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +8 -5
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +36 -17
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +16 -5
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +42 -9
- package/dest/e2e_deploy_contract/deploy_test.d.ts +4 -4
- package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
- package/dest/e2e_deploy_contract/deploy_test.js +2 -1
- package/dest/e2e_epochs/epochs_test.d.ts +33 -8
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +143 -44
- package/dest/e2e_fees/fees_test.d.ts +6 -3
- package/dest/e2e_fees/fees_test.d.ts.map +1 -1
- package/dest/e2e_fees/fees_test.js +50 -17
- package/dest/e2e_nested_contract/nested_contract_test.d.ts +3 -3
- package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
- package/dest/e2e_nested_contract/nested_contract_test.js +6 -7
- package/dest/e2e_p2p/inactivity_slash_test.d.ts +1 -1
- package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -1
- package/dest/e2e_p2p/inactivity_slash_test.js +4 -3
- package/dest/e2e_p2p/p2p_network.d.ts +14 -12
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +70 -34
- package/dest/e2e_p2p/reqresp/utils.d.ts +3 -3
- package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -1
- package/dest/e2e_p2p/reqresp/utils.js +67 -14
- package/dest/e2e_p2p/shared.d.ts +37 -8
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +91 -51
- package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts +2 -0
- package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts.map +1 -0
- package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.js +184 -0
- package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts +18 -0
- package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts.map +1 -0
- package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.js +120 -0
- package/dest/e2e_token_contract/token_contract_test.d.ts +6 -4
- package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
- package/dest/e2e_token_contract/token_contract_test.js +23 -11
- package/dest/fixtures/authwit_proxy.d.ts +15 -0
- package/dest/fixtures/authwit_proxy.d.ts.map +1 -0
- package/dest/fixtures/authwit_proxy.js +34 -0
- package/dest/fixtures/e2e_prover_test.d.ts +9 -8
- package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
- package/dest/fixtures/e2e_prover_test.js +39 -50
- package/dest/fixtures/elu_monitor.d.ts +21 -0
- package/dest/fixtures/elu_monitor.d.ts.map +1 -0
- package/dest/fixtures/elu_monitor.js +102 -0
- package/dest/fixtures/fixtures.d.ts +74 -1
- package/dest/fixtures/fixtures.d.ts.map +1 -1
- package/dest/fixtures/fixtures.js +71 -0
- package/dest/fixtures/get_bb_config.d.ts +1 -1
- package/dest/fixtures/get_bb_config.d.ts.map +1 -1
- package/dest/fixtures/get_bb_config.js +5 -5
- package/dest/fixtures/ha_setup.d.ts +71 -0
- package/dest/fixtures/ha_setup.d.ts.map +1 -0
- package/dest/fixtures/ha_setup.js +116 -0
- package/dest/fixtures/index.d.ts +2 -1
- package/dest/fixtures/index.d.ts.map +1 -1
- package/dest/fixtures/index.js +1 -0
- package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts +25 -0
- package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts.map +1 -0
- package/dest/fixtures/schnorr_hardcoded_account_contract.js +37 -0
- package/dest/fixtures/setup.d.ts +86 -32
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +209 -169
- package/dest/fixtures/setup_p2p_test.d.ts +22 -10
- package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.js +23 -17
- package/dest/fixtures/token_utils.d.ts +2 -2
- package/dest/fixtures/token_utils.d.ts.map +1 -1
- package/dest/fixtures/token_utils.js +5 -7
- package/dest/fixtures/utils.d.ts +2 -2
- package/dest/fixtures/utils.d.ts.map +1 -1
- package/dest/fixtures/utils.js +1 -1
- package/dest/forward-compatibility/wallet_rpc_client.d.ts +7 -0
- package/dest/forward-compatibility/wallet_rpc_client.d.ts.map +1 -0
- package/dest/forward-compatibility/wallet_rpc_client.js +15 -0
- package/dest/forward-compatibility/wallet_service.d.ts +3 -0
- package/dest/forward-compatibility/wallet_service.d.ts.map +1 -0
- package/dest/forward-compatibility/wallet_service.js +109 -0
- package/dest/install_legacy_contracts.d.cts +10 -0
- package/dest/install_legacy_contracts.d.cts.map +1 -0
- package/dest/legacy-jest-resolver.d.cts +3 -0
- package/dest/legacy-jest-resolver.d.cts.map +1 -0
- package/dest/shared/cross_chain_test_harness.d.ts +4 -2
- package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
- package/dest/shared/cross_chain_test_harness.js +22 -18
- package/dest/shared/gas_portal_test_harness.d.ts +8 -5
- package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
- package/dest/shared/gas_portal_test_harness.js +19 -10
- package/dest/shared/index.d.ts +2 -1
- package/dest/shared/index.d.ts.map +1 -1
- package/dest/shared/index.js +1 -0
- package/dest/shared/jest_setup.js +41 -1
- package/dest/shared/mock_state_view.d.ts +86 -0
- package/dest/shared/mock_state_view.d.ts.map +1 -0
- package/dest/shared/mock_state_view.js +186 -0
- package/dest/shared/submit-transactions.d.ts +2 -2
- package/dest/shared/submit-transactions.d.ts.map +1 -1
- package/dest/shared/submit-transactions.js +1 -1
- package/dest/shared/uniswap_l1_l2.d.ts +1 -1
- package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
- package/dest/shared/uniswap_l1_l2.js +57 -40
- package/dest/shared/wait_for_l1_to_l2_message.d.ts +13 -0
- package/dest/shared/wait_for_l1_to_l2_message.d.ts.map +1 -0
- package/dest/shared/wait_for_l1_to_l2_message.js +10 -0
- package/dest/simulators/lending_simulator.d.ts +10 -3
- package/dest/simulators/lending_simulator.d.ts.map +1 -1
- package/dest/simulators/lending_simulator.js +26 -14
- package/dest/simulators/token_simulator.d.ts +1 -1
- package/dest/simulators/token_simulator.d.ts.map +1 -1
- package/dest/simulators/token_simulator.js +3 -24
- package/dest/spartan/setup_test_wallets.d.ts +12 -3
- package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
- package/dest/spartan/setup_test_wallets.js +108 -41
- package/dest/spartan/tx_metrics.d.ts +18 -4
- package/dest/spartan/tx_metrics.d.ts.map +1 -1
- package/dest/spartan/tx_metrics.js +74 -21
- package/dest/spartan/utils/bot.d.ts +3 -2
- package/dest/spartan/utils/bot.d.ts.map +1 -1
- package/dest/spartan/utils/bot.js +2 -1
- package/dest/spartan/utils/config.d.ts +11 -28
- package/dest/spartan/utils/config.d.ts.map +1 -1
- package/dest/spartan/utils/config.js +4 -1
- package/dest/spartan/utils/index.d.ts +5 -3
- package/dest/spartan/utils/index.d.ts.map +1 -1
- package/dest/spartan/utils/index.js +5 -1
- package/dest/spartan/utils/k8s.d.ts +3 -1
- package/dest/spartan/utils/k8s.d.ts.map +1 -1
- package/dest/spartan/utils/k8s.js +6 -0
- package/dest/spartan/utils/nodes.d.ts +4 -5
- package/dest/spartan/utils/nodes.d.ts.map +1 -1
- package/dest/spartan/utils/nodes.js +11 -11
- package/dest/spartan/utils/pod_logs.d.ts +25 -0
- package/dest/spartan/utils/pod_logs.d.ts.map +1 -0
- package/dest/spartan/utils/pod_logs.js +74 -0
- package/dest/spartan/utils/scripts.d.ts +18 -4
- package/dest/spartan/utils/scripts.d.ts.map +1 -1
- package/dest/spartan/utils/scripts.js +19 -4
- package/dest/test-wallet/test_wallet.d.ts +85 -0
- package/dest/test-wallet/test_wallet.d.ts.map +1 -0
- package/dest/test-wallet/test_wallet.js +273 -0
- package/dest/test-wallet/utils.d.ts +41 -0
- package/dest/test-wallet/utils.d.ts.map +1 -0
- package/dest/test-wallet/utils.js +66 -0
- package/dest/test-wallet/wallet_worker_script.d.ts +2 -0
- package/dest/test-wallet/wallet_worker_script.d.ts.map +1 -0
- package/dest/test-wallet/wallet_worker_script.js +53 -0
- package/dest/test-wallet/worker_wallet.d.ts +53 -0
- package/dest/test-wallet/worker_wallet.d.ts.map +1 -0
- package/dest/test-wallet/worker_wallet.js +155 -0
- package/dest/test-wallet/worker_wallet_schema.d.ts +160 -0
- package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -0
- package/dest/test-wallet/worker_wallet_schema.js +22 -0
- package/package.json +52 -45
- package/src/bench/client_flows/benchmark.ts +19 -0
- package/src/bench/client_flows/client_flows_benchmark.ts +64 -49
- package/src/bench/client_flows/config.ts +9 -1
- package/src/bench/utils.ts +10 -4
- package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +52 -25
- package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +56 -19
- package/src/e2e_deploy_contract/deploy_test.ts +6 -5
- package/src/e2e_epochs/epochs_test.ts +166 -68
- package/src/e2e_fees/bridging_race.notest.ts +1 -1
- package/src/e2e_fees/fees_test.ts +57 -32
- package/src/e2e_nested_contract/nested_contract_test.ts +10 -6
- package/src/e2e_p2p/inactivity_slash_test.ts +8 -7
- package/src/e2e_p2p/p2p_network.ts +93 -49
- package/src/e2e_p2p/reqresp/utils.ts +84 -17
- package/src/e2e_p2p/shared.ts +109 -65
- package/src/e2e_storage_proof/fixtures/storage_proof.json +915 -0
- package/src/e2e_storage_proof/fixtures/storage_proof_fetcher.ts +190 -0
- package/src/e2e_storage_proof/fixtures/storage_proof_fixture.ts +173 -0
- package/src/e2e_token_contract/token_contract_test.ts +38 -11
- package/src/fixtures/authwit_proxy.ts +54 -0
- package/src/fixtures/dumps/epoch_proof_result.json +1 -1
- package/src/fixtures/e2e_prover_test.ts +49 -56
- package/src/fixtures/elu_monitor.ts +126 -0
- package/src/fixtures/fixtures.ts +93 -0
- package/src/fixtures/get_bb_config.ts +7 -6
- package/src/fixtures/ha_setup.ts +188 -0
- package/src/fixtures/index.ts +1 -0
- package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
- package/src/fixtures/setup.ts +272 -233
- package/src/fixtures/setup_p2p_test.ts +37 -32
- package/src/fixtures/token_utils.ts +3 -3
- package/src/fixtures/utils.ts +2 -0
- package/src/forward-compatibility/wallet_rpc_client.ts +14 -0
- package/src/forward-compatibility/wallet_service.ts +104 -0
- package/src/guides/up_quick_start.sh +3 -5
- package/src/install_legacy_contracts.cjs +75 -0
- package/src/legacy-jest-resolver.cjs +112 -0
- package/src/shared/cross_chain_test_harness.ts +27 -13
- package/src/shared/gas_portal_test_harness.ts +21 -11
- package/src/shared/index.ts +1 -0
- package/src/shared/jest_setup.ts +51 -1
- package/src/shared/mock_state_view.ts +188 -0
- package/src/shared/submit-transactions.ts +3 -2
- package/src/shared/uniswap_l1_l2.ts +103 -54
- package/src/shared/wait_for_l1_to_l2_message.ts +23 -0
- package/src/simulators/lending_simulator.ts +32 -14
- package/src/simulators/token_simulator.ts +6 -30
- package/src/spartan/setup_test_wallets.ts +146 -35
- package/src/spartan/tx_metrics.ts +82 -24
- package/src/spartan/utils/bot.ts +4 -1
- package/src/spartan/utils/config.ts +3 -0
- package/src/spartan/utils/index.ts +8 -1
- package/src/spartan/utils/k8s.ts +8 -0
- package/src/spartan/utils/nodes.ts +17 -12
- package/src/spartan/utils/pod_logs.ts +99 -0
- package/src/spartan/utils/scripts.ts +43 -7
- package/src/test-wallet/test_wallet.ts +376 -0
- package/src/test-wallet/utils.ts +108 -0
- package/src/test-wallet/wallet_worker_script.ts +63 -0
- package/src/test-wallet/worker_wallet.ts +218 -0
- package/src/test-wallet/worker_wallet_schema.ts +13 -0
package/src/fixtures/fixtures.ts
CHANGED
|
@@ -1,5 +1,88 @@
|
|
|
1
|
+
import type { AztecNode } from '@aztec/aztec.js/node';
|
|
2
|
+
import type { GasFees } from '@aztec/stdlib/gas';
|
|
3
|
+
|
|
1
4
|
export const METRICS_PORT = 4318;
|
|
2
5
|
|
|
6
|
+
/** Default fee padding applied to predicted min fees in e2e tests. */
|
|
7
|
+
export const DEFAULT_MIN_FEE_PADDING = 5;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Large fee padding for txs that may be mined significantly later than when they were created,
|
|
11
|
+
* such as cloned txs in throughput/capacity benchmarks, where fees may spike between creation and mining.
|
|
12
|
+
*/
|
|
13
|
+
export const LARGE_MIN_FEE_PADDING = 15;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Fee padding used by tests running under proposer pipelining. Under pipelining the fee-asset
|
|
17
|
+
* price modifier evolves faster across the build/publish gap, so client-set maxFeesPerGas (sized
|
|
18
|
+
* for the default 5x padding) was getting bumped past by the time the tx mined a few slots later.
|
|
19
|
+
* Observed worst case in CI: fee evolved ~20x between PXE snapshot and inclusion, exceeding even
|
|
20
|
+
* LARGE_MIN_FEE_PADDING (15x).
|
|
21
|
+
*/
|
|
22
|
+
export const PIPELINED_FEE_PADDING = 30;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Setup option preset that opts a test into proposer pipelining. Use with `setup()`:
|
|
26
|
+
*
|
|
27
|
+
* await setup(N, { ...PIPELINING_SETUP_OPTS, ...otherOpts });
|
|
28
|
+
*
|
|
29
|
+
* The preset sets:
|
|
30
|
+
* - `inboxLag: 2` so the sequencer sources L1->L2 messages from checkpoint N-1 (already sealed),
|
|
31
|
+
* avoiding `L1ToL2MessagesNotReadyError` when building for slot N during slot N-1.
|
|
32
|
+
* - `minTxsPerBlock: 0` so empty checkpoints land even when a tx arrives late in the build window
|
|
33
|
+
* (otherwise the chain stalls on alternating slots).
|
|
34
|
+
* - `aztecSlotDuration: 12` / `ethereumSlotDuration: 4` so the pipelined cycle fits inside the
|
|
35
|
+
* default 300s Jest hook budget. Tests that depend on the env-default 72s/12s should override.
|
|
36
|
+
* - `walletMinFeePadding: PIPELINED_FEE_PADDING` (30x) to absorb the wider fee evolution window.
|
|
37
|
+
*/
|
|
38
|
+
export const PIPELINING_SETUP_OPTS = {
|
|
39
|
+
inboxLag: 2,
|
|
40
|
+
minTxsPerBlock: 0,
|
|
41
|
+
aztecSlotDuration: 12,
|
|
42
|
+
ethereumSlotDuration: 4,
|
|
43
|
+
walletMinFeePadding: PIPELINED_FEE_PADDING,
|
|
44
|
+
} as const;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Setup option preset that opts a test into the deterministic AutomineSequencer path.
|
|
48
|
+
* Use only for single-sequencer tests that don't exercise block-building or consensus
|
|
49
|
+
* (e.g. e2e_token, e2e_amm, e2e_authwit). Not compatible with `e2e_p2p/*`,
|
|
50
|
+
* `e2e_epochs/*`, `e2e_slashing/*`, `e2e_block_building`, or any multi-validator suite.
|
|
51
|
+
*
|
|
52
|
+
* await setup(N, { ...AUTOMINE_E2E_OPTS, ...otherOpts });
|
|
53
|
+
*
|
|
54
|
+
* The preset:
|
|
55
|
+
* - Swaps the production Sequencer for an AutomineSequencer that builds one block per
|
|
56
|
+
* submitted tx, publishes synchronously to L1, and owns all time control through a
|
|
57
|
+
* serial queue (see `sequencer-client/src/sequencer/automine/automine_sequencer.ts`).
|
|
58
|
+
* - Disables the validator client and AnvilTestWatcher (the AutomineSequencer needs
|
|
59
|
+
* neither).
|
|
60
|
+
* - Uses `inboxLag: 1` (synchronous) since the AutomineSequencer publishes one block per tx.
|
|
61
|
+
* - Switches anvil into automine mode at setup time (no interval mining); each L1 tx
|
|
62
|
+
* mines an L1 block immediately.
|
|
63
|
+
*
|
|
64
|
+
* Requires `aztecTargetCommitteeSize: 0`, which is the e2e default at `setup.ts:317`.
|
|
65
|
+
*/
|
|
66
|
+
export const AUTOMINE_E2E_OPTS = {
|
|
67
|
+
useAutomineSequencer: true,
|
|
68
|
+
disableAnvilTestWatcher: true,
|
|
69
|
+
inboxLag: 1,
|
|
70
|
+
minTxsPerBlock: 0,
|
|
71
|
+
aztecSlotDuration: 12,
|
|
72
|
+
ethereumSlotDuration: 4,
|
|
73
|
+
walletMinFeePadding: PIPELINED_FEE_PADDING,
|
|
74
|
+
} as const;
|
|
75
|
+
|
|
76
|
+
/** Returns worst-case predicted min fees with padding applied, mirroring the BaseWallet pattern. */
|
|
77
|
+
export async function getPaddedMaxFeesPerGas(node: AztecNode, padding = DEFAULT_MIN_FEE_PADDING): Promise<GasFees> {
|
|
78
|
+
const predicted = await node.getPredictedMinFees();
|
|
79
|
+
const worstCase =
|
|
80
|
+
predicted.length > 0
|
|
81
|
+
? predicted.reduce((worst, fees) => (fees.feePerL2Gas > worst.feePerL2Gas ? fees : worst))
|
|
82
|
+
: await node.getCurrentMinFees();
|
|
83
|
+
return worstCase.mul(1 + padding);
|
|
84
|
+
}
|
|
85
|
+
|
|
3
86
|
export const shouldCollectMetrics = () => {
|
|
4
87
|
if (process.env.COLLECT_METRICS) {
|
|
5
88
|
return METRICS_PORT;
|
|
@@ -7,6 +90,16 @@ export const shouldCollectMetrics = () => {
|
|
|
7
90
|
return undefined;
|
|
8
91
|
};
|
|
9
92
|
|
|
93
|
+
/** Returns the boot node UDP port from environment variable or default value. */
|
|
94
|
+
export function getBootNodeUdpPort(): number {
|
|
95
|
+
return process.env.BOOT_NODE_UDP_PORT ? parseInt(process.env.BOOT_NODE_UDP_PORT, 10) : 4500;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Returns the anvil port from environment variable or default value. */
|
|
99
|
+
export function getAnvilPort(): number {
|
|
100
|
+
return process.env.ANVIL_PORT ? parseInt(process.env.ANVIL_PORT, 10) : 8545;
|
|
101
|
+
}
|
|
102
|
+
|
|
10
103
|
export const TEST_PEER_CHECK_INTERVAL_MS = 1000;
|
|
11
104
|
export const TEST_MAX_PENDING_TX_POOL_COUNT = 10_000; // Number of max pending TXs ~ 1.56GB
|
|
12
105
|
|
|
@@ -13,8 +13,10 @@ const {
|
|
|
13
13
|
BB_SKIP_CLEANUP = '',
|
|
14
14
|
TEMP_DIR = tmpdir(),
|
|
15
15
|
BB_WORKING_DIRECTORY = '',
|
|
16
|
-
BB_NUM_IVC_VERIFIERS = '
|
|
16
|
+
BB_NUM_IVC_VERIFIERS = '8',
|
|
17
17
|
BB_IVC_CONCURRENCY = '1',
|
|
18
|
+
BB_CHONK_VERIFY_MAX_BATCH = '16',
|
|
19
|
+
BB_CHONK_VERIFY_BATCH_CONCURRENCY = '6',
|
|
18
20
|
} = process.env;
|
|
19
21
|
|
|
20
22
|
export const getBBConfig = async (
|
|
@@ -41,16 +43,15 @@ export const getBBConfig = async (
|
|
|
41
43
|
const bbSkipCleanup = ['1', 'true'].includes(BB_SKIP_CLEANUP);
|
|
42
44
|
const cleanup = bbSkipCleanup ? () => Promise.resolve() : () => tryRmDir(directoryToCleanup);
|
|
43
45
|
|
|
44
|
-
const numIvcVerifiers = Number(BB_NUM_IVC_VERIFIERS);
|
|
45
|
-
const ivcConcurrency = Number(BB_IVC_CONCURRENCY);
|
|
46
|
-
|
|
47
46
|
return {
|
|
48
47
|
bbSkipCleanup,
|
|
49
48
|
bbBinaryPath,
|
|
50
49
|
bbWorkingDirectory,
|
|
51
50
|
cleanup,
|
|
52
|
-
numConcurrentIVCVerifiers:
|
|
53
|
-
bbIVCConcurrency:
|
|
51
|
+
numConcurrentIVCVerifiers: Number(BB_NUM_IVC_VERIFIERS),
|
|
52
|
+
bbIVCConcurrency: Number(BB_IVC_CONCURRENCY),
|
|
53
|
+
bbChonkVerifyMaxBatch: Number(BB_CHONK_VERIFY_MAX_BATCH),
|
|
54
|
+
bbChonkVerifyConcurrency: Number(BB_CHONK_VERIFY_BATCH_CONCURRENCY),
|
|
54
55
|
};
|
|
55
56
|
} catch (err) {
|
|
56
57
|
logger.error(`Native BB not available, error: ${err}`);
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { EthAddress } from '@aztec/aztec.js/addresses';
|
|
2
|
+
import { Fr } from '@aztec/aztec.js/fields';
|
|
3
|
+
import type { Logger } from '@aztec/aztec.js/log';
|
|
4
|
+
import { SecretValue } from '@aztec/foundation/config';
|
|
5
|
+
|
|
6
|
+
import { Pool } from 'pg';
|
|
7
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Configuration for HA database connection
|
|
11
|
+
*/
|
|
12
|
+
export interface HADatabaseConfig {
|
|
13
|
+
/** PostgreSQL connection URL */
|
|
14
|
+
databaseUrl: SecretValue<string>;
|
|
15
|
+
/** Node ID for HA coordination */
|
|
16
|
+
nodeId: string;
|
|
17
|
+
/** Enable HA signing */
|
|
18
|
+
haSigningEnabled: boolean;
|
|
19
|
+
/** Polling interval in ms */
|
|
20
|
+
pollingIntervalMs: number;
|
|
21
|
+
/** Signing timeout in ms */
|
|
22
|
+
signingTimeoutMs: number;
|
|
23
|
+
/** Max stuck duties age in ms */
|
|
24
|
+
maxStuckDutiesAgeMs: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get database configuration from environment variables
|
|
29
|
+
*/
|
|
30
|
+
export function createHADatabaseConfig(nodeId: string): HADatabaseConfig {
|
|
31
|
+
const databaseUrl = new SecretValue(
|
|
32
|
+
process.env.DATABASE_URL || 'postgresql://aztec:aztec@localhost:5432/aztec_ha_test',
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
databaseUrl,
|
|
37
|
+
nodeId,
|
|
38
|
+
haSigningEnabled: true,
|
|
39
|
+
pollingIntervalMs: 100,
|
|
40
|
+
signingTimeoutMs: 3000,
|
|
41
|
+
maxStuckDutiesAgeMs: 72000,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Setup PostgreSQL database connection pool for HA tests
|
|
47
|
+
*
|
|
48
|
+
* Note: Database migrations should be run separately before starting tests,
|
|
49
|
+
* either via docker-compose entrypoint or manually with: aztec migrate-ha-db up
|
|
50
|
+
*/
|
|
51
|
+
export function setupHADatabase(databaseUrl: string, logger?: Logger): Pool {
|
|
52
|
+
try {
|
|
53
|
+
// Create connection pool for test usage
|
|
54
|
+
// Migrations are already run by docker-compose entrypoint before tests start
|
|
55
|
+
const pool = new Pool({ connectionString: databaseUrl });
|
|
56
|
+
|
|
57
|
+
logger?.info('Connected to HA database (migrations should already be applied)');
|
|
58
|
+
|
|
59
|
+
return pool;
|
|
60
|
+
} catch (error) {
|
|
61
|
+
logger?.error(`Failed to connect to HA database: ${error}`);
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Clean up HA database - drop all tables
|
|
68
|
+
* Use this between tests to ensure clean state
|
|
69
|
+
*/
|
|
70
|
+
export async function cleanupHADatabase(pool: Pool, logger?: Logger): Promise<void> {
|
|
71
|
+
try {
|
|
72
|
+
// Drop all HA tables
|
|
73
|
+
await pool.query('DROP TABLE IF EXISTS validator_duties CASCADE');
|
|
74
|
+
await pool.query('DROP TABLE IF EXISTS schema_version CASCADE');
|
|
75
|
+
// Drop migration tracking table (node-pg-migrate uses 'pgmigrations' by default)
|
|
76
|
+
// This ensures migrations will run fresh on next startup
|
|
77
|
+
await pool.query('DROP TABLE IF EXISTS pgmigrations CASCADE');
|
|
78
|
+
|
|
79
|
+
logger?.info('HA database cleaned up successfully');
|
|
80
|
+
} catch (error) {
|
|
81
|
+
logger?.error(`Failed to cleanup HA database: ${error}`);
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Query validator duties from the database
|
|
88
|
+
*/
|
|
89
|
+
export async function getValidatorDuties(
|
|
90
|
+
pool: Pool,
|
|
91
|
+
slot: bigint,
|
|
92
|
+
dutyType?: 'ATTESTATION' | 'BLOCK_PROPOSAL' | 'GOVERNANCE_VOTE' | 'SLASHING_VOTE',
|
|
93
|
+
): Promise<
|
|
94
|
+
Array<{
|
|
95
|
+
slot: string;
|
|
96
|
+
dutyType: string;
|
|
97
|
+
validatorAddress: string;
|
|
98
|
+
nodeId: string;
|
|
99
|
+
startedAt: Date;
|
|
100
|
+
completedAt: Date | undefined;
|
|
101
|
+
}>
|
|
102
|
+
> {
|
|
103
|
+
const query = dutyType
|
|
104
|
+
? 'SELECT slot, duty_type, validator_address, node_id, started_at, completed_at FROM validator_duties WHERE slot = $1 AND duty_type = $2 ORDER BY started_at'
|
|
105
|
+
: 'SELECT slot, duty_type, validator_address, node_id, started_at, completed_at FROM validator_duties WHERE slot = $1 ORDER BY started_at';
|
|
106
|
+
|
|
107
|
+
const params = dutyType ? [slot.toString(), dutyType] : [slot.toString()];
|
|
108
|
+
|
|
109
|
+
const result = await pool.query<{
|
|
110
|
+
slot: string;
|
|
111
|
+
duty_type: string;
|
|
112
|
+
validator_address: string;
|
|
113
|
+
node_id: string;
|
|
114
|
+
started_at: Date;
|
|
115
|
+
completed_at: Date | undefined;
|
|
116
|
+
}>(query, params);
|
|
117
|
+
|
|
118
|
+
return result.rows.map(row => ({
|
|
119
|
+
slot: row.slot,
|
|
120
|
+
dutyType: row.duty_type,
|
|
121
|
+
validatorAddress: row.validator_address,
|
|
122
|
+
nodeId: row.node_id,
|
|
123
|
+
startedAt: row.started_at,
|
|
124
|
+
completedAt: row.completed_at,
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Convert private keys to Ethereum addresses
|
|
130
|
+
*/
|
|
131
|
+
export function getAddressesFromPrivateKeys(privateKeys: `0x${string}`[]): string[] {
|
|
132
|
+
return privateKeys.map(pk => {
|
|
133
|
+
const account = privateKeyToAccount(pk);
|
|
134
|
+
return account.address;
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Create initial validators from private keys for L1 contract deployment
|
|
140
|
+
*/
|
|
141
|
+
export function createInitialValidatorsFromPrivateKeys(attesterPrivateKeys: `0x${string}`[]): Array<{
|
|
142
|
+
attester: EthAddress;
|
|
143
|
+
withdrawer: EthAddress;
|
|
144
|
+
privateKey: `0x${string}`;
|
|
145
|
+
bn254SecretKey: SecretValue<bigint>;
|
|
146
|
+
}> {
|
|
147
|
+
return attesterPrivateKeys.map(pk => {
|
|
148
|
+
const account = privateKeyToAccount(pk);
|
|
149
|
+
return {
|
|
150
|
+
attester: EthAddress.fromString(account.address),
|
|
151
|
+
withdrawer: EthAddress.fromString(account.address),
|
|
152
|
+
privateKey: pk,
|
|
153
|
+
bn254SecretKey: new SecretValue(Fr.random().toBigInt()),
|
|
154
|
+
};
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Verify no duplicate attestations per validator (HA coordination check)
|
|
160
|
+
* Groups duties by validator address and verifies each validator attested exactly once
|
|
161
|
+
*/
|
|
162
|
+
export function verifyNoDuplicateAttestations(
|
|
163
|
+
attestationDuties: Array<{
|
|
164
|
+
validatorAddress: string;
|
|
165
|
+
nodeId: string;
|
|
166
|
+
completedAt: Date | undefined;
|
|
167
|
+
}>,
|
|
168
|
+
logger?: Logger,
|
|
169
|
+
): Map<string, typeof attestationDuties> {
|
|
170
|
+
const dutiesByValidator = new Map<string, typeof attestationDuties>();
|
|
171
|
+
for (const duty of attestationDuties) {
|
|
172
|
+
const existing = dutiesByValidator.get(duty.validatorAddress) || [];
|
|
173
|
+
existing.push(duty);
|
|
174
|
+
dutiesByValidator.set(duty.validatorAddress, existing);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
for (const [validatorAddress, validatorDuties] of dutiesByValidator.entries()) {
|
|
178
|
+
if (validatorDuties.length !== 1) {
|
|
179
|
+
throw new Error(`Validator ${validatorAddress} attested ${validatorDuties.length} times (expected exactly once)`);
|
|
180
|
+
}
|
|
181
|
+
if (!validatorDuties[0].completedAt) {
|
|
182
|
+
throw new Error(`Validator ${validatorAddress} attestation duty not completed`);
|
|
183
|
+
}
|
|
184
|
+
logger?.info(`Validator ${validatorAddress} attested once via node ${validatorDuties[0].nodeId}`);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return dutiesByValidator;
|
|
188
|
+
}
|
package/src/fixtures/index.ts
CHANGED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { DefaultAccountContract } from '@aztec/accounts/defaults';
|
|
2
|
+
import type { ContractArtifact } from '@aztec/aztec.js/abi';
|
|
3
|
+
import type { AuthWitnessProvider } from '@aztec/aztec.js/account';
|
|
4
|
+
import type { CompleteAddress } from '@aztec/aztec.js/addresses';
|
|
5
|
+
import { AuthWitness } from '@aztec/aztec.js/authorization';
|
|
6
|
+
import type { Fr } from '@aztec/aztec.js/fields';
|
|
7
|
+
import { Schnorr } from '@aztec/foundation/crypto/schnorr';
|
|
8
|
+
import { GrumpkinScalar } from '@aztec/foundation/curves/grumpkin';
|
|
9
|
+
import { SchnorrHardcodedAccountContractArtifact } from '@aztec/noir-contracts.js/SchnorrHardcodedAccount';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The private key that matches the hardcoded public key in the SchnorrHardcodedAccountContract.
|
|
13
|
+
* The corresponding public key is baked into the Noir contract as a global constant.
|
|
14
|
+
*/
|
|
15
|
+
export const SCHNORR_HARDCODED_PRIVATE_KEY = GrumpkinScalar.fromHexString(
|
|
16
|
+
'0xd35d743ac0dfe3d6dbe6be8c877cb524a00ab1e3d52d7bada095dfc8894ccfa',
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Account contract backed by the SchnorrHardcodedAccount Noir contract.
|
|
21
|
+
* This contract verifies Schnorr signatures against a public key that is hardcoded
|
|
22
|
+
* in the contract artifact (not stored in a note), so it does not require on-chain
|
|
23
|
+
* deployment or initialization. Useful for tests that need a working account without
|
|
24
|
+
* mining any blocks.
|
|
25
|
+
*/
|
|
26
|
+
export class SchnorrHardcodedKeyAccountContract extends DefaultAccountContract {
|
|
27
|
+
constructor(private privateKey: GrumpkinScalar = SCHNORR_HARDCODED_PRIVATE_KEY) {
|
|
28
|
+
super();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
override getContractArtifact(): Promise<ContractArtifact> {
|
|
32
|
+
return Promise.resolve(SchnorrHardcodedAccountContractArtifact);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
getInitializationFunctionAndArgs() {
|
|
36
|
+
return Promise.resolve(undefined);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
getAuthWitnessProvider(_address: CompleteAddress): AuthWitnessProvider {
|
|
40
|
+
const privateKey = this.privateKey;
|
|
41
|
+
return {
|
|
42
|
+
async createAuthWit(messageHash: Fr): Promise<AuthWitness> {
|
|
43
|
+
const signer = new Schnorr();
|
|
44
|
+
const signature = await signer.constructSignature(messageHash, privateKey);
|
|
45
|
+
return new AuthWitness(messageHash, signature.toLimbFields());
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|