@aztec/end-to-end 0.0.1-commit.d431d1c → 0.0.1-commit.d6f2b3f94
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/dest/bench/client_flows/client_flows_benchmark.d.ts +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.js +28 -13
- 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 +9 -7
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +1 -1
- 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 +7 -8
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +1 -1
- 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_epochs/epochs_test.d.ts +7 -1
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +38 -10
- package/dest/e2e_fees/bridging_race.notest.js +1 -1
- package/dest/e2e_fees/fees_test.d.ts +1 -1
- package/dest/e2e_fees/fees_test.d.ts.map +1 -1
- package/dest/e2e_fees/fees_test.js +6 -6
- 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.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 +2 -2
- package/dest/e2e_p2p/p2p_network.d.ts +1 -1
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +6 -2
- 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 +153 -0
- package/dest/e2e_p2p/shared.d.ts +6 -6
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +12 -16
- 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 +1 -1
- package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
- package/dest/e2e_token_contract/token_contract_test.js +3 -3
- package/dest/fixtures/e2e_prover_test.d.ts +1 -1
- package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
- package/dest/fixtures/e2e_prover_test.js +8 -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 +114 -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 +17 -15
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +38 -92
- package/dest/fixtures/setup_p2p_test.d.ts +12 -8
- package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.js +29 -21
- package/dest/fixtures/token_utils.d.ts +1 -1
- package/dest/fixtures/token_utils.d.ts.map +1 -1
- package/dest/fixtures/token_utils.js +7 -4
- 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 +11 -11
- package/dest/shared/gas_portal_test_harness.js +1 -1
- package/dest/shared/submit-transactions.d.ts +3 -3
- 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 +20 -18
- package/dest/simulators/lending_simulator.js +2 -2
- package/dest/spartan/setup_test_wallets.d.ts +1 -1
- package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
- package/dest/spartan/setup_test_wallets.js +61 -34
- 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 +178 -4
- package/dest/spartan/utils/bot.d.ts +27 -0
- package/dest/spartan/utils/bot.d.ts.map +1 -0
- package/dest/spartan/utils/bot.js +141 -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 +39 -0
- package/dest/spartan/utils/config.d.ts.map +1 -0
- package/dest/spartan/utils/config.js +21 -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 +9 -0
- package/dest/spartan/utils/index.d.ts.map +1 -0
- package/dest/spartan/utils/index.js +18 -0
- package/dest/spartan/utils/k8s.d.ts +126 -0
- package/dest/spartan/utils/k8s.d.ts.map +1 -0
- package/dest/spartan/utils/k8s.js +375 -0
- package/dest/spartan/utils/nodes.d.ts +41 -0
- package/dest/spartan/utils/nodes.d.ts.map +1 -0
- package/dest/spartan/utils/nodes.js +461 -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/package.json +42 -39
- package/src/bench/client_flows/client_flows_benchmark.ts +16 -29
- package/src/bench/client_flows/config.ts +9 -1
- package/src/bench/utils.ts +10 -8
- package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +10 -13
- package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +6 -7
- package/src/e2e_deploy_contract/deploy_test.ts +2 -2
- package/src/e2e_epochs/epochs_test.ts +71 -35
- package/src/e2e_fees/bridging_race.notest.ts +1 -4
- package/src/e2e_fees/fees_test.ts +16 -20
- package/src/e2e_l1_publisher/write_json.ts +3 -8
- package/src/e2e_nested_contract/nested_contract_test.ts +3 -5
- package/src/e2e_p2p/inactivity_slash_test.ts +4 -4
- package/src/e2e_p2p/p2p_network.ts +19 -13
- package/src/e2e_p2p/reqresp/utils.ts +207 -0
- package/src/e2e_p2p/shared.ts +21 -22
- 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 +4 -6
- package/src/fixtures/dumps/epoch_proof_result.json +1 -1
- package/src/fixtures/e2e_prover_test.ts +7 -12
- package/src/fixtures/ha_setup.ts +184 -0
- package/src/fixtures/index.ts +1 -0
- package/src/fixtures/setup.ts +47 -125
- package/src/fixtures/setup_p2p_test.ts +31 -27
- package/src/fixtures/token_utils.ts +6 -5
- package/src/shared/cross_chain_test_harness.ts +13 -27
- package/src/shared/gas_portal_test_harness.ts +1 -1
- package/src/shared/submit-transactions.ts +9 -15
- package/src/shared/uniswap_l1_l2.ts +20 -29
- package/src/simulators/lending_simulator.ts +2 -2
- package/src/spartan/setup_test_wallets.ts +72 -24
- package/src/spartan/tx_metrics.ts +152 -7
- package/src/spartan/utils/bot.ts +185 -0
- package/src/spartan/utils/chaos.ts +253 -0
- package/src/spartan/utils/clients.ts +100 -0
- package/src/spartan/utils/config.ts +27 -0
- package/src/spartan/utils/health.ts +255 -0
- package/src/spartan/utils/helm.ts +84 -0
- package/src/spartan/utils/index.ts +64 -0
- package/src/spartan/utils/k8s.ts +527 -0
- package/src/spartan/utils/nodes.ts +538 -0
- package/src/spartan/utils/scripts.ts +99 -0
- package/src/spartan/utils.ts +1 -1246
|
@@ -114,9 +114,7 @@ export class FullProverTest {
|
|
|
114
114
|
FullProverTest.TOKEN_NAME,
|
|
115
115
|
FullProverTest.TOKEN_SYMBOL,
|
|
116
116
|
FullProverTest.TOKEN_DECIMALS,
|
|
117
|
-
)
|
|
118
|
-
.send({ from: this.accounts[0] })
|
|
119
|
-
.wait();
|
|
117
|
+
).send({ from: this.accounts[0], wait: { returnReceipt: true } });
|
|
120
118
|
this.logger.verbose(`Token deployed to ${asset.address}`);
|
|
121
119
|
|
|
122
120
|
this.fakeProofsAsset = asset;
|
|
@@ -146,7 +144,7 @@ export class FullProverTest {
|
|
|
146
144
|
this.logger.info(`Enabling proving`, { realProofs: this.realProofs });
|
|
147
145
|
|
|
148
146
|
// We don't wish to mark as proven automatically, so we set the flag to false
|
|
149
|
-
this.context.watcher
|
|
147
|
+
this.context.watcher.setIsMarkingAsProven(false);
|
|
150
148
|
|
|
151
149
|
this.simulatedProverNode = this.context.proverNode!;
|
|
152
150
|
({
|
|
@@ -154,7 +152,7 @@ export class FullProverTest {
|
|
|
154
152
|
deployL1ContractsValues: this.l1Contracts,
|
|
155
153
|
cheatCodes: this.cheatCodes,
|
|
156
154
|
} = this.context);
|
|
157
|
-
this.aztecNodeAdmin = this.context.aztecNodeService
|
|
155
|
+
this.aztecNodeAdmin = this.context.aztecNodeService;
|
|
158
156
|
|
|
159
157
|
const config = this.context.aztecNodeConfig;
|
|
160
158
|
const blobClient = await createBlobClientWithFileStores(config, this.logger);
|
|
@@ -200,7 +198,7 @@ export class FullProverTest {
|
|
|
200
198
|
this.aztecNode,
|
|
201
199
|
{ proverEnabled: this.realProofs },
|
|
202
200
|
undefined,
|
|
203
|
-
|
|
201
|
+
'pxe-proven',
|
|
204
202
|
);
|
|
205
203
|
this.logger.debug(`Contract address ${this.fakeProofsAsset.address}`);
|
|
206
204
|
await provenWallet.registerContract(this.fakeProofsAssetInstance, TokenContract.artifact);
|
|
@@ -227,7 +225,7 @@ export class FullProverTest {
|
|
|
227
225
|
this.logger.verbose('Starting archiver for new prover node');
|
|
228
226
|
const archiver = await createArchiver(
|
|
229
227
|
{ ...this.context.aztecNodeConfig, dataDirectory: undefined },
|
|
230
|
-
{ blobClient, dateProvider: this.context.dateProvider
|
|
228
|
+
{ blobClient, dateProvider: this.context.dateProvider },
|
|
231
229
|
{ blockUntilSync: true },
|
|
232
230
|
);
|
|
233
231
|
|
|
@@ -308,13 +306,10 @@ export class FullProverTest {
|
|
|
308
306
|
const publicAmount = 10000n;
|
|
309
307
|
|
|
310
308
|
this.logger.verbose(`Minting ${privateAmount + publicAmount} publicly...`);
|
|
311
|
-
await asset.methods
|
|
312
|
-
.mint_to_public(accounts[0], privateAmount + publicAmount)
|
|
313
|
-
.send({ from: accounts[0] })
|
|
314
|
-
.wait();
|
|
309
|
+
await asset.methods.mint_to_public(accounts[0], privateAmount + publicAmount).send({ from: accounts[0] });
|
|
315
310
|
|
|
316
311
|
this.logger.verbose(`Transferring ${privateAmount} to private...`);
|
|
317
|
-
await asset.methods.transfer_to_private(accounts[0], privateAmount).send({ from: accounts[0] })
|
|
312
|
+
await asset.methods.transfer_to_private(accounts[0], privateAmount).send({ from: accounts[0] });
|
|
318
313
|
|
|
319
314
|
this.logger.info(`Minting complete`);
|
|
320
315
|
|
|
@@ -0,0 +1,184 @@
|
|
|
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: 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 = process.env.DATABASE_URL || 'postgresql://aztec:aztec@localhost:5432/aztec_ha_test';
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
databaseUrl,
|
|
35
|
+
nodeId,
|
|
36
|
+
haSigningEnabled: true,
|
|
37
|
+
pollingIntervalMs: 100,
|
|
38
|
+
signingTimeoutMs: 3000,
|
|
39
|
+
maxStuckDutiesAgeMs: 72000,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Setup PostgreSQL database connection pool for HA tests
|
|
45
|
+
*
|
|
46
|
+
* Note: Database migrations should be run separately before starting tests,
|
|
47
|
+
* either via docker-compose entrypoint or manually with: aztec migrate-ha-db up
|
|
48
|
+
*/
|
|
49
|
+
export function setupHADatabase(databaseUrl: string, logger?: Logger): Pool {
|
|
50
|
+
try {
|
|
51
|
+
// Create connection pool for test usage
|
|
52
|
+
// Migrations are already run by docker-compose entrypoint before tests start
|
|
53
|
+
const pool = new Pool({ connectionString: databaseUrl });
|
|
54
|
+
|
|
55
|
+
logger?.info('Connected to HA database (migrations should already be applied)');
|
|
56
|
+
|
|
57
|
+
return pool;
|
|
58
|
+
} catch (error) {
|
|
59
|
+
logger?.error(`Failed to connect to HA database: ${error}`);
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Clean up HA database - drop all tables
|
|
66
|
+
* Use this between tests to ensure clean state
|
|
67
|
+
*/
|
|
68
|
+
export async function cleanupHADatabase(pool: Pool, logger?: Logger): Promise<void> {
|
|
69
|
+
try {
|
|
70
|
+
// Drop all HA tables
|
|
71
|
+
await pool.query('DROP TABLE IF EXISTS validator_duties CASCADE');
|
|
72
|
+
await pool.query('DROP TABLE IF EXISTS slashing_protection CASCADE');
|
|
73
|
+
await pool.query('DROP TABLE IF EXISTS schema_version CASCADE');
|
|
74
|
+
|
|
75
|
+
logger?.info('HA database cleaned up successfully');
|
|
76
|
+
} catch (error) {
|
|
77
|
+
logger?.error(`Failed to cleanup HA database: ${error}`);
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Query validator duties from the database
|
|
84
|
+
*/
|
|
85
|
+
export async function getValidatorDuties(
|
|
86
|
+
pool: Pool,
|
|
87
|
+
slot: bigint,
|
|
88
|
+
dutyType?: 'ATTESTATION' | 'BLOCK_PROPOSAL' | 'GOVERNANCE_VOTE' | 'SLASHING_VOTE',
|
|
89
|
+
): Promise<
|
|
90
|
+
Array<{
|
|
91
|
+
slot: string;
|
|
92
|
+
dutyType: string;
|
|
93
|
+
validatorAddress: string;
|
|
94
|
+
nodeId: string;
|
|
95
|
+
startedAt: Date;
|
|
96
|
+
completedAt: Date | undefined;
|
|
97
|
+
}>
|
|
98
|
+
> {
|
|
99
|
+
const query = dutyType
|
|
100
|
+
? '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'
|
|
101
|
+
: 'SELECT slot, duty_type, validator_address, node_id, started_at, completed_at FROM validator_duties WHERE slot = $1 ORDER BY started_at';
|
|
102
|
+
|
|
103
|
+
const params = dutyType ? [slot.toString(), dutyType] : [slot.toString()];
|
|
104
|
+
|
|
105
|
+
const result = await pool.query<{
|
|
106
|
+
slot: string;
|
|
107
|
+
duty_type: string;
|
|
108
|
+
validator_address: string;
|
|
109
|
+
node_id: string;
|
|
110
|
+
started_at: Date;
|
|
111
|
+
completed_at: Date | undefined;
|
|
112
|
+
}>(query, params);
|
|
113
|
+
|
|
114
|
+
return result.rows.map(row => ({
|
|
115
|
+
slot: row.slot,
|
|
116
|
+
dutyType: row.duty_type,
|
|
117
|
+
validatorAddress: row.validator_address,
|
|
118
|
+
nodeId: row.node_id,
|
|
119
|
+
startedAt: row.started_at,
|
|
120
|
+
completedAt: row.completed_at,
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Convert private keys to Ethereum addresses
|
|
126
|
+
*/
|
|
127
|
+
export function getAddressesFromPrivateKeys(privateKeys: `0x${string}`[]): string[] {
|
|
128
|
+
return privateKeys.map(pk => {
|
|
129
|
+
const account = privateKeyToAccount(pk);
|
|
130
|
+
return account.address;
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Create initial validators from private keys for L1 contract deployment
|
|
136
|
+
*/
|
|
137
|
+
export function createInitialValidatorsFromPrivateKeys(attesterPrivateKeys: `0x${string}`[]): Array<{
|
|
138
|
+
attester: EthAddress;
|
|
139
|
+
withdrawer: EthAddress;
|
|
140
|
+
privateKey: `0x${string}`;
|
|
141
|
+
bn254SecretKey: SecretValue<bigint>;
|
|
142
|
+
}> {
|
|
143
|
+
return attesterPrivateKeys.map(pk => {
|
|
144
|
+
const account = privateKeyToAccount(pk);
|
|
145
|
+
return {
|
|
146
|
+
attester: EthAddress.fromString(account.address),
|
|
147
|
+
withdrawer: EthAddress.fromString(account.address),
|
|
148
|
+
privateKey: pk,
|
|
149
|
+
bn254SecretKey: new SecretValue(Fr.random().toBigInt()),
|
|
150
|
+
};
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Verify no duplicate attestations per validator (HA coordination check)
|
|
156
|
+
* Groups duties by validator address and verifies each validator attested exactly once
|
|
157
|
+
*/
|
|
158
|
+
export function verifyNoDuplicateAttestations(
|
|
159
|
+
attestationDuties: Array<{
|
|
160
|
+
validatorAddress: string;
|
|
161
|
+
nodeId: string;
|
|
162
|
+
completedAt: Date | undefined;
|
|
163
|
+
}>,
|
|
164
|
+
logger?: Logger,
|
|
165
|
+
): Map<string, typeof attestationDuties> {
|
|
166
|
+
const dutiesByValidator = new Map<string, typeof attestationDuties>();
|
|
167
|
+
for (const duty of attestationDuties) {
|
|
168
|
+
const existing = dutiesByValidator.get(duty.validatorAddress) || [];
|
|
169
|
+
existing.push(duty);
|
|
170
|
+
dutiesByValidator.set(duty.validatorAddress, existing);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
for (const [validatorAddress, validatorDuties] of dutiesByValidator.entries()) {
|
|
174
|
+
if (validatorDuties.length !== 1) {
|
|
175
|
+
throw new Error(`Validator ${validatorAddress} attested ${validatorDuties.length} times (expected exactly once)`);
|
|
176
|
+
}
|
|
177
|
+
if (!validatorDuties[0].completedAt) {
|
|
178
|
+
throw new Error(`Validator ${validatorAddress} attestation duty not completed`);
|
|
179
|
+
}
|
|
180
|
+
logger?.info(`Validator ${validatorAddress} attested once via node ${validatorDuties[0].nodeId}`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return dutiesByValidator;
|
|
184
|
+
}
|
package/src/fixtures/index.ts
CHANGED
package/src/fixtures/setup.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SchnorrAccountContractArtifact } from '@aztec/accounts/schnorr';
|
|
2
|
-
import { type InitialAccountData, generateSchnorrAccounts
|
|
2
|
+
import { type InitialAccountData, generateSchnorrAccounts } from '@aztec/accounts/testing';
|
|
3
3
|
import { type Archiver, createArchiver } from '@aztec/archiver';
|
|
4
4
|
import { type AztecNodeConfig, AztecNodeService, getConfigEnvVars } from '@aztec/aztec-node';
|
|
5
5
|
import { AztecAddress, EthAddress } from '@aztec/aztec.js/addresses';
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import { publishContractClass, publishInstance } from '@aztec/aztec.js/deployment';
|
|
14
14
|
import { Fr } from '@aztec/aztec.js/fields';
|
|
15
15
|
import { type Logger, createLogger } from '@aztec/aztec.js/log';
|
|
16
|
-
import {
|
|
16
|
+
import type { AztecNode } from '@aztec/aztec.js/node';
|
|
17
17
|
import type { Wallet } from '@aztec/aztec.js/wallet';
|
|
18
18
|
import { AnvilTestWatcher, CheatCodes } from '@aztec/aztec/testing';
|
|
19
19
|
import { createBlobClientWithFileStores } from '@aztec/blob-client/client';
|
|
@@ -41,7 +41,7 @@ import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types';
|
|
|
41
41
|
import { SecretValue } from '@aztec/foundation/config';
|
|
42
42
|
import { randomBytes } from '@aztec/foundation/crypto/random';
|
|
43
43
|
import { tryRmDir } from '@aztec/foundation/fs';
|
|
44
|
-
import {
|
|
44
|
+
import { withLoggerBindings } from '@aztec/foundation/log/server';
|
|
45
45
|
import { retryUntil } from '@aztec/foundation/retry';
|
|
46
46
|
import { sleep } from '@aztec/foundation/sleep';
|
|
47
47
|
import { DateProvider, TestDateProvider } from '@aztec/foundation/timer';
|
|
@@ -92,9 +92,6 @@ import { getEndToEndTestTelemetryClient } from './with_telemetry_utils.js';
|
|
|
92
92
|
|
|
93
93
|
export { startAnvil };
|
|
94
94
|
|
|
95
|
-
const { AZTEC_NODE_URL = '' } = process.env;
|
|
96
|
-
const getAztecUrl = () => AZTEC_NODE_URL;
|
|
97
|
-
|
|
98
95
|
let telemetry: TelemetryClient | undefined = undefined;
|
|
99
96
|
async function getTelemetryClient(partialConfig: Partial<TelemetryClientConfig> & { benchmark?: boolean } = {}) {
|
|
100
97
|
if (!telemetry) {
|
|
@@ -125,14 +122,14 @@ export async function setupSharedBlobStorage(config: { dataDirectory?: string }
|
|
|
125
122
|
* @param aztecNode - An instance of Aztec Node.
|
|
126
123
|
* @param opts - Partial configuration for the PXE.
|
|
127
124
|
* @param logger - The logger to be used.
|
|
128
|
-
* @param
|
|
125
|
+
* @param actor - Actor label to include in log output (e.g., 'pxe-test').
|
|
129
126
|
* @returns A test wallet, logger and teardown function.
|
|
130
127
|
*/
|
|
131
128
|
export async function setupPXEAndGetWallet(
|
|
132
129
|
aztecNode: AztecNode,
|
|
133
130
|
opts: Partial<PXEConfig> = {},
|
|
134
131
|
logger = getLogger(),
|
|
135
|
-
|
|
132
|
+
actor?: string,
|
|
136
133
|
): Promise<{
|
|
137
134
|
wallet: TestWallet;
|
|
138
135
|
logger: Logger;
|
|
@@ -150,9 +147,7 @@ export async function setupPXEAndGetWallet(
|
|
|
150
147
|
|
|
151
148
|
const teardown = configuredDataDirectory ? () => Promise.resolve() : () => tryRmDir(PXEConfig.dataDirectory!);
|
|
152
149
|
|
|
153
|
-
const wallet = await TestWallet.create(aztecNode, PXEConfig, {
|
|
154
|
-
useLogSuffix,
|
|
155
|
-
});
|
|
150
|
+
const wallet = await TestWallet.create(aztecNode, PXEConfig, { loggerActorLabel: actor });
|
|
156
151
|
|
|
157
152
|
return {
|
|
158
153
|
wallet,
|
|
@@ -209,6 +204,8 @@ export type SetupOptions = {
|
|
|
209
204
|
skipAccountDeployment?: boolean;
|
|
210
205
|
/** L1 contracts deployment arguments. */
|
|
211
206
|
l1ContractsArgs?: Partial<DeployAztecL1ContractsArgs>;
|
|
207
|
+
/** Wallet minimum fee padding multiplier (defaults to 0.5, which is 50% padding). */
|
|
208
|
+
walletMinFeePadding?: number;
|
|
212
209
|
} & Partial<AztecNodeConfig>;
|
|
213
210
|
|
|
214
211
|
/** Context for an end-to-end test as returned by the `setup` function */
|
|
@@ -217,13 +214,13 @@ export type EndToEndContext = {
|
|
|
217
214
|
anvil: Anvil | undefined;
|
|
218
215
|
/** The Aztec Node service or client a connected to it. */
|
|
219
216
|
aztecNode: AztecNode;
|
|
220
|
-
/** The Aztec Node as a service
|
|
221
|
-
aztecNodeService: AztecNodeService
|
|
222
|
-
/** Client to the Aztec Node admin interface
|
|
223
|
-
aztecNodeAdmin: AztecNodeAdmin
|
|
217
|
+
/** The Aztec Node as a service. */
|
|
218
|
+
aztecNodeService: AztecNodeService;
|
|
219
|
+
/** Client to the Aztec Node admin interface. */
|
|
220
|
+
aztecNodeAdmin: AztecNodeAdmin;
|
|
224
221
|
/** The prover node service (only set if startProverNode is true) */
|
|
225
222
|
proverNode: ProverNode | undefined;
|
|
226
|
-
/** A client to the sequencer service
|
|
223
|
+
/** A client to the sequencer service. */
|
|
227
224
|
sequencer: SequencerClient | undefined;
|
|
228
225
|
/** Return values from deployAztecL1Contracts function. */
|
|
229
226
|
deployL1ContractsValues: DeployAztecL1ContractsReturnType;
|
|
@@ -243,12 +240,12 @@ export type EndToEndContext = {
|
|
|
243
240
|
cheatCodes: CheatCodes;
|
|
244
241
|
/** The cheat codes for L1 */
|
|
245
242
|
ethCheatCodes: EthCheatCodes;
|
|
246
|
-
/** The anvil test watcher
|
|
247
|
-
watcher: AnvilTestWatcher
|
|
248
|
-
/** Allows tweaking current system time, used by the epoch cache only
|
|
249
|
-
dateProvider: TestDateProvider
|
|
243
|
+
/** The anvil test watcher. */
|
|
244
|
+
watcher: AnvilTestWatcher;
|
|
245
|
+
/** Allows tweaking current system time, used by the epoch cache only. */
|
|
246
|
+
dateProvider: TestDateProvider;
|
|
250
247
|
/** Telemetry client */
|
|
251
|
-
telemetryClient: TelemetryClient
|
|
248
|
+
telemetryClient: TelemetryClient;
|
|
252
249
|
/** Mock gossip sub network used for gossipping messages (only if mockGossipSubNetwork was set to true in opts) */
|
|
253
250
|
mockGossipSubNetwork: MockGossipSubNetwork | undefined;
|
|
254
251
|
/** Prefilled public data used for setting up nodes. */
|
|
@@ -258,82 +255,11 @@ export type EndToEndContext = {
|
|
|
258
255
|
/** BB config (only set if running locally). */
|
|
259
256
|
bbConfig: Awaited<ReturnType<typeof getBBConfig>>;
|
|
260
257
|
/** Directory to cleanup on teardown. */
|
|
261
|
-
directoryToCleanup: string
|
|
258
|
+
directoryToCleanup: string;
|
|
262
259
|
/** Function to stop the started services. */
|
|
263
260
|
teardown: () => Promise<void>;
|
|
264
261
|
};
|
|
265
262
|
|
|
266
|
-
/**
|
|
267
|
-
* Function to setup the test against a remote deployment. It is assumed that L1 contract are already deployed
|
|
268
|
-
*/
|
|
269
|
-
async function setupWithRemoteEnvironment(
|
|
270
|
-
account: HDAccount | PrivateKeyAccount,
|
|
271
|
-
config: AztecNodeConfig,
|
|
272
|
-
logger: Logger,
|
|
273
|
-
numberOfAccounts: number,
|
|
274
|
-
): Promise<EndToEndContext> {
|
|
275
|
-
const aztecNodeUrl = getAztecUrl();
|
|
276
|
-
logger.verbose(`Creating Aztec Node client to remote host ${aztecNodeUrl}`);
|
|
277
|
-
const aztecNode = createAztecNodeClient(aztecNodeUrl);
|
|
278
|
-
await waitForNode(aztecNode, logger);
|
|
279
|
-
logger.verbose('JSON RPC client connected to Aztec Node');
|
|
280
|
-
logger.verbose(`Retrieving contract addresses from ${aztecNodeUrl}`);
|
|
281
|
-
const { l1ContractAddresses, rollupVersion } = await aztecNode.getNodeInfo();
|
|
282
|
-
|
|
283
|
-
const l1Client = createExtendedL1Client(config.l1RpcUrls, account, foundry);
|
|
284
|
-
|
|
285
|
-
const deployL1ContractsValues: DeployAztecL1ContractsReturnType = {
|
|
286
|
-
l1ContractAddresses,
|
|
287
|
-
l1Client,
|
|
288
|
-
rollupVersion,
|
|
289
|
-
};
|
|
290
|
-
const ethCheatCodes = new EthCheatCodes(config.l1RpcUrls, new DateProvider());
|
|
291
|
-
const wallet = await TestWallet.create(aztecNode);
|
|
292
|
-
const cheatCodes = await CheatCodes.create(config.l1RpcUrls, aztecNode, new DateProvider());
|
|
293
|
-
const teardown = () => Promise.resolve();
|
|
294
|
-
|
|
295
|
-
logger.verbose('Populating wallet from already registered accounts...');
|
|
296
|
-
const initialFundedAccounts = await getInitialTestAccountsData();
|
|
297
|
-
|
|
298
|
-
if (initialFundedAccounts.length < numberOfAccounts) {
|
|
299
|
-
throw new Error(`Required ${numberOfAccounts} accounts. Found ${initialFundedAccounts.length}.`);
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
const testAccounts = await Promise.all(
|
|
303
|
-
initialFundedAccounts.slice(0, numberOfAccounts).map(async account => {
|
|
304
|
-
const accountManager = await wallet.createSchnorrAccount(account.secret, account.salt, account.signingKey);
|
|
305
|
-
return accountManager.address;
|
|
306
|
-
}),
|
|
307
|
-
);
|
|
308
|
-
|
|
309
|
-
return {
|
|
310
|
-
anvil: undefined,
|
|
311
|
-
aztecNode,
|
|
312
|
-
aztecNodeService: undefined,
|
|
313
|
-
aztecNodeAdmin: undefined,
|
|
314
|
-
sequencer: undefined,
|
|
315
|
-
proverNode: undefined,
|
|
316
|
-
deployL1ContractsValues,
|
|
317
|
-
config,
|
|
318
|
-
aztecNodeConfig: config,
|
|
319
|
-
initialFundedAccounts,
|
|
320
|
-
wallet,
|
|
321
|
-
accounts: testAccounts,
|
|
322
|
-
logger,
|
|
323
|
-
cheatCodes,
|
|
324
|
-
ethCheatCodes,
|
|
325
|
-
prefilledPublicData: undefined,
|
|
326
|
-
mockGossipSubNetwork: undefined,
|
|
327
|
-
watcher: undefined,
|
|
328
|
-
dateProvider: undefined,
|
|
329
|
-
telemetryClient: undefined,
|
|
330
|
-
acvmConfig: undefined,
|
|
331
|
-
bbConfig: undefined,
|
|
332
|
-
directoryToCleanup: undefined,
|
|
333
|
-
teardown,
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
|
-
|
|
337
263
|
/**
|
|
338
264
|
* Sets up the environment for the end-to-end tests.
|
|
339
265
|
* @param numberOfAccounts - The number of new accounts to be created once the PXE is initiated.
|
|
@@ -376,16 +302,10 @@ export async function setup(
|
|
|
376
302
|
if (!isAnvilTestChain(chain.id)) {
|
|
377
303
|
throw new Error(`No ETHEREUM_HOSTS set but non anvil chain requested`);
|
|
378
304
|
}
|
|
379
|
-
if (AZTEC_NODE_URL) {
|
|
380
|
-
throw new Error(
|
|
381
|
-
`AZTEC_NODE_URL provided but no ETHEREUM_HOSTS set. Refusing to run, please set both variables so tests can deploy L1 contracts to the same Anvil instance`,
|
|
382
|
-
);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
305
|
const res = await startAnvil({
|
|
386
306
|
l1BlockTime: opts.ethereumSlotDuration,
|
|
387
307
|
accounts: opts.anvilAccounts,
|
|
388
|
-
port: opts.anvilPort,
|
|
308
|
+
port: opts.anvilPort ?? (process.env.ANVIL_PORT ? parseInt(process.env.ANVIL_PORT) : undefined),
|
|
389
309
|
});
|
|
390
310
|
anvil = res.anvil;
|
|
391
311
|
config.l1RpcUrls = [res.rpcUrl];
|
|
@@ -436,11 +356,6 @@ export async function setup(
|
|
|
436
356
|
config.coinbase = EthAddress.fromString(publisherHdAccount.address);
|
|
437
357
|
}
|
|
438
358
|
|
|
439
|
-
if (AZTEC_NODE_URL) {
|
|
440
|
-
// we are setting up against a remote environment, l1 contracts are assumed to already be deployed
|
|
441
|
-
return await setupWithRemoteEnvironment(publisherHdAccount!, config, logger, numberOfAccounts);
|
|
442
|
-
}
|
|
443
|
-
|
|
444
359
|
// Determine which addresses to fund in genesis
|
|
445
360
|
const initialFundedAccounts =
|
|
446
361
|
opts.initialFundedAccounts ??
|
|
@@ -567,10 +482,12 @@ export async function setup(
|
|
|
567
482
|
}
|
|
568
483
|
}
|
|
569
484
|
|
|
570
|
-
const aztecNodeService = await
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
485
|
+
const aztecNodeService = await withLoggerBindings({ actor: 'node-0' }, () =>
|
|
486
|
+
AztecNodeService.createAndSync(
|
|
487
|
+
config,
|
|
488
|
+
{ dateProvider, telemetry: telemetryClient, p2pClientDeps },
|
|
489
|
+
{ prefilledPublicData },
|
|
490
|
+
),
|
|
574
491
|
);
|
|
575
492
|
const sequencerClient = aztecNodeService.getSequencer();
|
|
576
493
|
|
|
@@ -588,7 +505,7 @@ export async function setup(
|
|
|
588
505
|
const proverNodeConfig = {
|
|
589
506
|
...config.proverNodeConfig,
|
|
590
507
|
dataDirectory: proverNodeDataDirectory,
|
|
591
|
-
p2pEnabled:
|
|
508
|
+
p2pEnabled: !!mockGossipSubNetwork,
|
|
592
509
|
};
|
|
593
510
|
proverNode = await createAndSyncProverNode(
|
|
594
511
|
proverNodePrivateKeyHex,
|
|
@@ -596,6 +513,11 @@ export async function setup(
|
|
|
596
513
|
proverNodeConfig,
|
|
597
514
|
aztecNodeService,
|
|
598
515
|
prefilledPublicData,
|
|
516
|
+
{
|
|
517
|
+
p2pClientDeps: mockGossipSubNetwork
|
|
518
|
+
? { p2pServiceFactory: getMockPubSubP2PServiceFactory(mockGossipSubNetwork) }
|
|
519
|
+
: undefined,
|
|
520
|
+
},
|
|
599
521
|
);
|
|
600
522
|
}
|
|
601
523
|
|
|
@@ -604,7 +526,11 @@ export async function setup(
|
|
|
604
526
|
pxeConfig.dataDirectory = path.join(directoryToCleanup, randomBytes(8).toString('hex'));
|
|
605
527
|
// For tests we only want proving enabled if specifically requested
|
|
606
528
|
pxeConfig.proverEnabled = !!pxeOpts.proverEnabled;
|
|
607
|
-
const wallet = await TestWallet.create(aztecNodeService, pxeConfig);
|
|
529
|
+
const wallet = await TestWallet.create(aztecNodeService, pxeConfig, { loggerActorLabel: 'pxe-0' });
|
|
530
|
+
|
|
531
|
+
if (opts.walletMinFeePadding !== undefined) {
|
|
532
|
+
wallet.setMinFeePadding(opts.walletMinFeePadding);
|
|
533
|
+
}
|
|
608
534
|
|
|
609
535
|
const cheatCodes = await CheatCodes.create(config.l1RpcUrls, aztecNodeService, dateProvider);
|
|
610
536
|
|
|
@@ -629,7 +555,7 @@ export async function setup(
|
|
|
629
555
|
`${numberOfAccounts} accounts are being deployed. Reliably progressing past genesis by setting minTxsPerBlock to 1 and waiting for the accounts to be deployed`,
|
|
630
556
|
);
|
|
631
557
|
const accountsData = initialFundedAccounts.slice(0, numberOfAccounts);
|
|
632
|
-
const accountManagers = await deployFundedSchnorrAccounts(wallet,
|
|
558
|
+
const accountManagers = await deployFundedSchnorrAccounts(wallet, accountsData);
|
|
633
559
|
accounts = accountManagers.map(accountManager => accountManager.address);
|
|
634
560
|
} else if (needsEmptyBlock) {
|
|
635
561
|
logger.info('No accounts are being deployed, waiting for an empty block 1 to be mined');
|
|
@@ -672,7 +598,7 @@ export async function setup(
|
|
|
672
598
|
logger.error(`Error during e2e test teardown`, err);
|
|
673
599
|
} finally {
|
|
674
600
|
try {
|
|
675
|
-
await telemetryClient
|
|
601
|
+
await telemetryClient.stop();
|
|
676
602
|
} catch (err) {
|
|
677
603
|
logger.error(`Error during telemetry client stop`, err);
|
|
678
604
|
}
|
|
@@ -786,7 +712,7 @@ export function createAndSyncProverNode(
|
|
|
786
712
|
prefilledPublicData: PublicDataTreeLeaf[] = [],
|
|
787
713
|
proverNodeDeps: ProverNodeDeps = {},
|
|
788
714
|
) {
|
|
789
|
-
return
|
|
715
|
+
return withLoggerBindings({ actor: 'prover-0' }, async () => {
|
|
790
716
|
const aztecNodeTxProvider = aztecNode && {
|
|
791
717
|
getTxByHash: aztecNode.getTxByHash.bind(aztecNode),
|
|
792
718
|
getTxsByHash: aztecNode.getTxsByHash.bind(aztecNode),
|
|
@@ -921,13 +847,11 @@ export async function ensureAccountContractsPublished(wallet: Wallet, accountsTo
|
|
|
921
847
|
).map(contractMetadata => contractMetadata.instance);
|
|
922
848
|
const contractClass = await getContractClassFromArtifact(SchnorrAccountContractArtifact);
|
|
923
849
|
if (!(await wallet.getContractClassMetadata(contractClass.id)).isContractClassPubliclyRegistered) {
|
|
924
|
-
await (await publishContractClass(wallet, SchnorrAccountContractArtifact))
|
|
925
|
-
.send({ from: accountsToDeploy[0] })
|
|
926
|
-
.wait();
|
|
850
|
+
await (await publishContractClass(wallet, SchnorrAccountContractArtifact)).send({ from: accountsToDeploy[0] });
|
|
927
851
|
}
|
|
928
852
|
const requests = instances.map(instance => publishInstance(wallet, instance!));
|
|
929
853
|
const batch = new BatchCall(wallet, requests);
|
|
930
|
-
await batch.send({ from: accountsToDeploy[0] })
|
|
854
|
+
await batch.send({ from: accountsToDeploy[0] });
|
|
931
855
|
}
|
|
932
856
|
|
|
933
857
|
/**
|
|
@@ -951,12 +875,10 @@ export const deployAccounts =
|
|
|
951
875
|
deployedAccounts[i].signingKey,
|
|
952
876
|
);
|
|
953
877
|
const deployMethod = await accountManager.getDeployMethod();
|
|
954
|
-
await deployMethod
|
|
955
|
-
.
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
})
|
|
959
|
-
.wait();
|
|
878
|
+
await deployMethod.send({
|
|
879
|
+
from: AztecAddress.ZERO,
|
|
880
|
+
skipClassPublication: i !== 0, // Publish the contract class at most once.
|
|
881
|
+
});
|
|
960
882
|
}
|
|
961
883
|
|
|
962
884
|
return { deployedAccounts };
|
|
@@ -986,7 +908,7 @@ export async function publicDeployAccounts(
|
|
|
986
908
|
|
|
987
909
|
const batch = new BatchCall(wallet, calls);
|
|
988
910
|
|
|
989
|
-
const txReceipt = await batch.send({ from: accountsToDeploy[0] })
|
|
911
|
+
const txReceipt = await batch.send({ from: accountsToDeploy[0] });
|
|
990
912
|
if (waitUntilProven) {
|
|
991
913
|
if (!node) {
|
|
992
914
|
throw new Error('Need to provide an AztecNode to wait for proven.');
|