@aztec/end-to-end 0.0.1-commit.ee80a48 → 0.0.1-commit.f103f88
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 +22 -29
- 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 +6 -3
- 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 +23 -13
- 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 +11 -7
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +64 -36
- 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 +19 -12
- package/dest/e2e_nested_contract/nested_contract_test.d.ts +1 -1
- package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
- 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 +38 -20
- 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 +46 -9
- package/dest/e2e_p2p/shared.d.ts +26 -8
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +54 -45
- 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 +19 -9
- 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 +37 -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 +1 -1
- package/dest/fixtures/ha_setup.d.ts.map +1 -1
- package/dest/fixtures/ha_setup.js +3 -1
- package/dest/fixtures/setup.d.ts +53 -29
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +79 -163
- package/dest/fixtures/setup_p2p_test.d.ts +18 -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/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 +1 -1
- package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
- package/dest/shared/cross_chain_test_harness.js +13 -13
- package/dest/shared/gas_portal_test_harness.js +2 -2
- 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 +16 -17
- 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 +4 -4
- 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 +100 -39
- package/dest/spartan/tx_metrics.js +1 -1
- 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 +7 -1
- package/dest/spartan/utils/config.d.ts.map +1 -1
- package/dest/spartan/utils/config.js +3 -1
- package/dest/spartan/utils/index.d.ts +4 -2
- 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 +9 -9
- 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/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 +43 -43
- package/src/bench/client_flows/client_flows_benchmark.ts +31 -18
- package/src/bench/client_flows/config.ts +9 -1
- package/src/bench/utils.ts +8 -3
- package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +31 -21
- 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 +85 -63
- package/src/e2e_fees/bridging_race.notest.ts +1 -1
- package/src/e2e_fees/fees_test.ts +21 -29
- package/src/e2e_nested_contract/nested_contract_test.ts +7 -5
- package/src/e2e_p2p/inactivity_slash_test.ts +7 -7
- package/src/e2e_p2p/p2p_network.ts +58 -37
- package/src/e2e_p2p/reqresp/utils.ts +62 -13
- package/src/e2e_p2p/shared.ts +74 -60
- 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 +26 -9
- 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 +46 -55
- 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 +3 -1
- package/src/fixtures/setup.ts +124 -231
- package/src/fixtures/setup_p2p_test.ts +33 -32
- package/src/fixtures/token_utils.ts +3 -3
- 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 +13 -9
- package/src/shared/gas_portal_test_harness.ts +1 -1
- 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 +38 -33
- package/src/simulators/lending_simulator.ts +8 -4
- package/src/simulators/token_simulator.ts +6 -30
- package/src/spartan/setup_test_wallets.ts +141 -32
- package/src/spartan/tx_metrics.ts +1 -1
- package/src/spartan/utils/bot.ts +4 -1
- package/src/spartan/utils/config.ts +2 -0
- package/src/spartan/utils/index.ts +7 -0
- package/src/spartan/utils/k8s.ts +8 -0
- package/src/spartan/utils/nodes.ts +15 -10
- package/src/spartan/utils/pod_logs.ts +99 -0
- 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
|
@@ -44,7 +44,7 @@ export class NestedContractTest {
|
|
|
44
44
|
});
|
|
45
45
|
this.wallet = this.context.wallet;
|
|
46
46
|
[{ address: this.defaultAccountAddress }] = deployedAccounts;
|
|
47
|
-
this.aztecNode = this.context.aztecNodeService
|
|
47
|
+
this.aztecNode = this.context.aztecNodeService;
|
|
48
48
|
|
|
49
49
|
this.logger.info('Public deploy accounts');
|
|
50
50
|
await publicDeployAccounts(this.wallet, [this.defaultAccountAddress]);
|
|
@@ -65,9 +65,11 @@ export class NestedContractTest {
|
|
|
65
65
|
|
|
66
66
|
async applyManual() {
|
|
67
67
|
this.logger.info('Deploying parent and child contracts');
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
this.childContract =
|
|
68
|
+
({ contract: this.parentContract } = await ParentContract.deploy(this.wallet).send({
|
|
69
|
+
from: this.defaultAccountAddress,
|
|
70
|
+
}));
|
|
71
|
+
({ contract: this.childContract } = await ChildContract.deploy(this.wallet).send({
|
|
72
|
+
from: this.defaultAccountAddress,
|
|
73
|
+
}));
|
|
72
74
|
}
|
|
73
75
|
}
|
|
@@ -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,7 +119,7 @@ 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,
|
|
@@ -136,7 +132,7 @@ export class P2PNetworkTest {
|
|
|
136
132
|
aztecEpochDuration: initialValidatorConfig.aztecEpochDuration ?? l1ContractsConfig.aztecEpochDuration,
|
|
137
133
|
slashingRoundSizeInEpochs:
|
|
138
134
|
initialValidatorConfig.slashingRoundSizeInEpochs ?? l1ContractsConfig.slashingRoundSizeInEpochs,
|
|
139
|
-
|
|
135
|
+
slasherEnabled: initialValidatorConfig.slasherEnabled ?? true,
|
|
140
136
|
|
|
141
137
|
ethereumSlotDuration: initialValidatorConfig.ethereumSlotDuration ?? l1ContractsConfig.ethereumSlotDuration,
|
|
142
138
|
aztecSlotDuration: initialValidatorConfig.aztecSlotDuration ?? l1ContractsConfig.aztecSlotDuration,
|
|
@@ -304,10 +300,11 @@ export class P2PNetworkTest {
|
|
|
304
300
|
|
|
305
301
|
async setupAccount() {
|
|
306
302
|
this.logger.info('Setting up account');
|
|
307
|
-
const { deployedAccounts } = await deployAccounts(
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
303
|
+
const { deployedAccounts } = await deployAccounts(1, this.logger, {
|
|
304
|
+
wait: {
|
|
305
|
+
waitForStatus: TxStatus.CHECKPOINTED,
|
|
306
|
+
},
|
|
307
|
+
})({
|
|
311
308
|
wallet: this.context.wallet,
|
|
312
309
|
initialFundedAccounts: this.context.initialFundedAccounts,
|
|
313
310
|
});
|
|
@@ -322,8 +319,9 @@ export class P2PNetworkTest {
|
|
|
322
319
|
throw new Error('Call setupAccount before deploying spam contract');
|
|
323
320
|
}
|
|
324
321
|
|
|
325
|
-
|
|
326
|
-
|
|
322
|
+
({ contract: this.spamContract } = await SpamContract.deploy(this.wallet).send({
|
|
323
|
+
from: this.defaultAccountAddress!,
|
|
324
|
+
}));
|
|
327
325
|
}
|
|
328
326
|
|
|
329
327
|
async removeInitialNode() {
|
|
@@ -333,9 +331,9 @@ export class P2PNetworkTest {
|
|
|
333
331
|
const block = await this.context.deployL1ContractsValues.l1Client.getBlock({
|
|
334
332
|
blockNumber: receipt.blockNumber,
|
|
335
333
|
});
|
|
336
|
-
this.context.dateProvider
|
|
334
|
+
this.context.dateProvider.setTime(Number(block.timestamp) * 1000);
|
|
337
335
|
|
|
338
|
-
await this.context.aztecNodeService
|
|
336
|
+
await this.context.aztecNodeService.stop();
|
|
339
337
|
}
|
|
340
338
|
|
|
341
339
|
async sendDummyTx() {
|
|
@@ -343,7 +341,7 @@ export class P2PNetworkTest {
|
|
|
343
341
|
}
|
|
344
342
|
|
|
345
343
|
private async _sendDummyTx(l1Client: ExtendedViemWalletClient) {
|
|
346
|
-
const l1TxUtils =
|
|
344
|
+
const l1TxUtils = createL1TxUtils(l1Client);
|
|
347
345
|
return await l1TxUtils.sendAndMonitorTransaction({
|
|
348
346
|
to: l1Client.account!.address,
|
|
349
347
|
value: 1n,
|
|
@@ -358,7 +356,7 @@ export class P2PNetworkTest {
|
|
|
358
356
|
...this.setupOptions,
|
|
359
357
|
fundSponsoredFPC: true,
|
|
360
358
|
skipAccountDeployment: true,
|
|
361
|
-
|
|
359
|
+
slasherEnabled: this.setupOptions.slasherEnabled ?? this.deployL1ContractsArgs.slasherEnabled ?? false,
|
|
362
360
|
aztecTargetCommitteeSize: 0,
|
|
363
361
|
l1ContractsArgs: this.deployL1ContractsArgs,
|
|
364
362
|
},
|
|
@@ -370,12 +368,17 @@ export class P2PNetworkTest {
|
|
|
370
368
|
const sponsoredFPCAddress = await getSponsoredFPCAddress();
|
|
371
369
|
const initialFundedAccounts = [...this.context.initialFundedAccounts.map(a => a.address), sponsoredFPCAddress];
|
|
372
370
|
|
|
373
|
-
const {
|
|
374
|
-
|
|
371
|
+
const { genesis } = await getGenesisValues(
|
|
372
|
+
initialFundedAccounts,
|
|
373
|
+
undefined,
|
|
374
|
+
undefined,
|
|
375
|
+
this.context.genesis!.genesisTimestamp,
|
|
376
|
+
);
|
|
377
|
+
this.genesis = genesis;
|
|
375
378
|
|
|
376
379
|
const rollupContract = RollupContract.getFromL1ContractsValues(this.context.deployL1ContractsValues);
|
|
377
|
-
this.monitor = new ChainMonitor(rollupContract, this.context.dateProvider
|
|
378
|
-
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));
|
|
379
382
|
}
|
|
380
383
|
|
|
381
384
|
async stopNodes(nodes: AztecNodeService[]) {
|
|
@@ -406,6 +409,7 @@ export class P2PNetworkTest {
|
|
|
406
409
|
expectedNodeCount?: number,
|
|
407
410
|
timeoutSeconds = 30,
|
|
408
411
|
checkIntervalSeconds = 0.1,
|
|
412
|
+
topics: TopicType[] = [TopicType.tx],
|
|
409
413
|
) {
|
|
410
414
|
const nodeCount = expectedNodeCount ?? nodes.length;
|
|
411
415
|
const minPeerCount = nodeCount - 1;
|
|
@@ -431,6 +435,29 @@ export class P2PNetworkTest {
|
|
|
431
435
|
);
|
|
432
436
|
|
|
433
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
|
+
}
|
|
434
461
|
}
|
|
435
462
|
|
|
436
463
|
async teardown() {
|
|
@@ -442,8 +469,7 @@ export class P2PNetworkTest {
|
|
|
442
469
|
async getContracts(): Promise<{
|
|
443
470
|
rollup: RollupContract;
|
|
444
471
|
slasherContract: GetContractReturnType<typeof SlasherAbi, ViemClient>;
|
|
445
|
-
slashingProposer:
|
|
446
|
-
slashFactory: SlashFactoryContract;
|
|
472
|
+
slashingProposer: SlashingProposerContract | undefined;
|
|
447
473
|
}> {
|
|
448
474
|
if (!this.ctx.deployL1ContractsValues) {
|
|
449
475
|
throw new Error('DeployAztecL1ContractsValues not set');
|
|
@@ -460,14 +486,9 @@ export class P2PNetworkTest {
|
|
|
460
486
|
client: this.ctx.deployL1ContractsValues.l1Client,
|
|
461
487
|
});
|
|
462
488
|
|
|
463
|
-
// Get the actual slashing proposer from rollup
|
|
489
|
+
// Get the actual slashing proposer from rollup
|
|
464
490
|
const slashingProposer = await rollup.getSlashingProposer();
|
|
465
491
|
|
|
466
|
-
|
|
467
|
-
this.ctx.deployL1ContractsValues.l1Client,
|
|
468
|
-
getAddress(this.ctx.deployL1ContractsValues.l1ContractAddresses.slashFactoryAddress!.toString()),
|
|
469
|
-
);
|
|
470
|
-
|
|
471
|
-
return { rollup, slasherContract, slashingProposer, slashFactory };
|
|
492
|
+
return { rollup, slasherContract, slashingProposer };
|
|
472
493
|
}
|
|
473
494
|
}
|
|
@@ -3,24 +3,24 @@ import { createLogger } from '@aztec/aztec.js/log';
|
|
|
3
3
|
import { waitForTx } from '@aztec/aztec.js/node';
|
|
4
4
|
import { Tx } from '@aztec/aztec.js/tx';
|
|
5
5
|
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
6
|
-
import { SlotNumber } from '@aztec/foundation/branded-types';
|
|
6
|
+
import { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
7
7
|
import { timesAsync } from '@aztec/foundation/collection';
|
|
8
8
|
import { retryUntil } from '@aztec/foundation/retry';
|
|
9
9
|
|
|
10
|
-
import { jest } from '@jest/globals';
|
|
10
|
+
import { expect, jest } from '@jest/globals';
|
|
11
11
|
import fs from 'fs';
|
|
12
12
|
import os from 'os';
|
|
13
13
|
import path from 'path';
|
|
14
14
|
|
|
15
|
-
import { shouldCollectMetrics } from '../../fixtures/fixtures.js';
|
|
15
|
+
import { getBootNodeUdpPort, shouldCollectMetrics } from '../../fixtures/fixtures.js';
|
|
16
16
|
import { createNodes } from '../../fixtures/setup_p2p_test.js';
|
|
17
|
-
import { P2PNetworkTest,
|
|
17
|
+
import { P2PNetworkTest, WAIT_FOR_TX_TIMEOUT } from '../p2p_network.js';
|
|
18
18
|
import { prepareTransactions } from '../shared.js';
|
|
19
19
|
|
|
20
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
21
|
export const NUM_VALIDATORS = 6;
|
|
22
|
-
export const NUM_TXS_PER_NODE =
|
|
23
|
-
export const BOOT_NODE_UDP_PORT =
|
|
22
|
+
export const NUM_TXS_PER_NODE = 4;
|
|
23
|
+
export const BOOT_NODE_UDP_PORT = getBootNodeUdpPort();
|
|
24
24
|
|
|
25
25
|
export const createReqrespDataDir = () => fs.mkdtempSync(path.join(os.tmpdir(), 'reqresp-'));
|
|
26
26
|
|
|
@@ -38,8 +38,14 @@ export async function createReqrespTest(options: ReqrespOptions = {}): Promise<P
|
|
|
38
38
|
// To collect metrics - run in aztec-packages `docker compose --profile metrics up`
|
|
39
39
|
metricsPort: shouldCollectMetrics(),
|
|
40
40
|
initialConfig: {
|
|
41
|
-
|
|
42
|
-
aztecSlotDuration:
|
|
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
|
|
43
49
|
...(disableStatusHandshake ? { p2pDisableStatusHandshake: true } : {}),
|
|
44
50
|
listenAddress: '127.0.0.1',
|
|
45
51
|
aztecEpochDuration: 64, // stable committee
|
|
@@ -81,11 +87,11 @@ export async function runReqrespTxTest(params: {
|
|
|
81
87
|
|
|
82
88
|
const nodes = await createNodes(
|
|
83
89
|
aztecNodeConfig,
|
|
84
|
-
t.ctx.dateProvider
|
|
90
|
+
t.ctx.dateProvider,
|
|
85
91
|
t.bootstrapNodeEnr,
|
|
86
92
|
NUM_VALIDATORS,
|
|
87
93
|
BOOT_NODE_UDP_PORT,
|
|
88
|
-
t.
|
|
94
|
+
t.genesis,
|
|
89
95
|
dataDir,
|
|
90
96
|
shouldCollectMetrics(),
|
|
91
97
|
);
|
|
@@ -95,7 +101,7 @@ export async function runReqrespTxTest(params: {
|
|
|
95
101
|
|
|
96
102
|
await t.setupAccount();
|
|
97
103
|
|
|
98
|
-
const targetBlockNumber = await t.ctx.aztecNodeService
|
|
104
|
+
const targetBlockNumber = await t.ctx.aztecNodeService.getBlockNumber();
|
|
99
105
|
await retryUntil(
|
|
100
106
|
async () => {
|
|
101
107
|
const blockNumbers = await Promise.all(nodes.map(node => node.getBlockNumber()));
|
|
@@ -108,7 +114,7 @@ export async function runReqrespTxTest(params: {
|
|
|
108
114
|
|
|
109
115
|
t.logger.info('Preparing transactions to send');
|
|
110
116
|
const txBatches = await timesAsync(2, () =>
|
|
111
|
-
prepareTransactions(t.logger, t.ctx.aztecNodeService
|
|
117
|
+
prepareTransactions(t.logger, t.ctx.aztecNodeService, NUM_TXS_PER_NODE, t.fundedAccount),
|
|
112
118
|
);
|
|
113
119
|
|
|
114
120
|
t.logger.info('Removing initial node');
|
|
@@ -116,7 +122,7 @@ export async function runReqrespTxTest(params: {
|
|
|
116
122
|
|
|
117
123
|
t.logger.info('Starting fresh slot');
|
|
118
124
|
const [timestamp] = await t.ctx.cheatCodes.rollup.advanceToNextSlot();
|
|
119
|
-
t.ctx.dateProvider
|
|
125
|
+
t.ctx.dateProvider.setTime(Number(timestamp) * 1000);
|
|
120
126
|
const startSlotTimestamp = BigInt(timestamp);
|
|
121
127
|
|
|
122
128
|
const { proposerIndexes, nodesToTurnOffTxGossip } = await getProposerIndexes(t, startSlotTimestamp);
|
|
@@ -143,6 +149,13 @@ export async function runReqrespTxTest(params: {
|
|
|
143
149
|
const submittedTxs = await Promise.all(
|
|
144
150
|
txBatches.map(async (batch, batchIndex) => {
|
|
145
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
|
+
);
|
|
146
159
|
await Promise.all(
|
|
147
160
|
batch.map(async tx => {
|
|
148
161
|
try {
|
|
@@ -157,6 +170,12 @@ export async function runReqrespTxTest(params: {
|
|
|
157
170
|
}),
|
|
158
171
|
);
|
|
159
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
|
+
|
|
160
179
|
t.logger.info('Waiting for all transactions to be mined');
|
|
161
180
|
await Promise.all(
|
|
162
181
|
submittedTxs.flatMap((batch, batchIndex) =>
|
|
@@ -170,6 +189,36 @@ export async function runReqrespTxTest(params: {
|
|
|
170
189
|
|
|
171
190
|
t.logger.info('All transactions mined');
|
|
172
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);
|
|
173
222
|
return nodes;
|
|
174
223
|
}
|
|
175
224
|
|
package/src/e2e_p2p/shared.ts
CHANGED
|
@@ -6,12 +6,9 @@ import { Fr } from '@aztec/aztec.js/fields';
|
|
|
6
6
|
import type { Logger } from '@aztec/aztec.js/log';
|
|
7
7
|
import { TxHash } from '@aztec/aztec.js/tx';
|
|
8
8
|
import type { RollupCheatCodes } from '@aztec/aztec/testing';
|
|
9
|
-
import type {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
TallySlashingProposerContract,
|
|
13
|
-
} from '@aztec/ethereum/contracts';
|
|
14
|
-
import { EpochNumber } from '@aztec/foundation/branded-types';
|
|
9
|
+
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
10
|
+
import type { RollupContract, SlashingProposerContract } from '@aztec/ethereum/contracts';
|
|
11
|
+
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
15
12
|
import { timesAsync, unique } from '@aztec/foundation/collection';
|
|
16
13
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
17
14
|
import { retryUntil } from '@aztec/foundation/retry';
|
|
@@ -21,10 +18,10 @@ import { TestContract, TestContractArtifact } from '@aztec/noir-test-contracts.j
|
|
|
21
18
|
import { getPXEConfig, getPXEConfig as getRpcConfig } from '@aztec/pxe/server';
|
|
22
19
|
import { getRoundForOffense } from '@aztec/slasher';
|
|
23
20
|
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
24
|
-
import type { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
|
|
25
|
-
import { type ProvenTx, TestWallet, proveInteraction } from '@aztec/test-wallet/server';
|
|
26
21
|
|
|
27
22
|
import { submitTxsTo } from '../shared/submit-transactions.js';
|
|
23
|
+
import { TestWallet } from '../test-wallet/test_wallet.js';
|
|
24
|
+
import { type ProvenTx, proveInteraction } from '../test-wallet/utils.js';
|
|
28
25
|
|
|
29
26
|
// submits a set of transactions to the provided Private eXecution Environment (PXE)
|
|
30
27
|
export const submitComplexTxsTo = async (
|
|
@@ -40,7 +37,7 @@ export const submitComplexTxsTo = async (
|
|
|
40
37
|
const spamCount = 15;
|
|
41
38
|
for (let i = 0; i < numTxs; i++) {
|
|
42
39
|
const method = spamContract.methods.spam(seed + BigInt(i * spamCount), spamCount, !!opts.callPublic);
|
|
43
|
-
const txHash = await method.send({ from, wait: NO_WAIT });
|
|
40
|
+
const { txHash } = await method.send({ from, wait: NO_WAIT });
|
|
44
41
|
logger.info(`Tx sent with hash ${txHash.toString()}`);
|
|
45
42
|
txs.push(txHash);
|
|
46
43
|
}
|
|
@@ -97,7 +94,7 @@ export async function prepareTransactions(
|
|
|
97
94
|
}
|
|
98
95
|
|
|
99
96
|
export function awaitProposalExecution(
|
|
100
|
-
slashingProposer:
|
|
97
|
+
slashingProposer: SlashingProposerContract,
|
|
101
98
|
timeoutSeconds: number,
|
|
102
99
|
logger: Logger,
|
|
103
100
|
): Promise<bigint> {
|
|
@@ -107,24 +104,12 @@ export function awaitProposalExecution(
|
|
|
107
104
|
reject(new Error(`Timeout waiting for proposal execution after ${timeoutSeconds}s`));
|
|
108
105
|
}, timeoutSeconds * 1000);
|
|
109
106
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
logger.warn(`Proposal ${args.payload} from round ${args.round} executed`);
|
|
113
|
-
clearTimeout(timeout);
|
|
114
|
-
unwatch();
|
|
115
|
-
resolve(args.round);
|
|
116
|
-
});
|
|
117
|
-
} else if (slashingProposer.type === 'tally') {
|
|
118
|
-
const unwatch = slashingProposer.listenToRoundExecuted(args => {
|
|
119
|
-
logger.warn(`Slash from round ${args.round} executed`);
|
|
120
|
-
clearTimeout(timeout);
|
|
121
|
-
unwatch();
|
|
122
|
-
resolve(args.round);
|
|
123
|
-
});
|
|
124
|
-
} else {
|
|
107
|
+
const unwatch = slashingProposer.listenToRoundExecuted(args => {
|
|
108
|
+
logger.warn(`Slash from round ${args.round} executed`);
|
|
125
109
|
clearTimeout(timeout);
|
|
126
|
-
|
|
127
|
-
|
|
110
|
+
unwatch();
|
|
111
|
+
resolve(args.round);
|
|
112
|
+
});
|
|
128
113
|
});
|
|
129
114
|
}
|
|
130
115
|
|
|
@@ -145,9 +130,62 @@ export async function awaitCommitteeExists({
|
|
|
145
130
|
'non-empty committee',
|
|
146
131
|
60,
|
|
147
132
|
);
|
|
133
|
+
logger.warn(`Committee has been formed`, { committee: committee!.map(c => c.toString()) });
|
|
148
134
|
return committee!.map(c => c.toString() as `0x${string}`);
|
|
149
135
|
}
|
|
150
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Advance epochs until we find one where the target proposer is selected for at least one slot,
|
|
139
|
+
* then stop one epoch before it. This leaves time for the caller to start sequencers before
|
|
140
|
+
* warping to the target epoch, avoiding the race where the target epoch passes before sequencers
|
|
141
|
+
* are ready.
|
|
142
|
+
*
|
|
143
|
+
* Returns the target epoch number so the caller can warp to it after starting sequencers.
|
|
144
|
+
*/
|
|
145
|
+
export async function advanceToEpochBeforeProposer({
|
|
146
|
+
epochCache,
|
|
147
|
+
cheatCodes,
|
|
148
|
+
targetProposer,
|
|
149
|
+
logger,
|
|
150
|
+
maxAttempts = 20,
|
|
151
|
+
}: {
|
|
152
|
+
epochCache: EpochCacheInterface;
|
|
153
|
+
cheatCodes: RollupCheatCodes;
|
|
154
|
+
targetProposer: EthAddress;
|
|
155
|
+
logger: Logger;
|
|
156
|
+
maxAttempts?: number;
|
|
157
|
+
}): Promise<{ targetEpoch: EpochNumber }> {
|
|
158
|
+
const { epochDuration } = await cheatCodes.getConfig();
|
|
159
|
+
|
|
160
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
161
|
+
const currentEpoch = await cheatCodes.getEpoch();
|
|
162
|
+
// Check the NEXT epoch's slots so we stay one epoch before the target,
|
|
163
|
+
// giving the caller time to start sequencers before the target epoch arrives.
|
|
164
|
+
const nextEpoch = Number(currentEpoch) + 1;
|
|
165
|
+
const startSlot = nextEpoch * Number(epochDuration);
|
|
166
|
+
const endSlot = startSlot + Number(epochDuration);
|
|
167
|
+
|
|
168
|
+
logger.info(
|
|
169
|
+
`Checking next epoch ${nextEpoch} (slots ${startSlot}-${endSlot - 1}) for proposer ${targetProposer} (current epoch: ${currentEpoch})`,
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
for (let s = startSlot; s < endSlot; s++) {
|
|
173
|
+
const proposer = await epochCache.getProposerAttesterAddressInSlot(SlotNumber(s));
|
|
174
|
+
if (proposer && proposer.equals(targetProposer)) {
|
|
175
|
+
logger.warn(
|
|
176
|
+
`Found target proposer ${targetProposer} in slot ${s} of epoch ${nextEpoch}. Staying at epoch ${currentEpoch} to allow sequencer startup.`,
|
|
177
|
+
);
|
|
178
|
+
return { targetEpoch: EpochNumber(nextEpoch) };
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
logger.info(`Target proposer not found in epoch ${nextEpoch}, advancing to next epoch`);
|
|
183
|
+
await cheatCodes.advanceToNextEpoch();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
throw new Error(`Target proposer ${targetProposer} not found in any slot after ${maxAttempts} epoch attempts`);
|
|
187
|
+
}
|
|
188
|
+
|
|
151
189
|
export async function awaitOffenseDetected({
|
|
152
190
|
logger,
|
|
153
191
|
nodeAdmin,
|
|
@@ -190,7 +228,6 @@ export async function awaitCommitteeKicked({
|
|
|
190
228
|
rollup,
|
|
191
229
|
cheatCodes,
|
|
192
230
|
committee,
|
|
193
|
-
slashFactory,
|
|
194
231
|
slashingProposer,
|
|
195
232
|
slashingRoundSize,
|
|
196
233
|
aztecSlotDuration,
|
|
@@ -201,8 +238,7 @@ export async function awaitCommitteeKicked({
|
|
|
201
238
|
rollup: RollupContract;
|
|
202
239
|
cheatCodes: RollupCheatCodes;
|
|
203
240
|
committee: readonly `0x${string}`[];
|
|
204
|
-
|
|
205
|
-
slashingProposer: EmpireSlashingProposerContract | TallySlashingProposerContract | undefined;
|
|
241
|
+
slashingProposer: SlashingProposerContract | undefined;
|
|
206
242
|
slashingRoundSize: number;
|
|
207
243
|
aztecSlotDuration: number;
|
|
208
244
|
aztecEpochDuration: number;
|
|
@@ -215,36 +251,14 @@ export async function awaitCommitteeKicked({
|
|
|
215
251
|
|
|
216
252
|
await cheatCodes.debugRollup();
|
|
217
253
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
const events = await slashFactory.getSlashPayloadCreatedEvents();
|
|
227
|
-
return events.length > 0 ? events : undefined;
|
|
228
|
-
},
|
|
229
|
-
'slash payload created',
|
|
230
|
-
120,
|
|
231
|
-
1,
|
|
232
|
-
);
|
|
233
|
-
expect(slashPayloadEvents.length).toBe(1);
|
|
234
|
-
// The uniqueness check is needed since a validator may be slashed more than once on the same round (eg because they let two epochs be pruned)
|
|
235
|
-
expect(unique(slashPayloadEvents[0].slashes.map(slash => slash.validator.toString()))).toHaveLength(
|
|
236
|
-
committee.length,
|
|
237
|
-
);
|
|
238
|
-
} else {
|
|
239
|
-
// Use the slash offset to ensure we are in the right epoch for tally
|
|
240
|
-
const slashOffsetInRounds = await slashingProposer.getSlashOffsetInRounds();
|
|
241
|
-
const slashingRoundSizeInEpochs = slashingRoundSize / aztecEpochDuration;
|
|
242
|
-
const slashingOffsetInEpochs = Number(slashOffsetInRounds) * slashingRoundSizeInEpochs;
|
|
243
|
-
const firstEpochInOffenseRound = offenseEpoch - (offenseEpoch % slashingRoundSizeInEpochs);
|
|
244
|
-
const targetEpoch = firstEpochInOffenseRound + slashingOffsetInEpochs;
|
|
245
|
-
logger.info(`Advancing to epoch ${targetEpoch} so we start slashing`);
|
|
246
|
-
await cheatCodes.advanceToEpoch(EpochNumber(targetEpoch), { offset: -aztecSlotDuration / 2 });
|
|
247
|
-
}
|
|
254
|
+
// Use the slash offset to ensure we are in the right epoch for tally
|
|
255
|
+
const slashOffsetInRounds = await slashingProposer.getSlashOffsetInRounds();
|
|
256
|
+
const slashingRoundSizeInEpochs = slashingRoundSize / aztecEpochDuration;
|
|
257
|
+
const slashingOffsetInEpochs = Number(slashOffsetInRounds) * slashingRoundSizeInEpochs;
|
|
258
|
+
const firstEpochInOffenseRound = offenseEpoch - (offenseEpoch % slashingRoundSizeInEpochs);
|
|
259
|
+
const targetEpoch = firstEpochInOffenseRound + slashingOffsetInEpochs;
|
|
260
|
+
logger.info(`Advancing to epoch ${targetEpoch} so we start slashing`);
|
|
261
|
+
await cheatCodes.advanceToEpoch(EpochNumber(targetEpoch), { offset: -aztecSlotDuration / 2 });
|
|
248
262
|
|
|
249
263
|
const attestersPre = await rollup.getAttesters();
|
|
250
264
|
expect(attestersPre.length).toBe(committee.length);
|