@aztec/end-to-end 0.0.1-commit.d431d1c → 0.0.1-commit.d939eb5aa
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/client_flows_benchmark.d.ts +2 -2
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.js +25 -17
- 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 +5 -4
- package/dest/bench/utils.d.ts.map +1 -1
- package/dest/bench/utils.js +13 -8
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +6 -3
- 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 +28 -19
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +2 -2
- 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 +3 -2
- package/dest/e2e_deploy_contract/deploy_test.d.ts +2 -2
- package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.d.ts +17 -7
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +92 -42
- package/dest/e2e_fees/bridging_race.notest.js +1 -1
- package/dest/e2e_fees/fees_test.d.ts +2 -2
- package/dest/e2e_fees/fees_test.d.ts.map +1 -1
- package/dest/e2e_fees/fees_test.js +25 -18
- package/dest/e2e_l1_publisher/write_json.d.ts +4 -3
- package/dest/e2e_l1_publisher/write_json.d.ts.map +1 -1
- package/dest/e2e_l1_publisher/write_json.js +1 -7
- package/dest/e2e_nested_contract/nested_contract_test.js +4 -6
- package/dest/e2e_p2p/inactivity_slash_test.js +3 -3
- package/dest/e2e_p2p/p2p_network.d.ts +9 -10
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +43 -21
- package/dest/e2e_p2p/reqresp/utils.d.ts +22 -0
- package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -0
- package/dest/e2e_p2p/reqresp/utils.js +190 -0
- package/dest/e2e_p2p/shared.d.ts +30 -12
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +62 -60
- 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 +4 -2
- package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
- package/dest/e2e_token_contract/token_contract_test.js +20 -10
- 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 +7 -6
- package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
- package/dest/fixtures/e2e_prover_test.js +40 -49
- 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 +5 -1
- package/dest/fixtures/fixtures.d.ts.map +1 -1
- package/dest/fixtures/fixtures.js +6 -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/setup.d.ts +57 -31
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +105 -178
- package/dest/fixtures/setup_p2p_test.d.ts +18 -11
- package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.js +43 -32
- 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 +7 -6
- 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 +3 -4
- package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
- package/dest/shared/cross_chain_test_harness.js +24 -24
- package/dest/shared/gas_portal_test_harness.js +3 -3
- 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 +4 -4
- package/dest/shared/submit-transactions.d.ts.map +1 -1
- package/dest/shared/submit-transactions.js +9 -11
- 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 +27 -28
- package/dest/simulators/lending_simulator.d.ts +1 -1
- package/dest/simulators/lending_simulator.d.ts.map +1 -1
- package/dest/simulators/lending_simulator.js +6 -6
- 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 +130 -42
- package/dest/spartan/tx_metrics.d.ts +38 -2
- package/dest/spartan/tx_metrics.d.ts.map +1 -1
- package/dest/spartan/tx_metrics.js +179 -5
- package/dest/spartan/utils/bot.d.ts +28 -0
- package/dest/spartan/utils/bot.d.ts.map +1 -0
- package/dest/spartan/utils/bot.js +142 -0
- package/dest/spartan/utils/chaos.d.ts +79 -0
- package/dest/spartan/utils/chaos.d.ts.map +1 -0
- package/dest/spartan/utils/chaos.js +142 -0
- package/dest/spartan/utils/clients.d.ts +39 -0
- package/dest/spartan/utils/clients.d.ts.map +1 -0
- package/dest/spartan/utils/clients.js +90 -0
- package/dest/spartan/utils/config.d.ts +45 -0
- package/dest/spartan/utils/config.d.ts.map +1 -0
- package/dest/spartan/utils/config.js +23 -0
- package/dest/spartan/utils/health.d.ts +63 -0
- package/dest/spartan/utils/health.d.ts.map +1 -0
- package/dest/spartan/utils/health.js +202 -0
- package/dest/spartan/utils/helm.d.ts +15 -0
- package/dest/spartan/utils/helm.d.ts.map +1 -0
- package/dest/spartan/utils/helm.js +47 -0
- package/dest/spartan/utils/index.d.ts +11 -0
- package/dest/spartan/utils/index.d.ts.map +1 -0
- package/dest/spartan/utils/index.js +22 -0
- package/dest/spartan/utils/k8s.d.ts +128 -0
- package/dest/spartan/utils/k8s.d.ts.map +1 -0
- package/dest/spartan/utils/k8s.js +381 -0
- package/dest/spartan/utils/nodes.d.ts +40 -0
- package/dest/spartan/utils/nodes.d.ts.map +1 -0
- package/dest/spartan/utils/nodes.js +461 -0
- 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 +30 -0
- package/dest/spartan/utils/scripts.d.ts.map +1 -0
- package/dest/spartan/utils/scripts.js +81 -0
- package/dest/spartan/utils.d.ts +2 -260
- package/dest/spartan/utils.d.ts.map +1 -1
- package/dest/spartan/utils.js +1 -942
- package/dest/test-wallet/test_wallet.d.ts +84 -0
- package/dest/test-wallet/test_wallet.d.ts.map +1 -0
- package/dest/test-wallet/test_wallet.js +249 -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 +71 -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 +48 -0
- package/dest/test-wallet/worker_wallet.d.ts +52 -0
- package/dest/test-wallet/worker_wallet.d.ts.map +1 -0
- package/dest/test-wallet/worker_wallet.js +151 -0
- package/dest/test-wallet/worker_wallet_schema.d.ts +279 -0
- package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -0
- package/dest/test-wallet/worker_wallet_schema.js +10 -0
- package/package.json +46 -43
- package/src/bench/client_flows/client_flows_benchmark.ts +36 -36
- package/src/bench/client_flows/config.ts +9 -1
- package/src/bench/utils.ts +15 -8
- package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +36 -29
- package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +7 -8
- package/src/e2e_deploy_contract/deploy_test.ts +3 -3
- package/src/e2e_epochs/epochs_test.ts +140 -92
- package/src/e2e_fees/bridging_race.notest.ts +2 -5
- package/src/e2e_fees/fees_test.ts +29 -41
- package/src/e2e_l1_publisher/write_json.ts +3 -8
- package/src/e2e_nested_contract/nested_contract_test.ts +7 -7
- package/src/e2e_p2p/inactivity_slash_test.ts +7 -7
- package/src/e2e_p2p/p2p_network.ts +71 -44
- package/src/e2e_p2p/reqresp/utils.ts +256 -0
- package/src/e2e_p2p/shared.ts +92 -80
- 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 +27 -12
- 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 -63
- package/src/fixtures/elu_monitor.ts +126 -0
- package/src/fixtures/fixtures.ts +10 -0
- package/src/fixtures/get_bb_config.ts +7 -6
- package/src/fixtures/ha_setup.ts +186 -0
- package/src/fixtures/index.ts +1 -0
- package/src/fixtures/setup.ts +144 -244
- package/src/fixtures/setup_p2p_test.ts +48 -52
- package/src/fixtures/token_utils.ts +7 -6
- package/src/guides/up_quick_start.sh +3 -3
- package/src/legacy-jest-resolver.cjs +135 -0
- package/src/shared/cross_chain_test_harness.ts +24 -34
- package/src/shared/gas_portal_test_harness.ts +2 -2
- 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 +11 -16
- package/src/shared/uniswap_l1_l2.ts +49 -51
- package/src/simulators/lending_simulator.ts +10 -6
- package/src/simulators/token_simulator.ts +6 -30
- package/src/spartan/setup_test_wallets.ts +183 -26
- package/src/spartan/tx_metrics.ts +153 -8
- package/src/spartan/utils/bot.ts +188 -0
- package/src/spartan/utils/chaos.ts +253 -0
- package/src/spartan/utils/clients.ts +100 -0
- package/src/spartan/utils/config.ts +29 -0
- package/src/spartan/utils/health.ts +255 -0
- package/src/spartan/utils/helm.ts +84 -0
- package/src/spartan/utils/index.ts +71 -0
- package/src/spartan/utils/k8s.ts +535 -0
- package/src/spartan/utils/nodes.ts +543 -0
- package/src/spartan/utils/pod_logs.ts +99 -0
- package/src/spartan/utils/scripts.ts +99 -0
- package/src/spartan/utils.ts +1 -1246
- package/src/test-wallet/test_wallet.ts +351 -0
- package/src/test-wallet/utils.ts +112 -0
- package/src/test-wallet/wallet_worker_script.ts +60 -0
- package/src/test-wallet/worker_wallet.ts +214 -0
- package/src/test-wallet/worker_wallet_schema.ts +13 -0
|
@@ -58,6 +58,7 @@ export class P2PInactivityTest {
|
|
|
58
58
|
basePort: BOOT_NODE_UDP_PORT,
|
|
59
59
|
startProverNode: true,
|
|
60
60
|
initialConfig: {
|
|
61
|
+
anvilSlotsInAnEpoch: 4,
|
|
61
62
|
proverNodeConfig: { proverNodeEpochProvingDelayMs: AZTEC_SLOT_DURATION * 1000 },
|
|
62
63
|
aztecTargetCommitteeSize: COMMITTEE_SIZE,
|
|
63
64
|
aztecSlotDuration: AZTEC_SLOT_DURATION,
|
|
@@ -66,7 +67,6 @@ export class P2PInactivityTest {
|
|
|
66
67
|
listenAddress: '127.0.0.1',
|
|
67
68
|
minTxsPerBlock: 0,
|
|
68
69
|
aztecEpochDuration: EPOCH_DURATION,
|
|
69
|
-
validatorReexecute: false,
|
|
70
70
|
sentinelEnabled: true,
|
|
71
71
|
slashingQuorum: SLASHING_QUORUM,
|
|
72
72
|
slashingRoundSizeInEpochs: SLASHING_ROUND_SIZE_IN_EPOCHS,
|
|
@@ -98,17 +98,17 @@ export class P2PInactivityTest {
|
|
|
98
98
|
this.rollup = rollup;
|
|
99
99
|
|
|
100
100
|
if (!this.keepInitialNode) {
|
|
101
|
-
await this.test.ctx.aztecNodeService
|
|
101
|
+
await this.test.ctx.aztecNodeService.stop();
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
// Create all active nodes
|
|
105
105
|
this.activeNodes = await createNodes(
|
|
106
106
|
this.test.ctx.aztecNodeConfig,
|
|
107
|
-
this.test.ctx.dateProvider
|
|
107
|
+
this.test.ctx.dateProvider,
|
|
108
108
|
this.test.bootstrapNodeEnr,
|
|
109
109
|
NUM_NODES - this.inactiveNodeCount - Number(this.keepInitialNode),
|
|
110
110
|
BOOT_NODE_UDP_PORT,
|
|
111
|
-
this.test.
|
|
111
|
+
this.test.genesis,
|
|
112
112
|
this.dataDir,
|
|
113
113
|
undefined,
|
|
114
114
|
Number(this.keepInitialNode),
|
|
@@ -118,18 +118,18 @@ export class P2PInactivityTest {
|
|
|
118
118
|
const inactiveConfig = { ...this.test.ctx.aztecNodeConfig, dontStartSequencer: true };
|
|
119
119
|
this.inactiveNodes = await createNodes(
|
|
120
120
|
inactiveConfig,
|
|
121
|
-
this.test.ctx.dateProvider
|
|
121
|
+
this.test.ctx.dateProvider,
|
|
122
122
|
this.test.bootstrapNodeEnr,
|
|
123
123
|
this.inactiveNodeCount,
|
|
124
124
|
BOOT_NODE_UDP_PORT,
|
|
125
|
-
this.test.
|
|
125
|
+
this.test.genesis,
|
|
126
126
|
this.dataDir,
|
|
127
127
|
undefined,
|
|
128
128
|
NUM_NODES - this.inactiveNodeCount,
|
|
129
129
|
);
|
|
130
130
|
|
|
131
131
|
this.nodes = [
|
|
132
|
-
...(this.keepInitialNode ? [this.test.ctx.aztecNodeService
|
|
132
|
+
...(this.keepInitialNode ? [this.test.ctx.aztecNodeService] : []),
|
|
133
133
|
...this.activeNodes,
|
|
134
134
|
...this.inactiveNodes,
|
|
135
135
|
];
|
|
@@ -3,16 +3,11 @@ import type { AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
|
|
|
3
3
|
import { AztecAddress, EthAddress } from '@aztec/aztec.js/addresses';
|
|
4
4
|
import { Fr } from '@aztec/aztec.js/fields';
|
|
5
5
|
import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config';
|
|
6
|
-
import {
|
|
7
|
-
type EmpireSlashingProposerContract,
|
|
8
|
-
GSEContract,
|
|
9
|
-
RollupContract,
|
|
10
|
-
type TallySlashingProposerContract,
|
|
11
|
-
} from '@aztec/ethereum/contracts';
|
|
6
|
+
import { GSEContract, RollupContract, type SlashingProposerContract } from '@aztec/ethereum/contracts';
|
|
12
7
|
import type { Operator } from '@aztec/ethereum/deploy-aztec-l1-contracts';
|
|
13
8
|
import { deployL1Contract } from '@aztec/ethereum/deploy-l1-contract';
|
|
14
9
|
import { MultiAdderArtifact } from '@aztec/ethereum/l1-artifacts';
|
|
15
|
-
import {
|
|
10
|
+
import { createL1TxUtils } from '@aztec/ethereum/l1-tx-utils';
|
|
16
11
|
import { ChainMonitor } from '@aztec/ethereum/test';
|
|
17
12
|
import type { ExtendedViemWalletClient, ViemClient } from '@aztec/ethereum/types';
|
|
18
13
|
import { EpochNumber } from '@aztec/foundation/branded-types';
|
|
@@ -24,10 +19,10 @@ import { SpamContract } from '@aztec/noir-test-contracts.js/Spam';
|
|
|
24
19
|
import type { BootstrapNode } from '@aztec/p2p/bootstrap';
|
|
25
20
|
import { createBootstrapNodeFromPrivateKey, getBootstrapNodeEnr } from '@aztec/p2p/test-helpers';
|
|
26
21
|
import { tryStop } from '@aztec/stdlib/interfaces/server';
|
|
27
|
-
import {
|
|
28
|
-
import
|
|
22
|
+
import { TopicType } from '@aztec/stdlib/p2p';
|
|
23
|
+
import { TxStatus } from '@aztec/stdlib/tx';
|
|
24
|
+
import type { GenesisData } from '@aztec/stdlib/world-state';
|
|
29
25
|
import { ZkPassportProofParams } from '@aztec/stdlib/zkpassport';
|
|
30
|
-
import type { TestWallet } from '@aztec/test-wallet/server';
|
|
31
26
|
import { getGenesisValues } from '@aztec/world-state/testing';
|
|
32
27
|
|
|
33
28
|
import getPort from 'get-port';
|
|
@@ -49,6 +44,7 @@ import {
|
|
|
49
44
|
generatePrivateKeys,
|
|
50
45
|
} from '../fixtures/setup_p2p_test.js';
|
|
51
46
|
import { getEndToEndTestTelemetryClient } from '../fixtures/with_telemetry_utils.js';
|
|
47
|
+
import type { TestWallet } from '../test-wallet/test_wallet.js';
|
|
52
48
|
|
|
53
49
|
// Use a fixed bootstrap node private key so that we can re-use the same snapshot and the nodes can find each other
|
|
54
50
|
const BOOTSTRAP_NODE_PRIVATE_KEY = '080212208f988fc0899e4a73a5aee4d271a5f20670603a756ad8d84f2c94263a6427c591';
|
|
@@ -58,7 +54,7 @@ export const WAIT_FOR_TX_TIMEOUT = l1ContractsConfig.aztecSlotDuration * 3;
|
|
|
58
54
|
export const SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES = {
|
|
59
55
|
aztecSlotDuration: 12,
|
|
60
56
|
ethereumSlotDuration: 4,
|
|
61
|
-
|
|
57
|
+
aztecProofSubmissionEpochs: 640,
|
|
62
58
|
};
|
|
63
59
|
|
|
64
60
|
export class P2PNetworkTest {
|
|
@@ -76,7 +72,7 @@ export class P2PNetworkTest {
|
|
|
76
72
|
public validators: Operator[] = [];
|
|
77
73
|
|
|
78
74
|
public deployedAccounts: InitialAccountData[] = [];
|
|
79
|
-
public
|
|
75
|
+
public genesis: GenesisData | undefined;
|
|
80
76
|
|
|
81
77
|
// The re-execution test needs a wallet and a spam contract
|
|
82
78
|
public wallet?: TestWallet;
|
|
@@ -123,11 +119,12 @@ export class P2PNetworkTest {
|
|
|
123
119
|
initialValidatorConfig.aztecProofSubmissionEpochs ?? l1ContractsConfig.aztecProofSubmissionEpochs,
|
|
124
120
|
slashingRoundSizeInEpochs:
|
|
125
121
|
initialValidatorConfig.slashingRoundSizeInEpochs ?? l1ContractsConfig.slashingRoundSizeInEpochs,
|
|
126
|
-
|
|
122
|
+
slasherEnabled: initialValidatorConfig.slasherEnabled ?? true,
|
|
127
123
|
aztecTargetCommitteeSize: numberOfValidators,
|
|
128
124
|
metricsPort: metricsPort,
|
|
129
125
|
numberOfInitialFundedAccounts: 2,
|
|
130
126
|
startProverNode,
|
|
127
|
+
walletMinFeePadding: 2.0,
|
|
131
128
|
};
|
|
132
129
|
|
|
133
130
|
this.deployL1ContractsArgs = {
|
|
@@ -135,7 +132,7 @@ export class P2PNetworkTest {
|
|
|
135
132
|
aztecEpochDuration: initialValidatorConfig.aztecEpochDuration ?? l1ContractsConfig.aztecEpochDuration,
|
|
136
133
|
slashingRoundSizeInEpochs:
|
|
137
134
|
initialValidatorConfig.slashingRoundSizeInEpochs ?? l1ContractsConfig.slashingRoundSizeInEpochs,
|
|
138
|
-
|
|
135
|
+
slasherEnabled: initialValidatorConfig.slasherEnabled ?? true,
|
|
139
136
|
|
|
140
137
|
ethereumSlotDuration: initialValidatorConfig.ethereumSlotDuration ?? l1ContractsConfig.ethereumSlotDuration,
|
|
141
138
|
aztecSlotDuration: initialValidatorConfig.aztecSlotDuration ?? l1ContractsConfig.aztecSlotDuration,
|
|
@@ -303,10 +300,11 @@ export class P2PNetworkTest {
|
|
|
303
300
|
|
|
304
301
|
async setupAccount() {
|
|
305
302
|
this.logger.info('Setting up account');
|
|
306
|
-
const { deployedAccounts } = await deployAccounts(
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
303
|
+
const { deployedAccounts } = await deployAccounts(1, this.logger, {
|
|
304
|
+
wait: {
|
|
305
|
+
waitForStatus: TxStatus.CHECKPOINTED,
|
|
306
|
+
},
|
|
307
|
+
})({
|
|
310
308
|
wallet: this.context.wallet,
|
|
311
309
|
initialFundedAccounts: this.context.initialFundedAccounts,
|
|
312
310
|
});
|
|
@@ -321,8 +319,9 @@ export class P2PNetworkTest {
|
|
|
321
319
|
throw new Error('Call setupAccount before deploying spam contract');
|
|
322
320
|
}
|
|
323
321
|
|
|
324
|
-
|
|
325
|
-
|
|
322
|
+
({ contract: this.spamContract } = await SpamContract.deploy(this.wallet).send({
|
|
323
|
+
from: this.defaultAccountAddress!,
|
|
324
|
+
}));
|
|
326
325
|
}
|
|
327
326
|
|
|
328
327
|
async removeInitialNode() {
|
|
@@ -332,9 +331,9 @@ export class P2PNetworkTest {
|
|
|
332
331
|
const block = await this.context.deployL1ContractsValues.l1Client.getBlock({
|
|
333
332
|
blockNumber: receipt.blockNumber,
|
|
334
333
|
});
|
|
335
|
-
this.context.dateProvider
|
|
334
|
+
this.context.dateProvider.setTime(Number(block.timestamp) * 1000);
|
|
336
335
|
|
|
337
|
-
await this.context.aztecNodeService
|
|
336
|
+
await this.context.aztecNodeService.stop();
|
|
338
337
|
}
|
|
339
338
|
|
|
340
339
|
async sendDummyTx() {
|
|
@@ -342,7 +341,7 @@ export class P2PNetworkTest {
|
|
|
342
341
|
}
|
|
343
342
|
|
|
344
343
|
private async _sendDummyTx(l1Client: ExtendedViemWalletClient) {
|
|
345
|
-
const l1TxUtils =
|
|
344
|
+
const l1TxUtils = createL1TxUtils(l1Client);
|
|
346
345
|
return await l1TxUtils.sendAndMonitorTransaction({
|
|
347
346
|
to: l1Client.account!.address,
|
|
348
347
|
value: 1n,
|
|
@@ -351,25 +350,35 @@ export class P2PNetworkTest {
|
|
|
351
350
|
|
|
352
351
|
async setup() {
|
|
353
352
|
this.logger.info('Setting up subsystems from fresh');
|
|
354
|
-
this.context = await setup(
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
353
|
+
this.context = await setup(
|
|
354
|
+
0,
|
|
355
|
+
{
|
|
356
|
+
...this.setupOptions,
|
|
357
|
+
fundSponsoredFPC: true,
|
|
358
|
+
skipAccountDeployment: true,
|
|
359
|
+
slasherEnabled: this.setupOptions.slasherEnabled ?? this.deployL1ContractsArgs.slasherEnabled ?? false,
|
|
360
|
+
aztecTargetCommitteeSize: 0,
|
|
361
|
+
l1ContractsArgs: this.deployL1ContractsArgs,
|
|
362
|
+
},
|
|
363
|
+
// Use checkpointed chain tip for PXE to avoid issues with blocks being dropped due to pruned anchor blocks.
|
|
364
|
+
{ syncChainTip: 'checkpointed' },
|
|
365
|
+
);
|
|
362
366
|
this.ctx = this.context;
|
|
363
367
|
|
|
364
368
|
const sponsoredFPCAddress = await getSponsoredFPCAddress();
|
|
365
369
|
const initialFundedAccounts = [...this.context.initialFundedAccounts.map(a => a.address), sponsoredFPCAddress];
|
|
366
370
|
|
|
367
|
-
const {
|
|
368
|
-
|
|
371
|
+
const { genesis } = await getGenesisValues(
|
|
372
|
+
initialFundedAccounts,
|
|
373
|
+
undefined,
|
|
374
|
+
undefined,
|
|
375
|
+
this.context.genesis!.genesisTimestamp,
|
|
376
|
+
);
|
|
377
|
+
this.genesis = genesis;
|
|
369
378
|
|
|
370
379
|
const rollupContract = RollupContract.getFromL1ContractsValues(this.context.deployL1ContractsValues);
|
|
371
|
-
this.monitor = new ChainMonitor(rollupContract, this.context.dateProvider
|
|
372
|
-
this.monitor.on('l1-block', ({ timestamp }) => this.context.dateProvider
|
|
380
|
+
this.monitor = new ChainMonitor(rollupContract, this.context.dateProvider).start();
|
|
381
|
+
this.monitor.on('l1-block', ({ timestamp }) => this.context.dateProvider.setTime(Number(timestamp) * 1000));
|
|
373
382
|
}
|
|
374
383
|
|
|
375
384
|
async stopNodes(nodes: AztecNodeService[]) {
|
|
@@ -400,6 +409,7 @@ export class P2PNetworkTest {
|
|
|
400
409
|
expectedNodeCount?: number,
|
|
401
410
|
timeoutSeconds = 30,
|
|
402
411
|
checkIntervalSeconds = 0.1,
|
|
412
|
+
topics: TopicType[] = [TopicType.tx],
|
|
403
413
|
) {
|
|
404
414
|
const nodeCount = expectedNodeCount ?? nodes.length;
|
|
405
415
|
const minPeerCount = nodeCount - 1;
|
|
@@ -425,6 +435,29 @@ export class P2PNetworkTest {
|
|
|
425
435
|
);
|
|
426
436
|
|
|
427
437
|
this.logger.warn('All nodes connected to P2P mesh');
|
|
438
|
+
|
|
439
|
+
// Wait for GossipSub mesh to form for all specified topics.
|
|
440
|
+
// We only require at least 1 mesh peer per node because GossipSub
|
|
441
|
+
// stops grafting once it reaches Dlo peers and won't fill the mesh to all available peers.
|
|
442
|
+
for (const topic of topics) {
|
|
443
|
+
this.logger.warn(`Waiting for GossipSub mesh to form for ${topic} topic...`);
|
|
444
|
+
await Promise.all(
|
|
445
|
+
nodes.map(async (node, index) => {
|
|
446
|
+
const p2p = node.getP2P();
|
|
447
|
+
await retryUntil(
|
|
448
|
+
async () => {
|
|
449
|
+
const meshPeers = await p2p.getGossipMeshPeerCount(topic);
|
|
450
|
+
this.logger.debug(`Node ${index} has ${meshPeers} gossip mesh peers for ${topic} topic`);
|
|
451
|
+
return meshPeers >= 1 ? true : undefined;
|
|
452
|
+
},
|
|
453
|
+
`Node ${index} to have gossip mesh peers for ${topic} topic`,
|
|
454
|
+
timeoutSeconds,
|
|
455
|
+
checkIntervalSeconds,
|
|
456
|
+
);
|
|
457
|
+
}),
|
|
458
|
+
);
|
|
459
|
+
this.logger.warn(`All nodes have gossip mesh peers for ${topic} topic`);
|
|
460
|
+
}
|
|
428
461
|
}
|
|
429
462
|
|
|
430
463
|
async teardown() {
|
|
@@ -436,8 +469,7 @@ export class P2PNetworkTest {
|
|
|
436
469
|
async getContracts(): Promise<{
|
|
437
470
|
rollup: RollupContract;
|
|
438
471
|
slasherContract: GetContractReturnType<typeof SlasherAbi, ViemClient>;
|
|
439
|
-
slashingProposer:
|
|
440
|
-
slashFactory: SlashFactoryContract;
|
|
472
|
+
slashingProposer: SlashingProposerContract | undefined;
|
|
441
473
|
}> {
|
|
442
474
|
if (!this.ctx.deployL1ContractsValues) {
|
|
443
475
|
throw new Error('DeployAztecL1ContractsValues not set');
|
|
@@ -454,14 +486,9 @@ export class P2PNetworkTest {
|
|
|
454
486
|
client: this.ctx.deployL1ContractsValues.l1Client,
|
|
455
487
|
});
|
|
456
488
|
|
|
457
|
-
// Get the actual slashing proposer from rollup
|
|
489
|
+
// Get the actual slashing proposer from rollup
|
|
458
490
|
const slashingProposer = await rollup.getSlashingProposer();
|
|
459
491
|
|
|
460
|
-
|
|
461
|
-
this.ctx.deployL1ContractsValues.l1Client,
|
|
462
|
-
getAddress(this.ctx.deployL1ContractsValues.l1ContractAddresses.slashFactoryAddress!.toString()),
|
|
463
|
-
);
|
|
464
|
-
|
|
465
|
-
return { rollup, slasherContract, slashingProposer, slashFactory };
|
|
492
|
+
return { rollup, slasherContract, slashingProposer };
|
|
466
493
|
}
|
|
467
494
|
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import type { AztecNodeService } from '@aztec/aztec-node';
|
|
2
|
+
import { createLogger } from '@aztec/aztec.js/log';
|
|
3
|
+
import { waitForTx } from '@aztec/aztec.js/node';
|
|
4
|
+
import { Tx } from '@aztec/aztec.js/tx';
|
|
5
|
+
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
6
|
+
import { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
7
|
+
import { timesAsync } from '@aztec/foundation/collection';
|
|
8
|
+
import { retryUntil } from '@aztec/foundation/retry';
|
|
9
|
+
|
|
10
|
+
import { expect, jest } from '@jest/globals';
|
|
11
|
+
import fs from 'fs';
|
|
12
|
+
import os from 'os';
|
|
13
|
+
import path from 'path';
|
|
14
|
+
|
|
15
|
+
import { getBootNodeUdpPort, shouldCollectMetrics } from '../../fixtures/fixtures.js';
|
|
16
|
+
import { createNodes } from '../../fixtures/setup_p2p_test.js';
|
|
17
|
+
import { P2PNetworkTest, WAIT_FOR_TX_TIMEOUT } from '../p2p_network.js';
|
|
18
|
+
import { prepareTransactions } from '../shared.js';
|
|
19
|
+
|
|
20
|
+
// Don't set this to a higher value than 9 because each node will use a different L1 publisher account and anvil seeds
|
|
21
|
+
export const NUM_VALIDATORS = 6;
|
|
22
|
+
export const NUM_TXS_PER_NODE = 4;
|
|
23
|
+
export const BOOT_NODE_UDP_PORT = getBootNodeUdpPort();
|
|
24
|
+
|
|
25
|
+
export const createReqrespDataDir = () => fs.mkdtempSync(path.join(os.tmpdir(), 'reqresp-'));
|
|
26
|
+
|
|
27
|
+
type ReqrespOptions = {
|
|
28
|
+
disableStatusHandshake?: boolean;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export async function createReqrespTest(options: ReqrespOptions = {}): Promise<P2PNetworkTest> {
|
|
32
|
+
const { disableStatusHandshake = false } = options;
|
|
33
|
+
const t = await P2PNetworkTest.create({
|
|
34
|
+
testName: 'e2e_p2p_reqresp_tx',
|
|
35
|
+
numberOfNodes: 0,
|
|
36
|
+
numberOfValidators: NUM_VALIDATORS,
|
|
37
|
+
basePort: BOOT_NODE_UDP_PORT,
|
|
38
|
+
// To collect metrics - run in aztec-packages `docker compose --profile metrics up`
|
|
39
|
+
metricsPort: shouldCollectMetrics(),
|
|
40
|
+
initialConfig: {
|
|
41
|
+
ethereumSlotDuration: 8,
|
|
42
|
+
aztecSlotDuration: 36,
|
|
43
|
+
blockDurationMs: 6000,
|
|
44
|
+
l1PublishingTime: 8,
|
|
45
|
+
minTxsPerBlock: 1,
|
|
46
|
+
maxTxsPerBlock: 2,
|
|
47
|
+
enforceTimeTable: true,
|
|
48
|
+
aztecProofSubmissionEpochs: 1024, // effectively do not reorg
|
|
49
|
+
...(disableStatusHandshake ? { p2pDisableStatusHandshake: true } : {}),
|
|
50
|
+
listenAddress: '127.0.0.1',
|
|
51
|
+
aztecEpochDuration: 64, // stable committee
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
await t.setup();
|
|
55
|
+
await t.applyBaseSetup();
|
|
56
|
+
return t;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export async function cleanupReqrespTest(params: { t: P2PNetworkTest; nodes?: AztecNodeService[]; dataDir: string }) {
|
|
60
|
+
const { t, nodes, dataDir } = params;
|
|
61
|
+
if (nodes) {
|
|
62
|
+
await t.stopNodes(nodes);
|
|
63
|
+
}
|
|
64
|
+
await t.teardown();
|
|
65
|
+
for (let i = 0; i < NUM_VALIDATORS; i++) {
|
|
66
|
+
fs.rmSync(`${dataDir}-${i}`, { recursive: true, force: true, maxRetries: 3 });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const getNodePort = (nodeIndex: number) => BOOT_NODE_UDP_PORT + 1 + nodeIndex;
|
|
71
|
+
|
|
72
|
+
export async function runReqrespTxTest(params: {
|
|
73
|
+
t: P2PNetworkTest;
|
|
74
|
+
dataDir: string;
|
|
75
|
+
disableStatusHandshake?: boolean;
|
|
76
|
+
}): Promise<AztecNodeService[]> {
|
|
77
|
+
const { t, dataDir, disableStatusHandshake = false } = params;
|
|
78
|
+
|
|
79
|
+
if (!t.bootstrapNodeEnr) {
|
|
80
|
+
throw new Error('Bootstrap node ENR is not available');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
t.logger.info('Creating nodes');
|
|
84
|
+
const aztecNodeConfig = disableStatusHandshake
|
|
85
|
+
? { ...t.ctx.aztecNodeConfig, p2pDisableStatusHandshake: true }
|
|
86
|
+
: t.ctx.aztecNodeConfig;
|
|
87
|
+
|
|
88
|
+
const nodes = await createNodes(
|
|
89
|
+
aztecNodeConfig,
|
|
90
|
+
t.ctx.dateProvider,
|
|
91
|
+
t.bootstrapNodeEnr,
|
|
92
|
+
NUM_VALIDATORS,
|
|
93
|
+
BOOT_NODE_UDP_PORT,
|
|
94
|
+
t.genesis,
|
|
95
|
+
dataDir,
|
|
96
|
+
shouldCollectMetrics(),
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
t.logger.info('Waiting for nodes to connect');
|
|
100
|
+
await t.waitForP2PMeshConnectivity(nodes, NUM_VALIDATORS);
|
|
101
|
+
|
|
102
|
+
await t.setupAccount();
|
|
103
|
+
|
|
104
|
+
const targetBlockNumber = await t.ctx.aztecNodeService.getBlockNumber();
|
|
105
|
+
await retryUntil(
|
|
106
|
+
async () => {
|
|
107
|
+
const blockNumbers = await Promise.all(nodes.map(node => node.getBlockNumber()));
|
|
108
|
+
return blockNumbers.every(blockNumber => blockNumber >= targetBlockNumber) ? true : undefined;
|
|
109
|
+
},
|
|
110
|
+
`validators to sync to L2 block ${targetBlockNumber}`,
|
|
111
|
+
60,
|
|
112
|
+
0.5,
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
t.logger.info('Preparing transactions to send');
|
|
116
|
+
const txBatches = await timesAsync(2, () =>
|
|
117
|
+
prepareTransactions(t.logger, t.ctx.aztecNodeService, NUM_TXS_PER_NODE, t.fundedAccount),
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
t.logger.info('Removing initial node');
|
|
121
|
+
await t.removeInitialNode();
|
|
122
|
+
|
|
123
|
+
t.logger.info('Starting fresh slot');
|
|
124
|
+
const [timestamp] = await t.ctx.cheatCodes.rollup.advanceToNextSlot();
|
|
125
|
+
t.ctx.dateProvider.setTime(Number(timestamp) * 1000);
|
|
126
|
+
const startSlotTimestamp = BigInt(timestamp);
|
|
127
|
+
|
|
128
|
+
const { proposerIndexes, nodesToTurnOffTxGossip } = await getProposerIndexes(t, startSlotTimestamp);
|
|
129
|
+
t.logger.info(`Turning off tx gossip for nodes: ${nodesToTurnOffTxGossip.map(getNodePort)}`);
|
|
130
|
+
t.logger.info(`Sending txs to proposer nodes: ${proposerIndexes.map(getNodePort)}`);
|
|
131
|
+
|
|
132
|
+
// Replace the p2p node implementation of some of the nodes with a spy such that it does not store transactions that are gossiped to it
|
|
133
|
+
// Original implementation of `handleGossipedTx` will store received transactions in the tx pool.
|
|
134
|
+
// We chose the first 2 nodes that will be the proposers for the next few slots
|
|
135
|
+
for (const nodeIndex of nodesToTurnOffTxGossip) {
|
|
136
|
+
const logger = createLogger(`p2p:${getNodePort(nodeIndex)}`);
|
|
137
|
+
jest.spyOn((nodes[nodeIndex] as any).p2pClient.p2pService, 'handleGossipedTx').mockImplementation(((
|
|
138
|
+
payloadData: Buffer,
|
|
139
|
+
) => {
|
|
140
|
+
const txHash = Tx.fromBuffer(payloadData).getTxHash();
|
|
141
|
+
logger.info(`Skipping storage of gossiped transaction ${txHash.toString()}`);
|
|
142
|
+
return Promise.resolve();
|
|
143
|
+
}) as any);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// We send the tx to the proposer nodes directly, ignoring the pxe and node in each context
|
|
147
|
+
// We cannot just call tx.send since they were created using a pxe wired to the first node which is now stopped
|
|
148
|
+
t.logger.info('Sending transactions through proposer nodes');
|
|
149
|
+
const submittedTxs = await Promise.all(
|
|
150
|
+
txBatches.map(async (batch, batchIndex) => {
|
|
151
|
+
const proposerNode = nodes[proposerIndexes[batchIndex]];
|
|
152
|
+
for (const tx of batch) {
|
|
153
|
+
t.logger.info(`Tx ${tx.getTxHash().toString()} base64: ${tx.toBuffer().toString('base64')}`);
|
|
154
|
+
}
|
|
155
|
+
const txHashes = batch.map(tx => tx.getTxHash().toString());
|
|
156
|
+
t.logger.info(
|
|
157
|
+
`Sending batch ${batchIndex} to proposer ${getNodePort(proposerIndexes[batchIndex])}: ${txHashes.join(', ')}`,
|
|
158
|
+
);
|
|
159
|
+
await Promise.all(
|
|
160
|
+
batch.map(async tx => {
|
|
161
|
+
try {
|
|
162
|
+
await proposerNode.sendTx(tx);
|
|
163
|
+
} catch (err) {
|
|
164
|
+
t.logger.error(`Error sending tx: ${err}`);
|
|
165
|
+
throw err;
|
|
166
|
+
}
|
|
167
|
+
}),
|
|
168
|
+
);
|
|
169
|
+
return batch.map(tx => ({ node: proposerNode, txHash: tx.getTxHash() }));
|
|
170
|
+
}),
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
// Log pool state per node after sending
|
|
174
|
+
for (let i = 0; i < NUM_VALIDATORS; i++) {
|
|
175
|
+
const count = await nodes[i].getPendingTxCount();
|
|
176
|
+
t.logger.info(`Node ${getNodePort(i)} pool has ${count} pending txs`);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
t.logger.info('Waiting for all transactions to be mined');
|
|
180
|
+
await Promise.all(
|
|
181
|
+
submittedTxs.flatMap((batch, batchIndex) =>
|
|
182
|
+
batch.map(async (submittedTx, txIndex) => {
|
|
183
|
+
t.logger.info(`Waiting for tx ${batchIndex}-${txIndex} ${submittedTx.txHash.toString()} to be mined`);
|
|
184
|
+
await waitForTx(submittedTx.node, submittedTx.txHash, { timeout: WAIT_FOR_TX_TIMEOUT * 1.5 });
|
|
185
|
+
t.logger.info(`Tx ${batchIndex}-${txIndex} ${submittedTx.txHash.toString()} has been mined`);
|
|
186
|
+
}),
|
|
187
|
+
),
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
t.logger.info('All transactions mined');
|
|
191
|
+
|
|
192
|
+
// Assert that multiple blocks were built for at least one slot
|
|
193
|
+
t.logger.info('Verifying multiple blocks for at least one checkpoint');
|
|
194
|
+
// Wait for L1 checkpoint sync, which may lag behind P2P block propagation.
|
|
195
|
+
const checkpoints = await retryUntil(
|
|
196
|
+
async () => {
|
|
197
|
+
const cps = await nodes[0].getCheckpoints(CheckpointNumber(1), 50);
|
|
198
|
+
return cps.length > 0 && cps.some(cp => cp.checkpoint.blocks.length >= 2) ? cps : undefined;
|
|
199
|
+
},
|
|
200
|
+
'waiting for multi-block checkpoint to sync from L1',
|
|
201
|
+
30,
|
|
202
|
+
1,
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
let mbpsFound = false;
|
|
206
|
+
let expectedBlockNumber = checkpoints[0].checkpoint.blocks[0].number;
|
|
207
|
+
|
|
208
|
+
for (const published of checkpoints) {
|
|
209
|
+
const blockCount = published.checkpoint.blocks.length;
|
|
210
|
+
mbpsFound = mbpsFound || blockCount >= 2;
|
|
211
|
+
|
|
212
|
+
for (let i = 0; i < blockCount; i++) {
|
|
213
|
+
const block = published.checkpoint.blocks[i];
|
|
214
|
+
expect(block.indexWithinCheckpoint).toBe(i);
|
|
215
|
+
expect(block.checkpointNumber).toBe(published.checkpoint.number);
|
|
216
|
+
expect(block.number).toBe(expectedBlockNumber);
|
|
217
|
+
expectedBlockNumber++;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
expect(mbpsFound).toBe(true);
|
|
222
|
+
return nodes;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
async function getProposerIndexes(t: P2PNetworkTest, startSlotTimestamp: bigint) {
|
|
226
|
+
// Get the nodes for the next set of slots
|
|
227
|
+
const rollupContract = new RollupContract(
|
|
228
|
+
t.ctx.deployL1ContractsValues.l1Client,
|
|
229
|
+
t.ctx.deployL1ContractsValues.l1ContractAddresses.rollupAddress,
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
const attesters = await rollupContract.getAttesters();
|
|
233
|
+
const startSlot = await rollupContract.getSlotAt(startSlotTimestamp);
|
|
234
|
+
|
|
235
|
+
const proposers = await Promise.all(
|
|
236
|
+
Array.from({ length: 3 }, async (_, i) => {
|
|
237
|
+
const slot = SlotNumber(startSlot + i);
|
|
238
|
+
const slotTimestamp = await rollupContract.getTimestampForSlot(slot);
|
|
239
|
+
return await rollupContract.getProposerAt(slotTimestamp);
|
|
240
|
+
}),
|
|
241
|
+
);
|
|
242
|
+
// Get the indexes of the nodes that are responsible for the next two slots
|
|
243
|
+
const proposerIndexes = proposers.map(proposer => attesters.findIndex(a => a.equals(proposer)));
|
|
244
|
+
|
|
245
|
+
if (proposerIndexes.some(i => i === -1)) {
|
|
246
|
+
throw new Error(
|
|
247
|
+
`Proposer index not found for proposer ` +
|
|
248
|
+
`(proposers=${proposers.map(p => p.toString()).join(',')}, indices=${proposerIndexes.join(',')})`,
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const nodesToTurnOffTxGossip = Array.from({ length: NUM_VALIDATORS }, (_, i) => i).filter(
|
|
253
|
+
i => !proposerIndexes.includes(i),
|
|
254
|
+
);
|
|
255
|
+
return { proposerIndexes, nodesToTurnOffTxGossip };
|
|
256
|
+
}
|