@aztec/end-to-end 0.0.1-commit.934299a21 → 0.0.1-commit.949a33fd8
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 +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.js +21 -28
- 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 +3 -2
- 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 +15 -15
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +1 -1
- package/dest/e2e_epochs/epochs_test.d.ts +18 -1
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +61 -10
- 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 +16 -9
- 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 +13 -11
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +65 -43
- package/dest/e2e_p2p/reqresp/utils.d.ts +1 -1
- package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -1
- package/dest/e2e_p2p/reqresp/utils.js +23 -7
- package/dest/e2e_p2p/shared.d.ts +25 -7
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +69 -49
- 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 +11 -11
- package/dest/fixtures/authwit_proxy.d.ts +3 -3
- package/dest/fixtures/authwit_proxy.d.ts.map +1 -1
- package/dest/fixtures/authwit_proxy.js +4 -0
- package/dest/fixtures/e2e_prover_test.d.ts +4 -3
- package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
- package/dest/fixtures/e2e_prover_test.js +11 -16
- package/dest/fixtures/fixtures.d.ts +12 -1
- package/dest/fixtures/fixtures.d.ts.map +1 -1
- package/dest/fixtures/fixtures.js +10 -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 +2 -2
- package/dest/fixtures/ha_setup.d.ts.map +1 -1
- package/dest/fixtures/ha_setup.js +1 -1
- package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts +25 -0
- package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts.map +1 -0
- package/dest/fixtures/schnorr_hardcoded_account_contract.js +39 -0
- package/dest/fixtures/setup.d.ts +24 -13
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +45 -25
- package/dest/fixtures/setup_p2p_test.d.ts +6 -6
- package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.js +8 -8
- 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 +2 -5
- package/dest/forward-compatibility/wallet_rpc_client.d.ts +7 -0
- package/dest/forward-compatibility/wallet_rpc_client.d.ts.map +1 -0
- package/dest/forward-compatibility/wallet_rpc_client.js +15 -0
- package/dest/forward-compatibility/wallet_service.d.ts +3 -0
- package/dest/forward-compatibility/wallet_service.d.ts.map +1 -0
- package/dest/forward-compatibility/wallet_service.js +109 -0
- package/dest/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 +3 -3
- package/dest/shared/jest_setup.js +32 -1
- package/dest/shared/submit-transactions.d.ts +1 -1
- package/dest/shared/submit-transactions.d.ts.map +1 -1
- package/dest/shared/submit-transactions.js +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 +14 -21
- 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 +2 -2
- package/dest/spartan/setup_test_wallets.d.ts +4 -2
- package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
- package/dest/spartan/setup_test_wallets.js +69 -38
- package/dest/spartan/tx_metrics.d.ts +1 -1
- package/dest/spartan/tx_metrics.d.ts.map +1 -1
- package/dest/spartan/tx_metrics.js +19 -3
- 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 +3 -1
- package/dest/spartan/utils/index.d.ts.map +1 -1
- package/dest/spartan/utils/index.js +4 -0
- package/dest/spartan/utils/nodes.js +1 -1
- 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 +24 -23
- package/dest/test-wallet/test_wallet.d.ts.map +1 -1
- package/dest/test-wallet/test_wallet.js +124 -83
- package/dest/test-wallet/worker_wallet.d.ts +4 -4
- package/dest/test-wallet/worker_wallet.d.ts.map +1 -1
- package/dest/test-wallet/worker_wallet_schema.d.ts +10 -5
- package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -1
- package/package.json +43 -44
- package/src/bench/client_flows/client_flows_benchmark.ts +29 -12
- package/src/bench/utils.ts +7 -2
- package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +21 -20
- package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +1 -1
- package/src/e2e_epochs/epochs_test.ts +70 -9
- package/src/e2e_fees/fees_test.ts +17 -8
- package/src/e2e_nested_contract/nested_contract_test.ts +6 -4
- package/src/e2e_p2p/inactivity_slash_test.ts +3 -3
- package/src/e2e_p2p/p2p_network.ts +82 -60
- package/src/e2e_p2p/reqresp/utils.ts +29 -7
- package/src/e2e_p2p/shared.ts +88 -63
- package/src/e2e_token_contract/token_contract_test.ts +16 -8
- package/src/fixtures/authwit_proxy.ts +4 -0
- package/src/fixtures/e2e_prover_test.ts +19 -18
- package/src/fixtures/fixtures.ts +22 -0
- package/src/fixtures/get_bb_config.ts +7 -6
- package/src/fixtures/ha_setup.ts +4 -2
- package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
- package/src/fixtures/setup.ts +69 -33
- package/src/fixtures/setup_p2p_test.ts +9 -9
- package/src/fixtures/token_utils.ts +1 -2
- package/src/forward-compatibility/wallet_rpc_client.ts +14 -0
- package/src/forward-compatibility/wallet_service.ts +104 -0
- package/src/guides/up_quick_start.sh +0 -2
- 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 -2
- package/src/shared/jest_setup.ts +36 -1
- package/src/shared/submit-transactions.ts +1 -4
- package/src/shared/uniswap_l1_l2.ts +35 -32
- package/src/simulators/lending_simulator.ts +8 -4
- package/src/simulators/token_simulator.ts +6 -2
- package/src/spartan/setup_test_wallets.ts +90 -35
- package/src/spartan/tx_metrics.ts +17 -5
- package/src/spartan/utils/config.ts +2 -0
- package/src/spartan/utils/index.ts +6 -0
- package/src/spartan/utils/nodes.ts +1 -1
- package/src/spartan/utils/pod_logs.ts +99 -0
- package/src/test-wallet/test_wallet.ts +152 -101
- package/src/test-wallet/worker_wallet.ts +3 -2
package/src/fixtures/setup.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { SchnorrAccountContractArtifact } from '@aztec/accounts/schnorr';
|
|
2
2
|
import { type InitialAccountData, generateSchnorrAccounts } from '@aztec/accounts/testing';
|
|
3
3
|
import { type AztecNodeConfig, AztecNodeService, getConfigEnvVars } from '@aztec/aztec-node';
|
|
4
|
+
import { NO_FROM } from '@aztec/aztec.js/account';
|
|
4
5
|
import { AztecAddress, EthAddress } from '@aztec/aztec.js/addresses';
|
|
5
6
|
import {
|
|
6
7
|
BatchCall,
|
|
7
8
|
type ContractFunctionInteraction,
|
|
8
9
|
type ContractMethod,
|
|
10
|
+
type DeployInteractionWaitOptions,
|
|
11
|
+
type DeployOptions,
|
|
9
12
|
getContractClassFromArtifact,
|
|
10
13
|
waitForProven,
|
|
11
14
|
} from '@aztec/aztec.js/contracts';
|
|
@@ -14,7 +17,7 @@ import { Fr } from '@aztec/aztec.js/fields';
|
|
|
14
17
|
import { type Logger, createLogger } from '@aztec/aztec.js/log';
|
|
15
18
|
import type { AztecNode } from '@aztec/aztec.js/node';
|
|
16
19
|
import type { Wallet } from '@aztec/aztec.js/wallet';
|
|
17
|
-
import { AnvilTestWatcher, CheatCodes } from '@aztec/aztec/testing';
|
|
20
|
+
import { AnvilTestWatcher, type AnvilTestWatcherOpts, CheatCodes } from '@aztec/aztec/testing';
|
|
18
21
|
import { SPONSORED_FPC_SALT } from '@aztec/constants';
|
|
19
22
|
import { isAnvilTestChain } from '@aztec/ethereum/chain';
|
|
20
23
|
import { createExtendedL1Client } from '@aztec/ethereum/client';
|
|
@@ -30,6 +33,7 @@ import {
|
|
|
30
33
|
} from '@aztec/ethereum/deploy-aztec-l1-contracts';
|
|
31
34
|
import type { Delayer } from '@aztec/ethereum/l1-tx-utils';
|
|
32
35
|
import { EthCheatCodes, EthCheatCodesWithState, startAnvil } from '@aztec/ethereum/test';
|
|
36
|
+
import type { Anvil } from '@aztec/ethereum/test';
|
|
33
37
|
import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types';
|
|
34
38
|
import { SecretValue } from '@aztec/foundation/config';
|
|
35
39
|
import { randomBytes } from '@aztec/foundation/crypto/random';
|
|
@@ -47,10 +51,10 @@ import type { ProverNodeConfig } from '@aztec/prover-node';
|
|
|
47
51
|
import { type PXEConfig, getPXEConfig } from '@aztec/pxe/server';
|
|
48
52
|
import type { SequencerClient } from '@aztec/sequencer-client';
|
|
49
53
|
import { type ContractInstanceWithAddress, getContractInstanceFromInstantiationParams } from '@aztec/stdlib/contract';
|
|
50
|
-
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
54
|
+
import type { AztecNodeAdmin, AztecNodeDebug } from '@aztec/stdlib/interfaces/client';
|
|
51
55
|
import { tryStop } from '@aztec/stdlib/interfaces/server';
|
|
52
|
-
import type { P2PClientType } from '@aztec/stdlib/p2p';
|
|
53
56
|
import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
|
|
57
|
+
import type { GenesisData } from '@aztec/stdlib/world-state';
|
|
54
58
|
import {
|
|
55
59
|
type TelemetryClient,
|
|
56
60
|
type TelemetryClientConfig,
|
|
@@ -61,7 +65,6 @@ import { BenchmarkTelemetryClient } from '@aztec/telemetry-client/bench';
|
|
|
61
65
|
import { deployFundedSchnorrAccounts } from '@aztec/wallets/testing';
|
|
62
66
|
import { getGenesisValues } from '@aztec/world-state/testing';
|
|
63
67
|
|
|
64
|
-
import type { Anvil } from '@viem/anvil';
|
|
65
68
|
import fs from 'fs/promises';
|
|
66
69
|
import { tmpdir } from 'os';
|
|
67
70
|
import path from 'path';
|
|
@@ -178,14 +181,22 @@ export type SetupOptions = {
|
|
|
178
181
|
proverNodeConfig?: Partial<ProverNodeConfig>;
|
|
179
182
|
/** Whether to use a mock gossip sub network for p2p clients. */
|
|
180
183
|
mockGossipSubNetwork?: boolean;
|
|
184
|
+
/** Whether to add simulated latency to the mock gossipsub network (in ms) */
|
|
185
|
+
mockGossipSubNetworkLatency?: number;
|
|
181
186
|
/** Whether to disable the anvil test watcher (can still be manually started) */
|
|
182
187
|
disableAnvilTestWatcher?: boolean;
|
|
188
|
+
anvilTestWatcherOpts?: AnvilTestWatcherOpts;
|
|
183
189
|
/** Whether to enable anvil automine during deployment of L1 contracts (consider defaulting this to true). */
|
|
184
190
|
automineL1Setup?: boolean;
|
|
185
191
|
/** How many accounts to seed and unlock in anvil. */
|
|
186
192
|
anvilAccounts?: number;
|
|
187
193
|
/** Port to start anvil (defaults to 8545) */
|
|
188
194
|
anvilPort?: number;
|
|
195
|
+
/**
|
|
196
|
+
* Number of slots per epoch for Anvil's finality simulation.
|
|
197
|
+
* Anvil reports `finalized = latest - slotsInAnEpoch * 2`.
|
|
198
|
+
*/
|
|
199
|
+
anvilSlotsInAnEpoch?: number;
|
|
189
200
|
/** Key to use for publishing L1 contracts */
|
|
190
201
|
l1PublisherKey?: SecretValue<`0x${string}`>;
|
|
191
202
|
/** ZkPassport configuration (domain, scope, mock verifier) */
|
|
@@ -196,8 +207,11 @@ export type SetupOptions = {
|
|
|
196
207
|
skipAccountDeployment?: boolean;
|
|
197
208
|
/** L1 contracts deployment arguments. */
|
|
198
209
|
l1ContractsArgs?: Partial<DeployAztecL1ContractsArgs>;
|
|
199
|
-
/** Wallet minimum fee padding multiplier
|
|
210
|
+
/** Wallet minimum fee padding multiplier */
|
|
200
211
|
walletMinFeePadding?: number;
|
|
212
|
+
/** Whether the initial node should be a lightweight RPC-only node (no sequencer, no validator).
|
|
213
|
+
* Use for tests that create their own validator nodes and don't need the initial sequencer. */
|
|
214
|
+
skipInitialSequencer?: boolean;
|
|
201
215
|
} & Partial<AztecNodeConfig>;
|
|
202
216
|
|
|
203
217
|
/** Context for an end-to-end test as returned by the `setup` function */
|
|
@@ -205,7 +219,7 @@ export type EndToEndContext = {
|
|
|
205
219
|
/** The Anvil instance (only set if anvil was started locally). */
|
|
206
220
|
anvil: Anvil | undefined;
|
|
207
221
|
/** The Aztec Node service or client a connected to it. */
|
|
208
|
-
aztecNode: AztecNode;
|
|
222
|
+
aztecNode: AztecNode & AztecNodeDebug;
|
|
209
223
|
/** The Aztec Node as a service. */
|
|
210
224
|
aztecNodeService: AztecNodeService;
|
|
211
225
|
/** Client to the Aztec Node admin interface. */
|
|
@@ -244,8 +258,8 @@ export type EndToEndContext = {
|
|
|
244
258
|
sequencerDelayer: Delayer | undefined;
|
|
245
259
|
/** Delayer for prover node L1 txs (only when enableDelayer and startProverNode are true). */
|
|
246
260
|
proverDelayer: Delayer | undefined;
|
|
247
|
-
/**
|
|
248
|
-
|
|
261
|
+
/** Genesis data used for setting up nodes. */
|
|
262
|
+
genesis: GenesisData | undefined;
|
|
249
263
|
/** ACVM config (only set if running locally). */
|
|
250
264
|
acvmConfig: Awaited<ReturnType<typeof getACVMConfig>>;
|
|
251
265
|
/** BB config (only set if running locally). */
|
|
@@ -271,7 +285,7 @@ export async function setup(
|
|
|
271
285
|
let anvil: Anvil | undefined;
|
|
272
286
|
try {
|
|
273
287
|
opts.aztecTargetCommitteeSize ??= 0;
|
|
274
|
-
opts.
|
|
288
|
+
opts.slasherEnabled ??= false;
|
|
275
289
|
|
|
276
290
|
const config: AztecNodeConfig & SetupOptions = { ...getConfigEnvVars(), ...opts };
|
|
277
291
|
// use initialValidators for the node config
|
|
@@ -298,6 +312,8 @@ export async function setup(
|
|
|
298
312
|
config.dataDirectory = directoryToCleanup;
|
|
299
313
|
}
|
|
300
314
|
|
|
315
|
+
const dateProvider = new TestDateProvider();
|
|
316
|
+
|
|
301
317
|
if (!config.l1RpcUrls?.length) {
|
|
302
318
|
if (!isAnvilTestChain(chain.id)) {
|
|
303
319
|
throw new Error(`No ETHEREUM_HOSTS set but non anvil chain requested`);
|
|
@@ -306,6 +322,8 @@ export async function setup(
|
|
|
306
322
|
l1BlockTime: opts.ethereumSlotDuration,
|
|
307
323
|
accounts: opts.anvilAccounts,
|
|
308
324
|
port: opts.anvilPort ?? (process.env.ANVIL_PORT ? parseInt(process.env.ANVIL_PORT) : undefined),
|
|
325
|
+
slotsInAnEpoch: opts.anvilSlotsInAnEpoch,
|
|
326
|
+
dateProvider,
|
|
309
327
|
});
|
|
310
328
|
anvil = res.anvil;
|
|
311
329
|
config.l1RpcUrls = [res.rpcUrl];
|
|
@@ -317,8 +335,6 @@ export async function setup(
|
|
|
317
335
|
logger.info(`Logging metrics to ${filename}`);
|
|
318
336
|
setupMetricsLogger(filename);
|
|
319
337
|
}
|
|
320
|
-
|
|
321
|
-
const dateProvider = new TestDateProvider();
|
|
322
338
|
const ethCheatCodes = new EthCheatCodesWithState(config.l1RpcUrls, dateProvider);
|
|
323
339
|
|
|
324
340
|
if (opts.stateLoad) {
|
|
@@ -368,10 +384,12 @@ export async function setup(
|
|
|
368
384
|
addressesToFund.push(sponsoredFPCAddress);
|
|
369
385
|
}
|
|
370
386
|
|
|
371
|
-
const
|
|
387
|
+
const genesisTimestamp = BigInt(Math.floor(Date.now() / 1000));
|
|
388
|
+
const { genesisArchiveRoot, genesis, fundingNeeded } = await getGenesisValues(
|
|
372
389
|
addressesToFund,
|
|
373
390
|
opts.initialAccountFeeJuice,
|
|
374
391
|
opts.genesisPublicData,
|
|
392
|
+
genesisTimestamp,
|
|
375
393
|
);
|
|
376
394
|
|
|
377
395
|
const wasAutomining = await ethCheatCodes.isAutoMining();
|
|
@@ -414,11 +432,12 @@ export async function setup(
|
|
|
414
432
|
await ethCheatCodes.setIntervalMining(config.ethereumSlotDuration);
|
|
415
433
|
}
|
|
416
434
|
|
|
417
|
-
//
|
|
418
|
-
//
|
|
419
|
-
//
|
|
420
|
-
|
|
421
|
-
|
|
435
|
+
// In compose mode (no local anvil), sync dateProvider to L1 time since it may have drifted
|
|
436
|
+
// ahead of system time due to the local-network watcher warping time forward on each filled slot.
|
|
437
|
+
// When running with a local anvil, the dateProvider is kept in sync via the stdout listener.
|
|
438
|
+
if (!anvil) {
|
|
439
|
+
dateProvider.setTime((await ethCheatCodes.lastBlockTimestamp()) * 1000);
|
|
440
|
+
}
|
|
422
441
|
|
|
423
442
|
if (opts.l2StartTime) {
|
|
424
443
|
await ethCheatCodes.warp(opts.l2StartTime, { resetBlockInterval: true });
|
|
@@ -429,6 +448,7 @@ export async function setup(
|
|
|
429
448
|
deployL1ContractsValues.l1ContractAddresses.rollupAddress,
|
|
430
449
|
deployL1ContractsValues.l1Client,
|
|
431
450
|
dateProvider,
|
|
451
|
+
opts.anvilTestWatcherOpts,
|
|
432
452
|
);
|
|
433
453
|
if (!opts.disableAnvilTestWatcher) {
|
|
434
454
|
await watcher.start();
|
|
@@ -456,10 +476,10 @@ export async function setup(
|
|
|
456
476
|
}
|
|
457
477
|
|
|
458
478
|
let mockGossipSubNetwork: MockGossipSubNetwork | undefined;
|
|
459
|
-
let p2pClientDeps: P2PClientDeps
|
|
479
|
+
let p2pClientDeps: P2PClientDeps | undefined = undefined;
|
|
460
480
|
|
|
461
481
|
if (opts.mockGossipSubNetwork) {
|
|
462
|
-
mockGossipSubNetwork = new MockGossipSubNetwork();
|
|
482
|
+
mockGossipSubNetwork = new MockGossipSubNetwork(opts.mockGossipSubNetworkLatency);
|
|
463
483
|
p2pClientDeps = { p2pServiceFactory: getMockPubSubP2PServiceFactory(mockGossipSubNetwork) };
|
|
464
484
|
}
|
|
465
485
|
|
|
@@ -487,11 +507,22 @@ export async function setup(
|
|
|
487
507
|
}
|
|
488
508
|
}
|
|
489
509
|
|
|
510
|
+
// When skipInitialSequencer is set, the initial node is a lightweight RPC-only node.
|
|
511
|
+
// We apply these overrides to a copy so they don't leak into the returned config.
|
|
512
|
+
// Keep P2P enabled if mockGossipSubNetwork is used (needed for tx propagation to validators).
|
|
513
|
+
const initialNodeConfig = opts.skipInitialSequencer
|
|
514
|
+
? {
|
|
515
|
+
...config,
|
|
516
|
+
disableValidator: true,
|
|
517
|
+
...(opts.mockGossipSubNetwork ? {} : { p2pEnabled: false, bootstrapNodes: [] as string[] }),
|
|
518
|
+
}
|
|
519
|
+
: config;
|
|
520
|
+
|
|
490
521
|
const aztecNodeService = await withLoggerBindings({ actor: 'node-0' }, () =>
|
|
491
522
|
AztecNodeService.createAndSync(
|
|
492
|
-
|
|
523
|
+
initialNodeConfig,
|
|
493
524
|
{ dateProvider, telemetry: telemetryClient, p2pClientDeps },
|
|
494
|
-
{
|
|
525
|
+
{ genesis, dontStartSequencer: opts.skipInitialSequencer },
|
|
495
526
|
),
|
|
496
527
|
);
|
|
497
528
|
const sequencerClient = aztecNodeService.getSequencer();
|
|
@@ -503,7 +534,7 @@ export async function setup(
|
|
|
503
534
|
const proverNodePrivateKeyHex: Hex = `0x${proverNodePrivateKey!.toString('hex')}`;
|
|
504
535
|
const proverNodeDataDirectory = path.join(directoryToCleanup, randomBytes(8).toString('hex'));
|
|
505
536
|
|
|
506
|
-
const p2pClientDeps: Partial<P2PClientDeps
|
|
537
|
+
const p2pClientDeps: Partial<P2PClientDeps> = {
|
|
507
538
|
p2pServiceFactory: mockGossipSubNetwork && getMockPubSubP2PServiceFactory(mockGossipSubNetwork!),
|
|
508
539
|
rpcTxProviders: [aztecNodeService],
|
|
509
540
|
};
|
|
@@ -516,7 +547,7 @@ export async function setup(
|
|
|
516
547
|
dataDirectory: proverNodeDataDirectory,
|
|
517
548
|
},
|
|
518
549
|
{ dateProvider, p2pClientDeps, telemetry: telemetryClient },
|
|
519
|
-
{
|
|
550
|
+
{ genesis },
|
|
520
551
|
));
|
|
521
552
|
}
|
|
522
553
|
|
|
@@ -552,7 +583,9 @@ export async function setup(
|
|
|
552
583
|
|
|
553
584
|
let accounts: AztecAddress[] = [];
|
|
554
585
|
|
|
555
|
-
if (
|
|
586
|
+
if (opts.skipInitialSequencer) {
|
|
587
|
+
logger.info('Sequencer not started on initial node, skipping block progression');
|
|
588
|
+
} else if (shouldDeployAccounts) {
|
|
556
589
|
logger.info(
|
|
557
590
|
`${numberOfAccounts} accounts are being deployed. Reliably progressing past genesis by setting minTxsPerBlock to 1 and waiting for the accounts to be deployed`,
|
|
558
591
|
);
|
|
@@ -621,7 +654,7 @@ export async function setup(
|
|
|
621
654
|
initialFundedAccounts,
|
|
622
655
|
logger,
|
|
623
656
|
mockGossipSubNetwork,
|
|
624
|
-
|
|
657
|
+
genesis,
|
|
625
658
|
proverNode,
|
|
626
659
|
sequencerDelayer,
|
|
627
660
|
proverDelayer,
|
|
@@ -701,7 +734,7 @@ export async function waitForProvenChain(node: AztecNode, targetBlock?: BlockNum
|
|
|
701
734
|
targetBlock ??= await node.getBlockNumber();
|
|
702
735
|
|
|
703
736
|
await retryUntil(
|
|
704
|
-
async () => (await node.
|
|
737
|
+
async () => (await node.getBlockNumber('proven')) >= targetBlock,
|
|
705
738
|
'proven chain status',
|
|
706
739
|
timeoutSec,
|
|
707
740
|
intervalSec,
|
|
@@ -719,9 +752,9 @@ export function createAndSyncProverNode(
|
|
|
719
752
|
deps: {
|
|
720
753
|
telemetry?: TelemetryClient;
|
|
721
754
|
dateProvider: DateProvider;
|
|
722
|
-
p2pClientDeps?: P2PClientDeps
|
|
755
|
+
p2pClientDeps?: P2PClientDeps;
|
|
723
756
|
},
|
|
724
|
-
options: {
|
|
757
|
+
options: { genesis?: GenesisData; dontStart?: boolean },
|
|
725
758
|
): Promise<{ proverNode: AztecNodeService }> {
|
|
726
759
|
return withLoggerBindings({ actor: 'prover-0' }, async () => {
|
|
727
760
|
const proverNode = await AztecNodeService.createAndSync(
|
|
@@ -734,7 +767,7 @@ export function createAndSyncProverNode(
|
|
|
734
767
|
proverPublisherPrivateKeys: [new SecretValue(proverNodePrivateKey)],
|
|
735
768
|
},
|
|
736
769
|
deps,
|
|
737
|
-
{
|
|
770
|
+
{ genesis: options.genesis, dontStartProverNode: options.dontStart },
|
|
738
771
|
);
|
|
739
772
|
|
|
740
773
|
if (!proverNode.getProverNode()) {
|
|
@@ -754,7 +787,9 @@ export function getBalancesFn(
|
|
|
754
787
|
): (...addresses: (AztecAddress | { address: AztecAddress })[]) => Promise<bigint[]> {
|
|
755
788
|
const balances = async (...addressLikes: (AztecAddress | { address: AztecAddress })[]) => {
|
|
756
789
|
const addresses = addressLikes.map(addressLike => ('address' in addressLike ? addressLike.address : addressLike));
|
|
757
|
-
const b = await Promise.all(
|
|
790
|
+
const b = await Promise.all(
|
|
791
|
+
addresses.map(async address => (await method(address).simulate({ from: address })).result),
|
|
792
|
+
);
|
|
758
793
|
const debugString = `${symbol} balances: ${addresses.map((address, i) => `${address}: ${b[i]}`).join(', ')}`;
|
|
759
794
|
logger.verbose(debugString);
|
|
760
795
|
return b;
|
|
@@ -823,7 +858,7 @@ export async function ensureAccountContractsPublished(wallet: Wallet, accountsTo
|
|
|
823
858
|
* Returns deployed account data that can be used by tests.
|
|
824
859
|
*/
|
|
825
860
|
export const deployAccounts =
|
|
826
|
-
(numberOfAccounts: number, logger: Logger) =>
|
|
861
|
+
(numberOfAccounts: number, logger: Logger, deployOptions?: Partial<DeployOptions<DeployInteractionWaitOptions>>) =>
|
|
827
862
|
async ({ wallet, initialFundedAccounts }: { wallet: TestWallet; initialFundedAccounts: InitialAccountData[] }) => {
|
|
828
863
|
if (initialFundedAccounts.length < numberOfAccounts) {
|
|
829
864
|
throw new Error(`Cannot deploy more than ${initialFundedAccounts.length} initial accounts.`);
|
|
@@ -840,8 +875,9 @@ export const deployAccounts =
|
|
|
840
875
|
);
|
|
841
876
|
const deployMethod = await accountManager.getDeployMethod();
|
|
842
877
|
await deployMethod.send({
|
|
843
|
-
from:
|
|
878
|
+
from: NO_FROM,
|
|
844
879
|
skipClassPublication: i !== 0, // Publish the contract class at most once.
|
|
880
|
+
...deployOptions,
|
|
845
881
|
});
|
|
846
882
|
}
|
|
847
883
|
|
|
@@ -872,7 +908,7 @@ export async function publicDeployAccounts(
|
|
|
872
908
|
|
|
873
909
|
const batch = new BatchCall(wallet, calls);
|
|
874
910
|
|
|
875
|
-
const txReceipt = await batch.send({ from: accountsToDeploy[0] });
|
|
911
|
+
const { receipt: txReceipt } = await batch.send({ from: accountsToDeploy[0] });
|
|
876
912
|
if (waitUntilProven) {
|
|
877
913
|
if (!node) {
|
|
878
914
|
throw new Error('Need to provide an AztecNode to wait for proven.');
|
|
@@ -7,7 +7,7 @@ import { SecretValue } from '@aztec/foundation/config';
|
|
|
7
7
|
import { withLoggerBindings } from '@aztec/foundation/log/server';
|
|
8
8
|
import { bufferToHex } from '@aztec/foundation/string';
|
|
9
9
|
import type { DateProvider } from '@aztec/foundation/timer';
|
|
10
|
-
import type {
|
|
10
|
+
import type { GenesisData } from '@aztec/stdlib/world-state';
|
|
11
11
|
|
|
12
12
|
import getPort from 'get-port';
|
|
13
13
|
|
|
@@ -40,7 +40,7 @@ export async function createNodes(
|
|
|
40
40
|
bootstrapNodeEnr: string,
|
|
41
41
|
numNodes: number,
|
|
42
42
|
bootNodePort: number,
|
|
43
|
-
|
|
43
|
+
genesis?: GenesisData,
|
|
44
44
|
dataDirectory?: string,
|
|
45
45
|
metricsPort?: number,
|
|
46
46
|
indexOffset = 0,
|
|
@@ -65,7 +65,7 @@ export async function createNodes(
|
|
|
65
65
|
port,
|
|
66
66
|
bootstrapNodeEnr,
|
|
67
67
|
validatorIndices,
|
|
68
|
-
|
|
68
|
+
genesis,
|
|
69
69
|
dataDir,
|
|
70
70
|
metricsPort,
|
|
71
71
|
);
|
|
@@ -97,7 +97,7 @@ export async function createNode(
|
|
|
97
97
|
tcpPort: number,
|
|
98
98
|
bootstrapNode: string | undefined,
|
|
99
99
|
addressIndex: number | number[],
|
|
100
|
-
|
|
100
|
+
genesis?: GenesisData,
|
|
101
101
|
dataDirectory?: string,
|
|
102
102
|
metricsPort?: number,
|
|
103
103
|
) {
|
|
@@ -108,7 +108,7 @@ export async function createNode(
|
|
|
108
108
|
return await AztecNodeService.createAndSync(
|
|
109
109
|
validatorConfig,
|
|
110
110
|
{ telemetry, dateProvider },
|
|
111
|
-
{
|
|
111
|
+
{ genesis, dontStartSequencer: config.dontStartSequencer },
|
|
112
112
|
);
|
|
113
113
|
});
|
|
114
114
|
}
|
|
@@ -119,7 +119,7 @@ export async function createNonValidatorNode(
|
|
|
119
119
|
dateProvider: DateProvider,
|
|
120
120
|
tcpPort: number,
|
|
121
121
|
bootstrapNode: string | undefined,
|
|
122
|
-
|
|
122
|
+
genesis?: GenesisData,
|
|
123
123
|
dataDirectory?: string,
|
|
124
124
|
metricsPort?: number,
|
|
125
125
|
) {
|
|
@@ -133,7 +133,7 @@ export async function createNonValidatorNode(
|
|
|
133
133
|
sequencerPublisherPrivateKeys: [],
|
|
134
134
|
};
|
|
135
135
|
const telemetry = await getEndToEndTestTelemetryClient(metricsPort);
|
|
136
|
-
return await AztecNodeService.createAndSync(config, { telemetry, dateProvider }, {
|
|
136
|
+
return await AztecNodeService.createAndSync(config, { telemetry, dateProvider }, { genesis });
|
|
137
137
|
});
|
|
138
138
|
}
|
|
139
139
|
|
|
@@ -143,7 +143,7 @@ export async function createProverNode(
|
|
|
143
143
|
bootstrapNode: string | undefined,
|
|
144
144
|
addressIndex: number,
|
|
145
145
|
deps: { dateProvider: DateProvider },
|
|
146
|
-
|
|
146
|
+
genesis?: GenesisData,
|
|
147
147
|
dataDirectory?: string,
|
|
148
148
|
metricsPort?: number,
|
|
149
149
|
): Promise<{ proverNode: AztecNodeService }> {
|
|
@@ -159,7 +159,7 @@ export async function createProverNode(
|
|
|
159
159
|
{ ...config, ...p2pConfig },
|
|
160
160
|
{ dataDirectory },
|
|
161
161
|
{ ...deps, telemetry },
|
|
162
|
-
{
|
|
162
|
+
{ genesis },
|
|
163
163
|
);
|
|
164
164
|
});
|
|
165
165
|
}
|
|
@@ -8,7 +8,6 @@ export async function deployToken(wallet: Wallet, admin: AztecAddress, initialAd
|
|
|
8
8
|
logger.info(`Deploying Token contract...`);
|
|
9
9
|
const { contract, instance } = await TokenContract.deploy(wallet, admin, 'TokenName', 'TokenSymbol', 18).send({
|
|
10
10
|
from: admin,
|
|
11
|
-
wait: { returnReceipt: true },
|
|
12
11
|
});
|
|
13
12
|
|
|
14
13
|
if (initialAdminBalance > 0n) {
|
|
@@ -39,7 +38,7 @@ export async function expectTokenBalance(
|
|
|
39
38
|
) {
|
|
40
39
|
// Then check the balance
|
|
41
40
|
const contractWithWallet = TokenContract.at(token.address, wallet);
|
|
42
|
-
const balance = await contractWithWallet.methods.balance_of_private(owner).simulate({ from: owner });
|
|
41
|
+
const { result: balance } = await contractWithWallet.methods.balance_of_private(owner).simulate({ from: owner });
|
|
43
42
|
logger.info(`Account ${owner} balance: ${balance}`);
|
|
44
43
|
expect(balance).toBe(expectedBalance);
|
|
45
44
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Wallet } from '@aztec/aztec.js/wallet';
|
|
2
|
+
import { WalletSchema } from '@aztec/aztec.js/wallet';
|
|
3
|
+
import { createSafeJsonRpcClient, makeFetch } from '@aztec/foundation/json-rpc/client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a JSON-RPC client that connects to a remote wallet service.
|
|
7
|
+
* The returned object implements the {@link Wallet} interface, proxying all calls over HTTP to the specified URL.
|
|
8
|
+
*/
|
|
9
|
+
export function createWalletClient(url: string): Wallet {
|
|
10
|
+
return createSafeJsonRpcClient<Wallet>(url, WalletSchema, {
|
|
11
|
+
namespaceMethods: 'wallet',
|
|
12
|
+
fetch: makeFetch([1, 2, 3], false),
|
|
13
|
+
});
|
|
14
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env -S node --no-warnings
|
|
2
|
+
/**
|
|
3
|
+
* Standalone entrypoint that spins up a local Aztec network (L1 + node) and exposes a {@link NodeEmbeddedWallet} over
|
|
4
|
+
* JSON-RPC.
|
|
5
|
+
*
|
|
6
|
+
* Intended for forward-compatibility testing: an **old** release image runs this script so that **new** tests can send
|
|
7
|
+
* new artifacts to old runtime code (loadContractArtifact, ACIR simulator, class-ID computation, entrypoint encoding,
|
|
8
|
+
* etc.).
|
|
9
|
+
*/
|
|
10
|
+
import { getSchnorrAccountContractAddress } from '@aztec/accounts/schnorr';
|
|
11
|
+
import { getInitialTestAccountsData } from '@aztec/accounts/testing';
|
|
12
|
+
import { createLocalNetwork } from '@aztec/aztec';
|
|
13
|
+
import { Fr } from '@aztec/aztec.js/fields';
|
|
14
|
+
import { WalletSchema } from '@aztec/aztec.js/wallet';
|
|
15
|
+
import { GrumpkinScalar } from '@aztec/foundation/curves/grumpkin';
|
|
16
|
+
import { createNamespacedSafeJsonRpcServer, startHttpRpcServer } from '@aztec/foundation/json-rpc/server';
|
|
17
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
18
|
+
import { AztecNodeApiSchema } from '@aztec/stdlib/interfaces/client';
|
|
19
|
+
import { EmbeddedWallet } from '@aztec/wallets/embedded';
|
|
20
|
+
|
|
21
|
+
const logger = createLogger('wallet-service');
|
|
22
|
+
|
|
23
|
+
const { ETHEREUM_HOSTS = 'http://localhost:8545', NODE_PORT = '8080', WALLET_PORT = '8081' } = process.env;
|
|
24
|
+
|
|
25
|
+
async function main() {
|
|
26
|
+
const l1RpcUrls = ETHEREUM_HOSTS.split(',').map(url => url.trim());
|
|
27
|
+
|
|
28
|
+
// Some tests (e.g. AMM) need 4 accounts but only 3 are funded via genesis. Generate deterministic keys for a 4th
|
|
29
|
+
// account so we can compute its address before network startup and include it in genesis funding. We cannot do this
|
|
30
|
+
// in the test because Wallet interface does not expose account creation functionality (only TestWallet exposes that
|
|
31
|
+
// but that's not used in forward compatibility testing).
|
|
32
|
+
const extraAccountSecret = Fr.fromHexString('0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef');
|
|
33
|
+
const extraAccountSalt = Fr.ZERO;
|
|
34
|
+
const extraAccountSigningKey = GrumpkinScalar.random();
|
|
35
|
+
const extraAccountAddress = await getSchnorrAccountContractAddress(
|
|
36
|
+
extraAccountSecret,
|
|
37
|
+
extraAccountSalt,
|
|
38
|
+
extraAccountSigningKey,
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
logger.info('Starting wallet service...', { l1RpcUrls });
|
|
42
|
+
|
|
43
|
+
// createLocalNetwork deploys L1 contracts, starts the node, and optionally deploys funded test accounts (when
|
|
44
|
+
// TEST_ACCOUNTS=true via env). We are not proving anything just like is done when local network is started by
|
|
45
|
+
// the `aztecStart` function. The extra account address is passed via prefundAddresses so it gets fee juice at genesis.
|
|
46
|
+
const { node, stop: stopNetwork } = await createLocalNetwork(
|
|
47
|
+
{ l1RpcUrls, realProofs: false, prefundAddresses: [extraAccountAddress.toString()] },
|
|
48
|
+
logger.info,
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// Create an ephemeral embedded wallet backed by the local node.
|
|
52
|
+
const wallet = await EmbeddedWallet.create(node, { ephemeral: true });
|
|
53
|
+
|
|
54
|
+
// Re-register the initial test accounts so they are available via wallet.getAccounts(). createLocalNetwork deploys
|
|
55
|
+
// them onchain but uses a temporary wallet that is then stopped.
|
|
56
|
+
//
|
|
57
|
+
// We use the non-lazy import path (@aztec/accounts/testing, not /lazy) to avoid the dynamic JSON import that is
|
|
58
|
+
// incompatible with Node.js import attribute enforcement.
|
|
59
|
+
const testAccountsData = await getInitialTestAccountsData();
|
|
60
|
+
const accounts = await Promise.all(
|
|
61
|
+
testAccountsData.map(({ secret, salt, signingKey }) => wallet.createSchnorrAccount(secret, salt, signingKey)),
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
// Register and deploy the 4th account.
|
|
65
|
+
const extraAccount = await wallet.createSchnorrAccount(extraAccountSecret, extraAccountSalt, extraAccountSigningKey);
|
|
66
|
+
const deployMethod = await extraAccount.getDeployMethod();
|
|
67
|
+
await deployMethod.send({ from: accounts[0].address });
|
|
68
|
+
|
|
69
|
+
logger.info('Embedded wallet created', {
|
|
70
|
+
accounts: [...accounts, extraAccount].map(a => a.address.toString()),
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Contract artifacts are large, so allow generous body sizes for RPC requests.
|
|
74
|
+
const rpcOptions = { maxBodySizeBytes: '50mb' };
|
|
75
|
+
|
|
76
|
+
// Serve node RPC
|
|
77
|
+
const nodeRpcServer = createNamespacedSafeJsonRpcServer({ node: [node, AztecNodeApiSchema] }, rpcOptions);
|
|
78
|
+
const nodeHttpServer = await startHttpRpcServer(nodeRpcServer, { port: NODE_PORT });
|
|
79
|
+
logger.info(`Node JSON-RPC server listening on port ${nodeHttpServer.port}`);
|
|
80
|
+
|
|
81
|
+
// Serve wallet RPC
|
|
82
|
+
const walletRpcServer = createNamespacedSafeJsonRpcServer({ wallet: [wallet, WalletSchema] }, rpcOptions);
|
|
83
|
+
const walletHttpServer = await startHttpRpcServer(walletRpcServer, { port: WALLET_PORT });
|
|
84
|
+
logger.info(`Wallet JSON-RPC server listening on port ${walletHttpServer.port}`);
|
|
85
|
+
|
|
86
|
+
const shutdown = async () => {
|
|
87
|
+
logger.info('Shutting down...');
|
|
88
|
+
nodeHttpServer.close();
|
|
89
|
+
walletHttpServer.close();
|
|
90
|
+
await wallet.stop();
|
|
91
|
+
await stopNetwork();
|
|
92
|
+
process.exit(0);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
96
|
+
process.once('SIGINT', shutdown);
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
98
|
+
process.once('SIGTERM', shutdown);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
main().catch(err => {
|
|
102
|
+
logger.error('Wallet service failed to start', err);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
});
|
|
@@ -18,10 +18,8 @@ aztec-wallet() {
|
|
|
18
18
|
|
|
19
19
|
aztec-wallet import-test-accounts
|
|
20
20
|
|
|
21
|
-
# docs:start:declare-accounts
|
|
22
21
|
aztec-wallet create-account -a alice -f test0
|
|
23
22
|
aztec-wallet create-account -a bob -f test0
|
|
24
|
-
# docs:end:declare-accounts
|
|
25
23
|
|
|
26
24
|
aztec-wallet bridge-fee-juice 1000000000000000000000 accounts:alice --mint --no-wait
|
|
27
25
|
|