@aztec/end-to-end 2.0.0-nightly.20250825 → 2.0.0-nightly.20250827
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/e2e_epochs/epochs_test.d.ts +1 -1
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +8 -3
- package/dest/e2e_fees/fees_test.d.ts.map +1 -1
- package/dest/e2e_fees/fees_test.js +1 -5
- package/dest/e2e_multi_validator/utils.d.ts +12 -0
- package/dest/e2e_multi_validator/utils.d.ts.map +1 -0
- package/dest/e2e_multi_validator/utils.js +220 -0
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +2 -2
- package/dest/fixtures/e2e_prover_test.js +4 -2
- package/dest/fixtures/setup_p2p_test.js +3 -1
- package/dest/fixtures/snapshot_manager.d.ts.map +1 -1
- package/dest/fixtures/snapshot_manager.js +9 -6
- package/dest/fixtures/utils.d.ts +6 -1
- package/dest/fixtures/utils.d.ts.map +1 -1
- package/dest/fixtures/utils.js +27 -9
- package/package.json +36 -35
- package/src/e2e_epochs/epochs_test.ts +11 -4
- package/src/e2e_fees/fees_test.ts +1 -2
- package/src/e2e_multi_validator/utils.ts +264 -0
- package/src/e2e_p2p/p2p_network.ts +2 -2
- package/src/fixtures/e2e_prover_test.ts +2 -2
- package/src/fixtures/setup_p2p_test.ts +1 -1
- package/src/fixtures/snapshot_manager.ts +6 -3
- package/src/fixtures/utils.ts +39 -9
- package/dest/sample-dapp/connect.d.mts +0 -2
- package/dest/sample-dapp/connect.d.mts.map +0 -1
- package/dest/sample-dapp/connect.js +0 -12
- package/dest/sample-dapp/contracts.d.mts +0 -3
- package/dest/sample-dapp/contracts.d.mts.map +0 -1
- package/dest/sample-dapp/contracts.js +0 -10
- package/dest/sample-dapp/deploy.d.mts +0 -3
- package/dest/sample-dapp/deploy.d.mts.map +0 -1
- package/dest/sample-dapp/deploy.js +0 -39
- package/dest/sample-dapp/index.d.mts +0 -2
- package/dest/sample-dapp/index.d.mts.map +0 -1
- package/dest/sample-dapp/index.js +0 -108
- package/src/sample-dapp/connect.mjs +0 -16
- package/src/sample-dapp/contracts.mjs +0 -14
- package/src/sample-dapp/deploy.mjs +0 -42
- package/src/sample-dapp/index.mjs +0 -131
package/dest/fixtures/utils.js
CHANGED
|
@@ -9,7 +9,7 @@ import { createBlobSinkClient } from '@aztec/blob-sink/client';
|
|
|
9
9
|
import { createBlobSinkServer } from '@aztec/blob-sink/server';
|
|
10
10
|
import { GENESIS_ARCHIVE_ROOT, SPONSORED_FPC_SALT } from '@aztec/constants';
|
|
11
11
|
import { FeeAssetArtifact, NULL_KEY, RollupContract, createExtendedL1Client, deployL1Contracts, deployMulticall3, getL1ContractsConfigEnvVars, isAnvilTestChain } from '@aztec/ethereum';
|
|
12
|
-
import { DelayedTxUtils, EthCheatCodesWithState, startAnvil } from '@aztec/ethereum/test';
|
|
12
|
+
import { DelayedTxUtils, EthCheatCodes, EthCheatCodesWithState, createDelayedL1TxUtilsFromViemWallet, startAnvil } from '@aztec/ethereum/test';
|
|
13
13
|
import { SecretValue } from '@aztec/foundation/config';
|
|
14
14
|
import { randomBytes } from '@aztec/foundation/crypto';
|
|
15
15
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
@@ -36,7 +36,7 @@ import getPort from 'get-port';
|
|
|
36
36
|
import { tmpdir } from 'os';
|
|
37
37
|
import * as path from 'path';
|
|
38
38
|
import { getContract } from 'viem';
|
|
39
|
-
import { mnemonicToAccount, privateKeyToAccount } from 'viem/accounts';
|
|
39
|
+
import { generatePrivateKey, mnemonicToAccount, privateKeyToAccount } from 'viem/accounts';
|
|
40
40
|
import { foundry } from 'viem/chains';
|
|
41
41
|
import { MNEMONIC, TEST_PEER_CHECK_INTERVAL_MS } from './fixtures.js';
|
|
42
42
|
import { getACVMConfig } from './get_acvm_config.js';
|
|
@@ -143,6 +143,7 @@ export const setupL1Contracts = async (l1RpcUrls, account, logger, args = {}, ch
|
|
|
143
143
|
l1Client,
|
|
144
144
|
rollupVersion
|
|
145
145
|
};
|
|
146
|
+
const ethCheatCodes = new EthCheatCodes(config.l1RpcUrls);
|
|
146
147
|
const cheatCodes = await CheatCodes.create(config.l1RpcUrls, pxeClient);
|
|
147
148
|
const teardown = ()=>Promise.resolve();
|
|
148
149
|
logger.verbose('Constructing available wallets from already registered accounts...');
|
|
@@ -166,6 +167,7 @@ export const setupL1Contracts = async (l1RpcUrls, account, logger, args = {}, ch
|
|
|
166
167
|
accounts: wallets.slice(0, numberOfAccounts).map((w)=>w.getAddress()),
|
|
167
168
|
logger,
|
|
168
169
|
cheatCodes,
|
|
170
|
+
ethCheatCodes,
|
|
169
171
|
prefilledPublicData: undefined,
|
|
170
172
|
mockGossipSubNetwork: undefined,
|
|
171
173
|
watcher: undefined,
|
|
@@ -240,8 +242,10 @@ export const setupL1Contracts = async (l1RpcUrls, account, logger, args = {}, ch
|
|
|
240
242
|
}
|
|
241
243
|
let publisherPrivKey = undefined;
|
|
242
244
|
let publisherHdAccount = undefined;
|
|
243
|
-
if (
|
|
244
|
-
publisherHdAccount = privateKeyToAccount(
|
|
245
|
+
if (opts.l1PublisherKey && opts.l1PublisherKey.getValue() && opts.l1PublisherKey.getValue() != NULL_KEY) {
|
|
246
|
+
publisherHdAccount = privateKeyToAccount(opts.l1PublisherKey.getValue());
|
|
247
|
+
} else if (config.publisherPrivateKeys && config.publisherPrivateKeys.length > 0 && config.publisherPrivateKeys[0].getValue() != NULL_KEY) {
|
|
248
|
+
publisherHdAccount = privateKeyToAccount(config.publisherPrivateKeys[0].getValue());
|
|
245
249
|
} else if (!MNEMONIC) {
|
|
246
250
|
throw new Error(`Mnemonic not provided and no publisher private key`);
|
|
247
251
|
} else {
|
|
@@ -250,8 +254,11 @@ export const setupL1Contracts = async (l1RpcUrls, account, logger, args = {}, ch
|
|
|
250
254
|
});
|
|
251
255
|
const publisherPrivKeyRaw = publisherHdAccount.getHdKey().privateKey;
|
|
252
256
|
publisherPrivKey = publisherPrivKeyRaw === null ? null : Buffer.from(publisherPrivKeyRaw);
|
|
253
|
-
config.
|
|
257
|
+
config.publisherPrivateKeys = [
|
|
258
|
+
new SecretValue(`0x${publisherPrivKey.toString('hex')}`)
|
|
259
|
+
];
|
|
254
260
|
}
|
|
261
|
+
config.coinbase = EthAddress.fromString(publisherHdAccount.address);
|
|
255
262
|
if (PXE_URL) {
|
|
256
263
|
// we are setting up against a remote environment, l1 contracts are assumed to already be deployed
|
|
257
264
|
return await setupWithRemoteEnvironment(publisherHdAccount, config, logger, numberOfAccounts);
|
|
@@ -365,6 +372,13 @@ export const setupL1Contracts = async (l1RpcUrls, account, logger, args = {}, ch
|
|
|
365
372
|
config.minTxsPerBlock = numberOfAccounts === 0 ? 0 : 1;
|
|
366
373
|
config.p2pEnabled = opts.mockGossipSubNetwork || config.p2pEnabled;
|
|
367
374
|
config.p2pIp = opts.p2pIp ?? config.p2pIp ?? '127.0.0.1';
|
|
375
|
+
if (!config.disableValidator) {
|
|
376
|
+
if ((config.validatorPrivateKeys?.getValue().length ?? 0) === 0) {
|
|
377
|
+
config.validatorPrivateKeys = new SecretValue([
|
|
378
|
+
generatePrivateKey()
|
|
379
|
+
]);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
368
382
|
const aztecNode = await AztecNodeService.createAndSync(config, {
|
|
369
383
|
dateProvider,
|
|
370
384
|
blobSinkClient,
|
|
@@ -377,7 +391,7 @@ export const setupL1Contracts = async (l1RpcUrls, account, logger, args = {}, ch
|
|
|
377
391
|
const sequencerClient = aztecNode.getSequencer();
|
|
378
392
|
if (sequencerClient) {
|
|
379
393
|
const publisher = sequencerClient.sequencer.publisher;
|
|
380
|
-
publisher.l1TxUtils = DelayedTxUtils.fromL1TxUtils(publisher.l1TxUtils, config.ethereumSlotDuration);
|
|
394
|
+
publisher.l1TxUtils = DelayedTxUtils.fromL1TxUtils(publisher.l1TxUtils, config.ethereumSlotDuration, l1Client);
|
|
381
395
|
}
|
|
382
396
|
let proverNode = undefined;
|
|
383
397
|
if (opts.startProverNode) {
|
|
@@ -434,8 +448,8 @@ export const setupL1Contracts = async (l1RpcUrls, account, logger, args = {}, ch
|
|
|
434
448
|
if (bbConfig?.cleanup) {
|
|
435
449
|
await bbConfig.cleanup();
|
|
436
450
|
}
|
|
437
|
-
await tryStop(anvil, logger);
|
|
438
451
|
await tryStop(watcher, logger);
|
|
452
|
+
await tryStop(anvil, logger);
|
|
439
453
|
await tryStop(blobSink, logger);
|
|
440
454
|
await tryRmDir(directoryToCleanup, logger);
|
|
441
455
|
} catch (err) {
|
|
@@ -447,6 +461,7 @@ export const setupL1Contracts = async (l1RpcUrls, account, logger, args = {}, ch
|
|
|
447
461
|
aztecNodeAdmin: aztecNode,
|
|
448
462
|
blobSink,
|
|
449
463
|
cheatCodes,
|
|
464
|
+
ethCheatCodes,
|
|
450
465
|
config,
|
|
451
466
|
dateProvider,
|
|
452
467
|
deployL1ContractsValues,
|
|
@@ -620,7 +635,9 @@ export function createAndSyncProverNode(proverNodePrivateKey, aztecNodeConfig, p
|
|
|
620
635
|
txCollectionNodeRpcUrls: [],
|
|
621
636
|
realProofs: false,
|
|
622
637
|
proverAgentCount: 2,
|
|
623
|
-
|
|
638
|
+
publisherPrivateKeys: [
|
|
639
|
+
new SecretValue(proverNodePrivateKey)
|
|
640
|
+
],
|
|
624
641
|
proverNodeMaxPendingJobs: 10,
|
|
625
642
|
proverNodeMaxParallelBlocksPerEpoch: 32,
|
|
626
643
|
proverNodePollingIntervalMs: 200,
|
|
@@ -629,6 +646,7 @@ export function createAndSyncProverNode(proverNodePrivateKey, aztecNodeConfig, p
|
|
|
629
646
|
txGatheringMaxParallelRequestsPerNode: 10,
|
|
630
647
|
txGatheringTimeoutMs: 24_000,
|
|
631
648
|
proverNodeFailedEpochStore: undefined,
|
|
649
|
+
proverId: EthAddress.fromNumber(1),
|
|
632
650
|
...proverNodeConfig
|
|
633
651
|
};
|
|
634
652
|
const l1TxUtils = createDelayedL1TxUtils(aztecNodeConfig, proverNodePrivateKey, 'prover-node', proverNodeDeps.dateProvider);
|
|
@@ -650,7 +668,7 @@ export function createAndSyncProverNode(proverNodePrivateKey, aztecNodeConfig, p
|
|
|
650
668
|
function createDelayedL1TxUtils(aztecNodeConfig, privateKey, logName, dateProvider) {
|
|
651
669
|
const l1Client = createExtendedL1Client(aztecNodeConfig.l1RpcUrls, privateKey, foundry);
|
|
652
670
|
const log = createLogger(logName);
|
|
653
|
-
const l1TxUtils =
|
|
671
|
+
const l1TxUtils = createDelayedL1TxUtilsFromViemWallet(l1Client, log, dateProvider, aztecNodeConfig);
|
|
654
672
|
l1TxUtils.enableDelayer(aztecNodeConfig.ethereumSlotDuration);
|
|
655
673
|
return l1TxUtils;
|
|
656
674
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/end-to-end",
|
|
3
|
-
"version": "2.0.0-nightly.
|
|
3
|
+
"version": "2.0.0-nightly.20250827",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./dest/index.js",
|
|
6
6
|
"inherits": [
|
|
@@ -25,40 +25,41 @@
|
|
|
25
25
|
"formatting": "run -T prettier --check ./src && run -T eslint ./src"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@aztec/accounts": "2.0.0-nightly.
|
|
29
|
-
"@aztec/archiver": "2.0.0-nightly.
|
|
30
|
-
"@aztec/aztec": "2.0.0-nightly.
|
|
31
|
-
"@aztec/aztec-node": "2.0.0-nightly.
|
|
32
|
-
"@aztec/aztec.js": "2.0.0-nightly.
|
|
33
|
-
"@aztec/bb-prover": "2.0.0-nightly.
|
|
34
|
-
"@aztec/blob-lib": "2.0.0-nightly.
|
|
35
|
-
"@aztec/blob-sink": "2.0.0-nightly.
|
|
36
|
-
"@aztec/bot": "2.0.0-nightly.
|
|
37
|
-
"@aztec/cli": "2.0.0-nightly.
|
|
38
|
-
"@aztec/constants": "2.0.0-nightly.
|
|
39
|
-
"@aztec/entrypoints": "2.0.0-nightly.
|
|
40
|
-
"@aztec/epoch-cache": "2.0.0-nightly.
|
|
41
|
-
"@aztec/ethereum": "2.0.0-nightly.
|
|
42
|
-
"@aztec/foundation": "2.0.0-nightly.
|
|
43
|
-
"@aztec/kv-store": "2.0.0-nightly.
|
|
44
|
-
"@aztec/l1-artifacts": "2.0.0-nightly.
|
|
45
|
-
"@aztec/merkle-tree": "2.0.0-nightly.
|
|
46
|
-
"@aztec/
|
|
47
|
-
"@aztec/noir-
|
|
48
|
-
"@aztec/noir-
|
|
49
|
-
"@aztec/noir-
|
|
50
|
-
"@aztec/
|
|
51
|
-
"@aztec/
|
|
52
|
-
"@aztec/
|
|
53
|
-
"@aztec/prover-
|
|
54
|
-
"@aztec/
|
|
55
|
-
"@aztec/
|
|
56
|
-
"@aztec/
|
|
57
|
-
"@aztec/
|
|
58
|
-
"@aztec/
|
|
59
|
-
"@aztec/
|
|
60
|
-
"@aztec/
|
|
61
|
-
"@aztec/
|
|
28
|
+
"@aztec/accounts": "2.0.0-nightly.20250827",
|
|
29
|
+
"@aztec/archiver": "2.0.0-nightly.20250827",
|
|
30
|
+
"@aztec/aztec": "2.0.0-nightly.20250827",
|
|
31
|
+
"@aztec/aztec-node": "2.0.0-nightly.20250827",
|
|
32
|
+
"@aztec/aztec.js": "2.0.0-nightly.20250827",
|
|
33
|
+
"@aztec/bb-prover": "2.0.0-nightly.20250827",
|
|
34
|
+
"@aztec/blob-lib": "2.0.0-nightly.20250827",
|
|
35
|
+
"@aztec/blob-sink": "2.0.0-nightly.20250827",
|
|
36
|
+
"@aztec/bot": "2.0.0-nightly.20250827",
|
|
37
|
+
"@aztec/cli": "2.0.0-nightly.20250827",
|
|
38
|
+
"@aztec/constants": "2.0.0-nightly.20250827",
|
|
39
|
+
"@aztec/entrypoints": "2.0.0-nightly.20250827",
|
|
40
|
+
"@aztec/epoch-cache": "2.0.0-nightly.20250827",
|
|
41
|
+
"@aztec/ethereum": "2.0.0-nightly.20250827",
|
|
42
|
+
"@aztec/foundation": "2.0.0-nightly.20250827",
|
|
43
|
+
"@aztec/kv-store": "2.0.0-nightly.20250827",
|
|
44
|
+
"@aztec/l1-artifacts": "2.0.0-nightly.20250827",
|
|
45
|
+
"@aztec/merkle-tree": "2.0.0-nightly.20250827",
|
|
46
|
+
"@aztec/node-keystore": "2.0.0-nightly.20250827",
|
|
47
|
+
"@aztec/noir-contracts.js": "2.0.0-nightly.20250827",
|
|
48
|
+
"@aztec/noir-noirc_abi": "2.0.0-nightly.20250827",
|
|
49
|
+
"@aztec/noir-protocol-circuits-types": "2.0.0-nightly.20250827",
|
|
50
|
+
"@aztec/noir-test-contracts.js": "2.0.0-nightly.20250827",
|
|
51
|
+
"@aztec/p2p": "2.0.0-nightly.20250827",
|
|
52
|
+
"@aztec/protocol-contracts": "2.0.0-nightly.20250827",
|
|
53
|
+
"@aztec/prover-client": "2.0.0-nightly.20250827",
|
|
54
|
+
"@aztec/prover-node": "2.0.0-nightly.20250827",
|
|
55
|
+
"@aztec/pxe": "2.0.0-nightly.20250827",
|
|
56
|
+
"@aztec/sequencer-client": "2.0.0-nightly.20250827",
|
|
57
|
+
"@aztec/simulator": "2.0.0-nightly.20250827",
|
|
58
|
+
"@aztec/slasher": "2.0.0-nightly.20250827",
|
|
59
|
+
"@aztec/stdlib": "2.0.0-nightly.20250827",
|
|
60
|
+
"@aztec/telemetry-client": "2.0.0-nightly.20250827",
|
|
61
|
+
"@aztec/validator-client": "2.0.0-nightly.20250827",
|
|
62
|
+
"@aztec/world-state": "2.0.0-nightly.20250827",
|
|
62
63
|
"@iarna/toml": "^2.2.5",
|
|
63
64
|
"@jest/globals": "^30.0.0",
|
|
64
65
|
"@noble/curves": "=1.0.0",
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
SequencerState,
|
|
27
27
|
} from '@aztec/sequencer-client';
|
|
28
28
|
import type { TestSequencerClient } from '@aztec/sequencer-client/test';
|
|
29
|
-
import
|
|
29
|
+
import { EthAddress, type L2BlockNumber } from '@aztec/stdlib/block';
|
|
30
30
|
import { type L1RollupConstants, getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
31
31
|
import { tryStop } from '@aztec/stdlib/interfaces/server';
|
|
32
32
|
|
|
@@ -124,7 +124,8 @@ export class EpochsTestContext {
|
|
|
124
124
|
proverTestDelayMs: opts.proverTestDelayMs ?? 0,
|
|
125
125
|
// We use numeric incremental prover ids for simplicity, but we can switch to
|
|
126
126
|
// using the prover's eth address if the proverId is used for something in the rollup contract
|
|
127
|
-
|
|
127
|
+
// Use numeric EthAddress for deterministic prover id
|
|
128
|
+
proverId: EthAddress.fromNumber(1),
|
|
128
129
|
// This must be enough so that the tx from the prover is delayed properly,
|
|
129
130
|
// but not so much to hang the sequencer and timeout the teardown
|
|
130
131
|
txPropagationMaxQueryAttempts: opts.txPropagationMaxQueryAttempts ?? 12,
|
|
@@ -189,7 +190,7 @@ export class EpochsTestContext {
|
|
|
189
190
|
const proverNode = await withLogNameSuffix(suffix, () =>
|
|
190
191
|
createAndSyncProverNode(
|
|
191
192
|
proverNodePrivateKey,
|
|
192
|
-
{ ...this.context.config, proverId:
|
|
193
|
+
{ ...this.context.config, proverId: EthAddress.fromNumber(parseInt(suffix, 10)) },
|
|
193
194
|
{ dataDirectory: join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')) },
|
|
194
195
|
this.context.aztecNode,
|
|
195
196
|
undefined,
|
|
@@ -250,9 +251,15 @@ export class EpochsTestContext {
|
|
|
250
251
|
this.logger.info(
|
|
251
252
|
`Setting tx delayer max inclusion time into slot to ${opts.txDelayerMaxInclusionTimeIntoSlot} seconds`,
|
|
252
253
|
);
|
|
254
|
+
// Here we reach into the sequencer and hook in a tx delayer. The problem is that the sequencer's l1 utils only uses a public client, not a wallet.
|
|
255
|
+
// The delayer needs a wallet (a client that can sign), so we have to create one here.
|
|
256
|
+
const l1Client = createExtendedL1Client(
|
|
257
|
+
resolvedConfig.l1RpcUrls!,
|
|
258
|
+
resolvedConfig.publisherPrivateKeys![0]!.getValue(),
|
|
259
|
+
);
|
|
253
260
|
const sequencer = node.getSequencer() as TestSequencerClient;
|
|
254
261
|
const publisher = sequencer.sequencer.publisher;
|
|
255
|
-
const delayed = DelayedTxUtils.fromL1TxUtils(publisher.l1TxUtils, this.L1_BLOCK_TIME_IN_S);
|
|
262
|
+
const delayed = DelayedTxUtils.fromL1TxUtils(publisher.l1TxUtils, this.L1_BLOCK_TIME_IN_S, l1Client);
|
|
256
263
|
delayed.delayer!.setMaxInclusionTimeIntoSlot(opts.txDelayerMaxInclusionTimeIntoSlot);
|
|
257
264
|
publisher.l1TxUtils = delayed;
|
|
258
265
|
}
|
|
@@ -108,6 +108,7 @@ export class FeesTest {
|
|
|
108
108
|
if (!numberOfAccounts) {
|
|
109
109
|
throw new Error('There must be at least 1 initial account.');
|
|
110
110
|
}
|
|
111
|
+
this.coinbase = setupOptions.coinbase ?? EthAddress.random();
|
|
111
112
|
this.logger = createLogger(`e2e:e2e_fees:${testName}`);
|
|
112
113
|
this.snapshotManager = createSnapshotManager(
|
|
113
114
|
`e2e_fees/${testName}-${numberOfAccounts}`,
|
|
@@ -119,7 +120,6 @@ export class FeesTest {
|
|
|
119
120
|
|
|
120
121
|
async setup() {
|
|
121
122
|
const context = await this.snapshotManager.setup();
|
|
122
|
-
await context.aztecNode.setConfig({ feeRecipient: this.sequencerAddress, coinbase: this.coinbase });
|
|
123
123
|
|
|
124
124
|
this.rollupContract = RollupContract.getFromConfig(context.aztecNodeConfig);
|
|
125
125
|
this.chainMonitor = new ChainMonitor(this.rollupContract, context.dateProvider, this.logger, 200).start();
|
|
@@ -205,7 +205,6 @@ export class FeesTest {
|
|
|
205
205
|
|
|
206
206
|
const canonicalFeeJuice = await getCanonicalFeeJuice();
|
|
207
207
|
this.feeJuiceContract = await FeeJuiceContract.at(canonicalFeeJuice.address, this.aliceWallet);
|
|
208
|
-
this.coinbase = EthAddress.random();
|
|
209
208
|
},
|
|
210
209
|
);
|
|
211
210
|
}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import type { AztecAddress } from '@aztec/aztec.js';
|
|
2
|
+
import { getAddressFromPrivateKey } from '@aztec/ethereum';
|
|
3
|
+
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
|
+
import type { EthPrivateKey } from '@aztec/node-keystore';
|
|
5
|
+
|
|
6
|
+
import { writeFile } from 'fs/promises';
|
|
7
|
+
import { createServer } from 'http';
|
|
8
|
+
import { signMessage, signTypedData } from 'viem/accounts';
|
|
9
|
+
|
|
10
|
+
// Create a mock JSON RPC signer
|
|
11
|
+
// Only supports signing messages and type data
|
|
12
|
+
|
|
13
|
+
const SUPPORTED_METHODS = ['eth_sign', 'eth_signTypedData_v4'];
|
|
14
|
+
|
|
15
|
+
export function createJSONRPCSigner(keyLookup: Map<string, EthPrivateKey>, stats: Map<string, number>) {
|
|
16
|
+
return createServer((req, res) => {
|
|
17
|
+
if (req.method === 'POST') {
|
|
18
|
+
let body = '';
|
|
19
|
+
req.on('data', chunk => {
|
|
20
|
+
body += chunk.toString();
|
|
21
|
+
});
|
|
22
|
+
req.on('end', () => {
|
|
23
|
+
try {
|
|
24
|
+
const jsonRequest = JSON.parse(body);
|
|
25
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
26
|
+
|
|
27
|
+
if (!SUPPORTED_METHODS.includes(jsonRequest.method)) {
|
|
28
|
+
res.end(
|
|
29
|
+
JSON.stringify({
|
|
30
|
+
jsonrpc: '2.0',
|
|
31
|
+
id: jsonRequest.id,
|
|
32
|
+
error: { code: -32601, message: 'Method not supported' },
|
|
33
|
+
}),
|
|
34
|
+
);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Get the address sending the transaction
|
|
39
|
+
const [address, data] = jsonRequest.params;
|
|
40
|
+
|
|
41
|
+
const lowerCaseAddress = address.toLowerCase();
|
|
42
|
+
stats.set(lowerCaseAddress, (stats.get(lowerCaseAddress) ?? 0) + 1);
|
|
43
|
+
|
|
44
|
+
// Find the private key for the address
|
|
45
|
+
const privateKey = keyLookup.get(address.toLowerCase());
|
|
46
|
+
if (!privateKey) {
|
|
47
|
+
res.end(
|
|
48
|
+
JSON.stringify({
|
|
49
|
+
jsonrpc: '2.0',
|
|
50
|
+
id: jsonRequest.id,
|
|
51
|
+
error: { code: -32602, message: `No private key found for address ${address}` },
|
|
52
|
+
}),
|
|
53
|
+
);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const promise =
|
|
58
|
+
jsonRequest.method === 'eth_sign'
|
|
59
|
+
? signMessage({ message: { raw: data as `0x${string}` }, privateKey })
|
|
60
|
+
: signTypedData({
|
|
61
|
+
privateKey,
|
|
62
|
+
...data,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
void promise.then(signature => {
|
|
66
|
+
res.end(
|
|
67
|
+
JSON.stringify({
|
|
68
|
+
jsonrpc: '2.0',
|
|
69
|
+
id: jsonRequest.id,
|
|
70
|
+
result: signature,
|
|
71
|
+
}),
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
} catch (err) {
|
|
75
|
+
res.end(
|
|
76
|
+
JSON.stringify({
|
|
77
|
+
jsonrpc: '2.0',
|
|
78
|
+
id: 1,
|
|
79
|
+
error: { code: -32603, message: `${err}` },
|
|
80
|
+
}),
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
} else {
|
|
85
|
+
res.writeHead(405);
|
|
86
|
+
res.end('Method not allowed');
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Functions for creating file based key stores for the e2e_multi_validator_node_key_store test
|
|
92
|
+
export async function createKeyFile1(
|
|
93
|
+
fileName: string,
|
|
94
|
+
mnemonic: string,
|
|
95
|
+
validatorIndex: number,
|
|
96
|
+
publisher1Key: EthPrivateKey,
|
|
97
|
+
publisher2Key: EthPrivateKey,
|
|
98
|
+
coinbase: EthAddress,
|
|
99
|
+
feeRecipient: AztecAddress,
|
|
100
|
+
) {
|
|
101
|
+
const obj = {
|
|
102
|
+
schemaVersion: 1,
|
|
103
|
+
validators: [
|
|
104
|
+
{
|
|
105
|
+
attester: {
|
|
106
|
+
mnemonic: mnemonic,
|
|
107
|
+
accountIndex: 0,
|
|
108
|
+
addressIndex: validatorIndex,
|
|
109
|
+
addressCount: 1,
|
|
110
|
+
},
|
|
111
|
+
coinbase: coinbase.toChecksumString(),
|
|
112
|
+
publisher: [publisher1Key, publisher2Key],
|
|
113
|
+
feeRecipient: feeRecipient.toString(),
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
};
|
|
117
|
+
await writeFile(fileName, JSON.stringify(obj, null, 2));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export async function createKeyFile2(
|
|
121
|
+
fileName: string,
|
|
122
|
+
validatorKey: EthPrivateKey,
|
|
123
|
+
publisherMnemonic: string,
|
|
124
|
+
publisher1Index: number,
|
|
125
|
+
coinbase: EthAddress,
|
|
126
|
+
feeRecipient: AztecAddress,
|
|
127
|
+
) {
|
|
128
|
+
const obj = {
|
|
129
|
+
schemaVersion: 1,
|
|
130
|
+
validators: [
|
|
131
|
+
{
|
|
132
|
+
attester: validatorKey,
|
|
133
|
+
coinbase: coinbase.toChecksumString(),
|
|
134
|
+
publisher: {
|
|
135
|
+
mnemonic: publisherMnemonic,
|
|
136
|
+
accountIndex: 0,
|
|
137
|
+
addressIndex: publisher1Index,
|
|
138
|
+
addressCount: 2,
|
|
139
|
+
},
|
|
140
|
+
feeRecipient: feeRecipient.toString(),
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
};
|
|
144
|
+
await writeFile(fileName, JSON.stringify(obj, null, 2));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export async function createKeyFile3(
|
|
148
|
+
fileName: string,
|
|
149
|
+
validatorAddress: EthAddress,
|
|
150
|
+
publisher1Key: EthPrivateKey,
|
|
151
|
+
publisher2Key: EthPrivateKey,
|
|
152
|
+
coinbase: EthAddress,
|
|
153
|
+
remoteSignerUrl: string,
|
|
154
|
+
feeRecipient: AztecAddress,
|
|
155
|
+
) {
|
|
156
|
+
const obj = {
|
|
157
|
+
schemaVersion: 1,
|
|
158
|
+
validators: [
|
|
159
|
+
{
|
|
160
|
+
attester: {
|
|
161
|
+
address: validatorAddress.toChecksumString(),
|
|
162
|
+
},
|
|
163
|
+
coinbase: coinbase.toChecksumString(),
|
|
164
|
+
publisher: [publisher1Key, publisher2Key],
|
|
165
|
+
feeRecipient: feeRecipient.toString(),
|
|
166
|
+
remoteSigner: {
|
|
167
|
+
remoteSignerUrl: remoteSignerUrl,
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
};
|
|
172
|
+
await writeFile(fileName, JSON.stringify(obj, null, 2));
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export async function createKeyFile4(
|
|
176
|
+
fileName: string,
|
|
177
|
+
validator1Address: EthAddress,
|
|
178
|
+
validator2Address: EthAddress,
|
|
179
|
+
publisher1Index: number,
|
|
180
|
+
publisher2Key: EthPrivateKey,
|
|
181
|
+
mnemonic: string,
|
|
182
|
+
publisher3Key: EthPrivateKey,
|
|
183
|
+
coinbase1: EthAddress,
|
|
184
|
+
coinbase2: EthAddress,
|
|
185
|
+
remoteSignerUrl: string,
|
|
186
|
+
feeRecipient1: AztecAddress,
|
|
187
|
+
feeRecipient2: AztecAddress,
|
|
188
|
+
) {
|
|
189
|
+
const obj = {
|
|
190
|
+
schemaVersion: 1,
|
|
191
|
+
remoteSigner: {
|
|
192
|
+
remoteSignerUrl: remoteSignerUrl,
|
|
193
|
+
},
|
|
194
|
+
validators: [
|
|
195
|
+
{
|
|
196
|
+
attester: {
|
|
197
|
+
address: validator1Address.toChecksumString(),
|
|
198
|
+
},
|
|
199
|
+
coinbase: coinbase1.toChecksumString(),
|
|
200
|
+
publisher: {
|
|
201
|
+
mnemonic: mnemonic,
|
|
202
|
+
accountIndex: 0,
|
|
203
|
+
addressIndex: publisher1Index,
|
|
204
|
+
addressCount: 2,
|
|
205
|
+
},
|
|
206
|
+
feeRecipient: feeRecipient1.toString(),
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
attester: {
|
|
210
|
+
address: validator2Address.toChecksumString(),
|
|
211
|
+
},
|
|
212
|
+
coinbase: coinbase2.toChecksumString(),
|
|
213
|
+
publisher: [publisher2Key, publisher3Key],
|
|
214
|
+
feeRecipient: feeRecipient2.toString(),
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
};
|
|
218
|
+
await writeFile(fileName, JSON.stringify(obj, null, 2));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export async function createKeyFile5(fileName: string, proverAddress: EthAddress, remoteSignerUrl: string) {
|
|
222
|
+
const obj = {
|
|
223
|
+
schemaVersion: 1,
|
|
224
|
+
prover: {
|
|
225
|
+
id: '0x1234567890123456789012345678901234567890',
|
|
226
|
+
publisher: [
|
|
227
|
+
{
|
|
228
|
+
address: proverAddress.toChecksumString(),
|
|
229
|
+
remoteSignerUrl: remoteSignerUrl,
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
await writeFile(fileName, JSON.stringify(obj, null, 2));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export async function createKeyFile6(
|
|
238
|
+
fileName: string,
|
|
239
|
+
mnemonic: string,
|
|
240
|
+
validator1Index: number,
|
|
241
|
+
coinbase: EthAddress,
|
|
242
|
+
feeRecipient: AztecAddress,
|
|
243
|
+
) {
|
|
244
|
+
const obj = {
|
|
245
|
+
schemaVersion: 1,
|
|
246
|
+
validators: [
|
|
247
|
+
{
|
|
248
|
+
attester: {
|
|
249
|
+
mnemonic: mnemonic,
|
|
250
|
+
accountIndex: 0,
|
|
251
|
+
addressIndex: validator1Index,
|
|
252
|
+
addressCount: 2,
|
|
253
|
+
},
|
|
254
|
+
coinbase: coinbase.toChecksumString(),
|
|
255
|
+
feeRecipient: feeRecipient.toString(),
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
};
|
|
259
|
+
await writeFile(fileName, JSON.stringify(obj, null, 2));
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export function addressForPrivateKey(privateKey: EthPrivateKey): EthAddress {
|
|
263
|
+
return EthAddress.fromString(getAddressFromPrivateKey(privateKey));
|
|
264
|
+
}
|
|
@@ -5,11 +5,11 @@ import { type AccountWalletWithSecretKey, AztecAddress, EthAddress, Fr } from '@
|
|
|
5
5
|
import {
|
|
6
6
|
type ExtendedViemWalletClient,
|
|
7
7
|
GSEContract,
|
|
8
|
-
L1TxUtils,
|
|
9
8
|
MultiAdderArtifact,
|
|
10
9
|
type Operator,
|
|
11
10
|
RollupContract,
|
|
12
11
|
type ViemClient,
|
|
12
|
+
createL1TxUtilsFromViemWallet,
|
|
13
13
|
deployL1Contract,
|
|
14
14
|
getL1ContractsConfigEnvVars,
|
|
15
15
|
} from '@aztec/ethereum';
|
|
@@ -349,7 +349,7 @@ export class P2PNetworkTest {
|
|
|
349
349
|
}
|
|
350
350
|
|
|
351
351
|
private async _sendDummyTx(l1Client: ExtendedViemWalletClient) {
|
|
352
|
-
const l1TxUtils =
|
|
352
|
+
const l1TxUtils = createL1TxUtilsFromViemWallet(l1Client);
|
|
353
353
|
return await l1TxUtils.sendAndMonitorTransaction({
|
|
354
354
|
to: l1Client.account!.address,
|
|
355
355
|
value: 1n,
|
|
@@ -296,10 +296,10 @@ export class FullProverTest {
|
|
|
296
296
|
...this.context.aztecNodeConfig,
|
|
297
297
|
txCollectionNodeRpcUrls: [],
|
|
298
298
|
dataDirectory: undefined,
|
|
299
|
-
proverId: this.proverAddress
|
|
299
|
+
proverId: this.proverAddress,
|
|
300
300
|
realProofs: this.realProofs,
|
|
301
301
|
proverAgentCount: 2,
|
|
302
|
-
|
|
302
|
+
publisherPrivateKeys: [new SecretValue(`0x${proverNodePrivateKey!.toString('hex')}` as const)],
|
|
303
303
|
proverNodeMaxPendingJobs: 100,
|
|
304
304
|
proverNodeMaxParallelBlocksPerEpoch: 32,
|
|
305
305
|
proverNodePollingIntervalMs: 100,
|
|
@@ -154,7 +154,7 @@ export async function createValidatorConfig(
|
|
|
154
154
|
const attesterPrivateKey = bufferToHex(getPrivateKeyFromIndex(ATTESTER_PRIVATE_KEYS_START_INDEX + addressIndex)!);
|
|
155
155
|
|
|
156
156
|
config.validatorPrivateKeys = new SecretValue([attesterPrivateKey]);
|
|
157
|
-
config.
|
|
157
|
+
config.publisherPrivateKeys = [new SecretValue(attesterPrivateKey)];
|
|
158
158
|
|
|
159
159
|
const nodeConfig: AztecNodeConfig = {
|
|
160
160
|
...config,
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
type CompleteAddress,
|
|
9
9
|
type ContractFunctionInteraction,
|
|
10
10
|
DefaultWaitForProvenOpts,
|
|
11
|
+
EthAddress,
|
|
11
12
|
type Logger,
|
|
12
13
|
type PXE,
|
|
13
14
|
type Wallet,
|
|
@@ -342,11 +343,14 @@ async function setupFromFresh(
|
|
|
342
343
|
const publisherPrivKeyRaw = hdAccount.getHdKey().privateKey;
|
|
343
344
|
const publisherPrivKey = publisherPrivKeyRaw === null ? null : Buffer.from(publisherPrivKeyRaw);
|
|
344
345
|
|
|
346
|
+
const l1Client = createExtendedL1Client([aztecNodeConfig.l1RpcUrls[0]], hdAccount, foundry);
|
|
347
|
+
|
|
345
348
|
const validatorPrivKey = getPrivateKeyFromIndex(0);
|
|
346
349
|
const proverNodePrivateKey = getPrivateKeyFromIndex(0);
|
|
347
350
|
|
|
348
|
-
aztecNodeConfig.
|
|
351
|
+
aztecNodeConfig.publisherPrivateKeys = [new SecretValue<`0x${string}`>(`0x${publisherPrivKey!.toString('hex')}`)];
|
|
349
352
|
aztecNodeConfig.validatorPrivateKeys = new SecretValue([`0x${validatorPrivKey!.toString('hex')}`]);
|
|
353
|
+
aztecNodeConfig.coinbase = opts.coinbase ?? EthAddress.fromString(`${hdAccount.address}`);
|
|
350
354
|
|
|
351
355
|
const ethCheatCodes = new EthCheatCodesWithState(aztecNodeConfig.l1RpcUrls);
|
|
352
356
|
|
|
@@ -361,7 +365,6 @@ async function setupFromFresh(
|
|
|
361
365
|
opts.initialAccountFeeJuice,
|
|
362
366
|
);
|
|
363
367
|
|
|
364
|
-
const l1Client = createExtendedL1Client([aztecNodeConfig.l1RpcUrls[0]], hdAccount, foundry);
|
|
365
368
|
await deployMulticall3(l1Client, logger);
|
|
366
369
|
|
|
367
370
|
const deployL1ContractsValues = await setupL1Contracts(aztecNodeConfig.l1RpcUrls[0], hdAccount, logger, {
|
|
@@ -439,7 +442,7 @@ async function setupFromFresh(
|
|
|
439
442
|
);
|
|
440
443
|
await blobSink.start();
|
|
441
444
|
|
|
442
|
-
logger.
|
|
445
|
+
logger.info('Creating and synching an aztec node...');
|
|
443
446
|
const aztecNode = await AztecNodeService.createAndSync(
|
|
444
447
|
aztecNodeConfig,
|
|
445
448
|
{ telemetry, dateProvider },
|