@aztec/aztec 3.0.3 → 4.0.0-devnet.1-patch.0

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.
Files changed (68) hide show
  1. package/dest/bin/index.js +2 -0
  2. package/dest/cli/aztec_start_action.d.ts +1 -1
  3. package/dest/cli/aztec_start_action.d.ts.map +1 -1
  4. package/dest/cli/aztec_start_action.js +6 -4
  5. package/dest/cli/aztec_start_options.d.ts +1 -1
  6. package/dest/cli/aztec_start_options.d.ts.map +1 -1
  7. package/dest/cli/aztec_start_options.js +9 -15
  8. package/dest/cli/cli.d.ts +1 -1
  9. package/dest/cli/cli.d.ts.map +1 -1
  10. package/dest/cli/cli.js +9 -53
  11. package/dest/cli/cmds/migrate_ha_db.d.ts +3 -0
  12. package/dest/cli/cmds/migrate_ha_db.d.ts.map +1 -0
  13. package/dest/cli/cmds/migrate_ha_db.js +27 -0
  14. package/dest/cli/cmds/start_archiver.d.ts +1 -1
  15. package/dest/cli/cmds/start_archiver.d.ts.map +1 -1
  16. package/dest/cli/cmds/start_archiver.js +10 -12
  17. package/dest/cli/cmds/start_p2p_bootstrap.d.ts +2 -2
  18. package/dest/cli/cmds/start_p2p_bootstrap.d.ts.map +1 -1
  19. package/dest/cli/cmds/start_p2p_bootstrap.js +1 -2
  20. package/dest/cli/cmds/start_prover_agent.d.ts +1 -1
  21. package/dest/cli/cmds/start_prover_agent.d.ts.map +1 -1
  22. package/dest/cli/cmds/start_prover_agent.js +3 -3
  23. package/dest/cli/cmds/start_prover_broker.d.ts +1 -1
  24. package/dest/cli/cmds/start_prover_broker.d.ts.map +1 -1
  25. package/dest/cli/cmds/start_prover_broker.js +2 -2
  26. package/dest/cli/util.js +1 -1
  27. package/dest/examples/token.js +3 -3
  28. package/dest/local-network/banana_fpc.d.ts +1 -1
  29. package/dest/local-network/banana_fpc.d.ts.map +1 -1
  30. package/dest/local-network/banana_fpc.js +2 -2
  31. package/dest/local-network/local-network.d.ts +4 -5
  32. package/dest/local-network/local-network.d.ts.map +1 -1
  33. package/dest/local-network/local-network.js +24 -12
  34. package/dest/testing/cheat_codes.d.ts +3 -1
  35. package/dest/testing/cheat_codes.d.ts.map +1 -1
  36. package/dest/testing/epoch_test_settler.d.ts +19 -0
  37. package/dest/testing/epoch_test_settler.d.ts.map +1 -0
  38. package/dest/testing/epoch_test_settler.js +62 -0
  39. package/dest/testing/index.d.ts +2 -1
  40. package/dest/testing/index.d.ts.map +1 -1
  41. package/dest/testing/index.js +1 -0
  42. package/package.json +37 -35
  43. package/scripts/aztec.sh +63 -0
  44. package/scripts/compile.sh +44 -0
  45. package/scripts/extract_function.js +47 -0
  46. package/scripts/flamegraph.sh +59 -0
  47. package/scripts/init.sh +35 -0
  48. package/scripts/new.sh +59 -0
  49. package/scripts/setup_project.sh +31 -0
  50. package/src/bin/index.ts +2 -0
  51. package/src/cli/aztec_start_action.ts +5 -3
  52. package/src/cli/aztec_start_options.ts +8 -14
  53. package/src/cli/cli.ts +12 -56
  54. package/src/cli/cmds/migrate_ha_db.ts +43 -0
  55. package/src/cli/cmds/start_archiver.ts +6 -17
  56. package/src/cli/cmds/start_p2p_bootstrap.ts +2 -2
  57. package/src/cli/cmds/start_prover_agent.ts +3 -11
  58. package/src/cli/cmds/start_prover_broker.ts +5 -1
  59. package/src/cli/util.ts +1 -1
  60. package/src/examples/token.ts +3 -5
  61. package/src/local-network/banana_fpc.ts +10 -6
  62. package/src/local-network/local-network.ts +37 -23
  63. package/src/testing/epoch_test_settler.ts +71 -0
  64. package/src/testing/index.ts +1 -0
  65. package/dest/cli/cmds/start_blob_sink.d.ts +0 -3
  66. package/dest/cli/cmds/start_blob_sink.d.ts.map +0 -1
  67. package/dest/cli/cmds/start_blob_sink.js +0 -33
  68. package/src/cli/cmds/start_blob_sink.ts +0 -57
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # Get the actual aztec version for the git tag.
5
+ AZTEC_VERSION=$(jq -r '.version' $(dirname $0)/../package.json)
6
+ NARGO_TOML_PATH="Nargo.toml"
7
+ MAIN_NR_PATH="src/main.nr"
8
+
9
+ if [ ! -f "$NARGO_TOML_PATH" ]; then
10
+ >&2 echo "Warning: Could not find Nargo.toml at $NARGO_TOML_PATH to add aztec dependency"
11
+ exit 1
12
+ fi
13
+
14
+ if [ ! -f "$MAIN_NR_PATH" ]; then
15
+ >&2 echo "Warning: Could not find main.nr at $MAIN_NR_PATH"
16
+ exit 1
17
+ fi
18
+
19
+ # Add aztec dependency to Nargo.toml
20
+ echo "" >> "$NARGO_TOML_PATH"
21
+ echo "aztec = { git=\"https://github.com/AztecProtocol/aztec-nr\", tag=\"v${AZTEC_VERSION}\", directory=\"aztec\" }" >> "$NARGO_TOML_PATH"
22
+ echo "Added aztec dependency (v${AZTEC_VERSION}) to Nargo.toml"
23
+
24
+ # Replace the contents of main.nr with the Aztec contract template
25
+ cat > "$MAIN_NR_PATH" << 'EOF'
26
+ use aztec::macros::aztec;
27
+
28
+ #[aztec]
29
+ contract Main {}
30
+ EOF
31
+ echo "Created main.nr with Aztec contract template"
package/src/bin/index.ts CHANGED
@@ -14,6 +14,7 @@ import { createConsoleLogger, createLogger } from '@aztec/foundation/log';
14
14
 
15
15
  import { Command } from 'commander';
16
16
 
17
+ import { injectMigrateCommand } from '../cli/cmds/migrate_ha_db.js';
17
18
  import { injectAztecCommands } from '../cli/index.js';
18
19
  import { getCliVersion } from '../cli/release_version.js';
19
20
 
@@ -55,6 +56,7 @@ async function main() {
55
56
  program = injectAztecNodeCommands(program, userLog, debugLogger);
56
57
  program = injectMiscCommands(program, userLog);
57
58
  program = injectValidatorKeysCommands(program, userLog);
59
+ program = injectMigrateCommand(program, userLog);
58
60
 
59
61
  await program.parseAsync(process.argv);
60
62
  }
@@ -35,6 +35,11 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg
35
35
  l1RpcUrls: options.l1RpcUrls,
36
36
  testAccounts: localNetwork.testAccounts,
37
37
  realProofs: false,
38
+ // Setting the epoch duration to 4 by default for local network. This allows the epoch to be "proven" faster, so
39
+ // the users can consume out hash without having to wait for a long time.
40
+ // Note: We are not proving anything in the local network (realProofs == false). But in `createLocalNetwork`,
41
+ // the EpochTestSettler will set the out hash to the outbox when an epoch is complete.
42
+ aztecEpochDuration: 4,
38
43
  },
39
44
  userLog,
40
45
  );
@@ -52,9 +57,6 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg
52
57
  } else if (options.proverNode) {
53
58
  const { startProverNode } = await import('./cmds/start_prover_node.js');
54
59
  ({ config } = await startProverNode(options, signalHandlers, services, userLog));
55
- } else if (options.blobSink) {
56
- const { startBlobSink } = await import('./cmds/start_blob_sink.js');
57
- await startBlobSink(options, signalHandlers, userLog);
58
60
  } else if (options.archiver) {
59
61
  const { startArchiver } = await import('./cmds/start_archiver.js');
60
62
  ({ config } = await startArchiver(options, signalHandlers, services));
@@ -1,5 +1,5 @@
1
1
  import { type ArchiverConfig, archiverConfigMappings } from '@aztec/archiver/config';
2
- import { blobSinkConfigMappings } from '@aztec/blob-sink/server/config';
2
+ import { blobClientConfigMapping } from '@aztec/blob-client/client/config';
3
3
  import { botConfigMappings } from '@aztec/bot/config';
4
4
  import { l1ContractsConfigMappings } from '@aztec/ethereum/config';
5
5
  import { l1ContractAddressesMapping } from '@aztec/ethereum/l1-contract-addresses';
@@ -19,7 +19,7 @@ import { proverAgentConfigMappings, proverBrokerConfigMappings } from '@aztec/pr
19
19
  import { proverNodeConfigMappings } from '@aztec/prover-node/config';
20
20
  import { allPxeConfigMappings } from '@aztec/pxe/config';
21
21
  import { sequencerClientConfigMappings } from '@aztec/sequencer-client/config';
22
- import { chainConfigMappings } from '@aztec/stdlib/config';
22
+ import { chainConfigMappings, nodeRpcConfigMappings } from '@aztec/stdlib/config';
23
23
  import { telemetryClientConfigMappings } from '@aztec/telemetry-client/config';
24
24
  import { worldStateConfigMappings } from '@aztec/world-state/config';
25
25
 
@@ -148,14 +148,16 @@ export const aztecStartOptions: { [key: string]: AztecStartOption[] } = {
148
148
  defaultValue: '',
149
149
  env: 'API_PREFIX',
150
150
  },
151
+ configToFlag('--rpcMaxBatchSize', nodeRpcConfigMappings.rpcMaxBatchSize),
152
+ configToFlag('--rpcMaxBodySize', nodeRpcConfigMappings.rpcMaxBodySize),
151
153
  ],
152
154
  ETHEREUM: [
153
155
  configToFlag('--l1-chain-id', l1ReaderConfigMappings.l1ChainId),
154
156
  // Do not set default for CLI: keep undefined unless provided via flag or env
155
157
  configToFlag('--l1-rpc-urls', { ...l1ReaderConfigMappings.l1RpcUrls, defaultValue: undefined }),
156
- configToFlag('--l1-consensus-host-urls', blobSinkConfigMappings.l1ConsensusHostUrls),
157
- configToFlag('--l1-consensus-host-api-keys', blobSinkConfigMappings.l1ConsensusHostApiKeys),
158
- configToFlag('--l1-consensus-host-api-key-headers', blobSinkConfigMappings.l1ConsensusHostApiKeyHeaders),
158
+ configToFlag('--l1-consensus-host-urls', blobClientConfigMapping.l1ConsensusHostUrls),
159
+ configToFlag('--l1-consensus-host-api-keys', blobClientConfigMapping.l1ConsensusHostApiKeys),
160
+ configToFlag('--l1-consensus-host-api-key-headers', blobClientConfigMapping.l1ConsensusHostApiKeyHeaders),
159
161
  ],
160
162
  'L1 CONTRACTS': [
161
163
  configToFlag('--registry-address', l1ContractAddressesMapping.registryAddress),
@@ -202,21 +204,13 @@ export const aztecStartOptions: { [key: string]: AztecStartOption[] } = {
202
204
  'sequencer',
203
205
  omitConfigMappings(sequencerClientConfigMappings, [
204
206
  'fakeProcessingDelayPerTxMs',
207
+ 'fakeThrowAfterProcessingTxCount',
205
208
  'skipCollectingAttestations',
206
209
  'skipInvalidateBlockAsProposer',
207
210
  'blobSinkMapSizeKb',
208
211
  ]),
209
212
  ),
210
213
  ],
211
- 'BLOB SINK': [
212
- {
213
- flag: '--blob-sink',
214
- description: 'Starts Aztec Blob Sink with options',
215
- defaultValue: undefined,
216
- env: undefined,
217
- },
218
- ...getOptions('blobSink', blobSinkConfigMappings),
219
- ],
220
214
  'PROVER NODE': [
221
215
  {
222
216
  flag: '--prover-node',
package/src/cli/cli.ts CHANGED
@@ -31,63 +31,19 @@ export function injectAztecCommands(program: Command, userLog: LogFn, debugLogge
31
31
 
32
32
  program.configureHelp({ sortSubcommands: true });
33
33
 
34
- program.addHelpText(
35
- 'after',
36
- `
37
-
38
- Additional commands:
39
-
40
- init [folder] [options]: creates a new Noir project
41
- Options:
42
- --name <name> Name of the package
43
- --contract Use a contract template (default)
44
- --lib Use a library template
45
- --bin Use a binary template
46
- Examples:
47
- $ aztec init # creates a contract project in current directory
48
- $ aztec init --lib # creates a library project
49
-
50
- new <path> [options]: creates a new Noir project in a new directory
51
- Options:
52
- --name <name> Name of the package
53
- --contract Use a contract template (default)
54
- --lib Use a library template
55
- --bin Use a binary template
56
- Examples:
57
- $ aztec new my-project # creates a contract project in ./my-project
58
- $ aztec new my-lib --lib # creates a library project in ./my-lib
59
-
60
- compile [options]: compiles Aztec Noir contracts
61
- Compiles contracts with nargo compile and then postprocesses them to generate Aztec-specific artifacts including:
62
- - Transpiled contract artifacts
63
- - Verification keys
64
- The compiled contracts will be placed in the target/ directory by default.
65
- Supports standard nargo compile options.
66
-
67
- fmt [options]: formats Noir code using nargo fmt
68
- Example:
69
- $ aztec fmt # formats all Noir files in the project
70
-
71
- check [options]: type-checks Noir code without compiling using nargo check
72
- Example:
73
- $ aztec check # checks all Noir files in the project
74
-
75
- test [options]: starts a dockerized TXE node via
76
- $ aztec start --txe
77
- then runs
78
- $ aztec test --silence-warnings --oracle-resolver=<TXE_ADDRESS> [options]
79
-
80
- lsp: starts the Nargo Language Server Protocol server
81
- Runs nargo lsp in a Docker container for IDE integration with Noir.
82
- This command is typically used by IDE extensions and not called directly by users.
83
- Example:
84
- $ aztec lsp # starts the LSP server
85
-
86
- preload-crs: Downloads and caches the Common Reference String (CRS) data required for zero-knowledge proofs.
87
- Example:
88
- $ aztec preload-crs # preloads CRS data
34
+ if (process.env.AZTEC_SHELL_WRAPPER) {
35
+ program.addHelpText(
36
+ 'after',
37
+ `
38
+ Additional commands:
39
+
40
+ init [folder] [options] creates a new Aztec Noir project.
41
+ new <path> [options] creates a new Aztec Noir project in a new directory.
42
+ compile [options] compiles Aztec Noir contracts.
43
+ test [options] starts a TXE and runs "nargo test" using it as the oracle resolver.
89
44
  `,
90
- );
45
+ );
46
+ }
91
47
 
92
48
  program
93
49
  .command('preload-crs')
@@ -0,0 +1,43 @@
1
+ import { runMigrations } from '@aztec/validator-ha-signer/migrations';
2
+
3
+ import type { Command } from 'commander';
4
+
5
+ export function injectMigrateCommand(program: Command, log: (msg: string) => void): Command {
6
+ const migrateCommand = program.command('migrate-ha-db').description('Run validator-ha-signer database migrations');
7
+
8
+ migrateCommand
9
+ .command('up')
10
+ .description('Apply pending migrations')
11
+ .requiredOption('--database-url <string>', 'PostgreSQL connection string', process.env.DATABASE_URL)
12
+ .option('--verbose', 'Enable verbose output', false)
13
+ .action(async options => {
14
+ const migrations = await runMigrations(options.databaseUrl, {
15
+ direction: 'up',
16
+ verbose: options.verbose,
17
+ });
18
+ if (migrations.length > 0) {
19
+ log(`Applied migrations: ${migrations.join(', ')}`);
20
+ } else {
21
+ log('No migrations to apply - schema is up to date');
22
+ }
23
+ });
24
+
25
+ migrateCommand
26
+ .command('down')
27
+ .description('Rollback the last migration')
28
+ .requiredOption('--database-url <string>', 'PostgreSQL connection string', process.env.DATABASE_URL)
29
+ .option('--verbose', 'Enable verbose output', false)
30
+ .action(async options => {
31
+ const migrations = await runMigrations(options.databaseUrl, {
32
+ direction: 'down',
33
+ verbose: options.verbose,
34
+ });
35
+ if (migrations.length > 0) {
36
+ log(`Rolled back migrations: ${migrations.join(', ')}`);
37
+ } else {
38
+ log('No migrations to rollback');
39
+ }
40
+ });
41
+
42
+ return program;
43
+ }
@@ -1,16 +1,9 @@
1
- import {
2
- Archiver,
3
- type ArchiverConfig,
4
- KVArchiverDataStore,
5
- archiverConfigMappings,
6
- getArchiverConfigFromEnv,
7
- } from '@aztec/archiver';
1
+ import { type ArchiverConfig, archiverConfigMappings, createArchiver, getArchiverConfigFromEnv } from '@aztec/archiver';
8
2
  import { createLogger } from '@aztec/aztec.js/log';
9
- import { type BlobSinkConfig, blobSinkConfigMapping, createBlobSinkClient } from '@aztec/blob-sink/client';
3
+ import { type BlobClientConfig, blobClientConfigMapping, createBlobClient } from '@aztec/blob-client/client';
10
4
  import { getL1Config } from '@aztec/cli/config';
11
5
  import type { NamespacedApiHandlers } from '@aztec/foundation/json-rpc/server';
12
6
  import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
13
- import { createStore } from '@aztec/kv-store/lmdb-v2';
14
7
  import { ArchiverApiSchema } from '@aztec/stdlib/interfaces/server';
15
8
  import { getConfigEnvVars as getTelemetryClientConfig, initTelemetryClient } from '@aztec/telemetry-client';
16
9
 
@@ -25,9 +18,9 @@ export async function startArchiver(
25
18
  services: NamespacedApiHandlers,
26
19
  ): Promise<{ config: ArchiverConfig & DataStoreConfig }> {
27
20
  const envConfig = getArchiverConfigFromEnv();
28
- const cliOptions = extractRelevantOptions<ArchiverConfig & DataStoreConfig & BlobSinkConfig>(
21
+ const cliOptions = extractRelevantOptions<ArchiverConfig & DataStoreConfig & BlobClientConfig>(
29
22
  options,
30
- { ...archiverConfigMappings, ...dataConfigMappings, ...blobSinkConfigMapping },
23
+ { ...archiverConfigMappings, ...dataConfigMappings, ...blobClientConfigMapping },
31
24
  'archiver',
32
25
  );
33
26
 
@@ -47,13 +40,9 @@ export async function startArchiver(
47
40
  archiverConfig.l1Contracts = addresses;
48
41
  archiverConfig = { ...archiverConfig, ...l1Config };
49
42
 
50
- const storeLog = createLogger('archiver:lmdb');
51
- const store = await createStore('archiver', KVArchiverDataStore.SCHEMA_VERSION, archiverConfig, storeLog);
52
- const archiverStore = new KVArchiverDataStore(store, archiverConfig.maxLogs);
53
-
54
43
  const telemetry = await initTelemetryClient(getTelemetryClientConfig());
55
- const blobSinkClient = createBlobSinkClient(archiverConfig, { logger: createLogger('archiver:blob-sink:client') });
56
- const archiver = await Archiver.createAndSync(archiverConfig, archiverStore, { telemetry, blobSinkClient }, true);
44
+ const blobClient = createBlobClient(archiverConfig, { logger: createLogger('archiver:blob-client:client') });
45
+ const archiver = await createArchiver(archiverConfig, { telemetry, blobClient }, { blockUntilSync: true });
57
46
  services.archiver = [archiver, ArchiverApiSchema];
58
47
  signalHandlers.push(archiver.stop);
59
48
 
@@ -1,6 +1,6 @@
1
1
  import { jsonStringify } from '@aztec/foundation/json-rpc';
2
2
  import type { NamespacedApiHandlers } from '@aztec/foundation/json-rpc/server';
3
- import { type LogFn, createLogger } from '@aztec/foundation/log';
3
+ import type { LogFn } from '@aztec/foundation/log';
4
4
  import { createStore } from '@aztec/kv-store/lmdb-v2';
5
5
  import { type BootnodeConfig, BootstrapNode, bootnodeConfigMappings } from '@aztec/p2p';
6
6
  import { emptyChainConfig } from '@aztec/stdlib/config';
@@ -27,7 +27,7 @@ export async function startP2PBootstrap(
27
27
  const telemetryConfig = extractRelevantOptions<TelemetryClientConfig>(options, telemetryClientConfigMappings, 'tel');
28
28
  const telemetryClient = await initTelemetryClient(telemetryConfig);
29
29
 
30
- const store = await createStore('p2p-bootstrap', 1, config, createLogger('p2p:bootstrap:store'));
30
+ const store = await createStore('p2p-bootstrap', 1, config);
31
31
  const node = new BootstrapNode(store, telemetryClient);
32
32
  await node.start(config);
33
33
  signalHandlers.push(() => node.stop());
@@ -4,9 +4,9 @@ import { Agent, makeUndiciFetch } from '@aztec/foundation/json-rpc/undici';
4
4
  import type { LogFn } from '@aztec/foundation/log';
5
5
  import { buildServerCircuitProver } from '@aztec/prover-client';
6
6
  import {
7
- InlineProofStore,
8
7
  type ProverAgentConfig,
9
8
  ProvingAgent,
9
+ createProofStore,
10
10
  createProvingJobBrokerClient,
11
11
  proverAgentConfigMappings,
12
12
  } from '@aztec/prover-client/broker';
@@ -55,18 +55,10 @@ export async function startProverAgent(
55
55
 
56
56
  const telemetry = await initTelemetryClient(extractRelevantOptions(options, telemetryClientConfigMappings, 'tel'));
57
57
  const prover = await buildServerCircuitProver(config, telemetry);
58
- const proofStore = new InlineProofStore();
58
+ const proofStore = await createProofStore(config.proofStore);
59
59
  const agents = times(
60
60
  config.proverAgentCount,
61
- () =>
62
- new ProvingAgent(
63
- broker,
64
- proofStore,
65
- prover,
66
- config.proverAgentProofTypes,
67
- config.proverAgentPollIntervalMs,
68
- telemetry,
69
- ),
61
+ () => new ProvingAgent(broker, proofStore, prover, config.proverAgentProofTypes, config.proverAgentPollIntervalMs),
70
62
  );
71
63
 
72
64
  // expose all agents as individual services
@@ -5,6 +5,7 @@ import type { LogFn } from '@aztec/foundation/log';
5
5
  import {
6
6
  type ProverBrokerConfig,
7
7
  ProvingJobBrokerSchema,
8
+ ProvingJobBrokerSchemaWithDebug,
8
9
  createAndStartProvingBroker,
9
10
  proverBrokerConfigMappings,
10
11
  } from '@aztec/prover-client/broker';
@@ -59,7 +60,10 @@ export async function startProverBroker(
59
60
  );
60
61
  }
61
62
 
62
- services.proverBroker = [broker, ProvingJobBrokerSchema];
63
+ services.proverBroker = [
64
+ broker,
65
+ config.proverBrokerDebugReplayEnabled ? ProvingJobBrokerSchemaWithDebug : ProvingJobBrokerSchema,
66
+ ];
63
67
  signalHandlers.push(() => broker.stop());
64
68
 
65
69
  return { broker, config };
package/src/cli/util.ts CHANGED
@@ -36,7 +36,7 @@ export function shutdown(logFn: LogFn, exitCode: ExitCode, cb?: Array<() => Prom
36
36
 
37
37
  logFn('Shutting down...', { exitCode });
38
38
  if (cb) {
39
- shutdownPromise = Promise.allSettled(cb).then(() => process.exit(exitCode));
39
+ shutdownPromise = Promise.allSettled(cb.map(fn => fn())).then(() => process.exit(exitCode));
40
40
  } else {
41
41
  // synchronously shuts down the process
42
42
  // no need to set shutdownPromise on this branch of the if statement because no more code will be executed
@@ -32,14 +32,12 @@ async function main() {
32
32
  logger.info(`Fetched Alice and Bob accounts: ${alice.toString()}, ${bob.toString()}`);
33
33
 
34
34
  logger.info('Deploying Token...');
35
- const token = await TokenContract.deploy(wallet, alice, 'TokenName', 'TokenSymbol', 18)
36
- .send({ from: alice })
37
- .deployed();
35
+ const token = await TokenContract.deploy(wallet, alice, 'TokenName', 'TokenSymbol', 18).send({ from: alice });
38
36
  logger.info('Token deployed');
39
37
 
40
38
  // Mint tokens to Alice
41
39
  logger.info(`Minting ${ALICE_MINT_BALANCE} more coins to Alice...`);
42
- await token.methods.mint_to_private(alice, ALICE_MINT_BALANCE).send({ from: alice }).wait();
40
+ await token.methods.mint_to_private(alice, ALICE_MINT_BALANCE).send({ from: alice });
43
41
 
44
42
  logger.info(`${ALICE_MINT_BALANCE} tokens were successfully minted by Alice and transferred to private`);
45
43
 
@@ -48,7 +46,7 @@ async function main() {
48
46
 
49
47
  // We will now transfer tokens from Alice to Bob
50
48
  logger.info(`Transferring ${TRANSFER_AMOUNT} tokens from Alice to Bob...`);
51
- await token.methods.transfer(bob, TRANSFER_AMOUNT).send({ from: alice }).wait();
49
+ await token.methods.transfer(bob, TRANSFER_AMOUNT).send({ from: alice });
52
50
 
53
51
  // Check the new balances
54
52
  const aliceBalance = await token.methods.balance_of_private(alice).simulate({ from: alice });
@@ -49,12 +49,16 @@ export async function setupBananaFPC(initialAccounts: InitialAccountData[], wall
49
49
  const bananaCoinAddress = await getBananaCoinAddress(initialAccounts);
50
50
  const admin = getBananaAdmin(initialAccounts);
51
51
  const [bananaCoin, fpc] = await Promise.all([
52
- TokenContract.deploy(wallet, admin, bananaCoinArgs.name, bananaCoinArgs.symbol, bananaCoinArgs.decimal)
53
- .send({ from: admin, contractAddressSalt: BANANA_COIN_SALT, universalDeploy: true })
54
- .deployed(),
55
- FPCContract.deploy(wallet, bananaCoinAddress, admin)
56
- .send({ from: admin, contractAddressSalt: BANANA_FPC_SALT, universalDeploy: true })
57
- .deployed(),
52
+ TokenContract.deploy(wallet, admin, bananaCoinArgs.name, bananaCoinArgs.symbol, bananaCoinArgs.decimal).send({
53
+ from: admin,
54
+ contractAddressSalt: BANANA_COIN_SALT,
55
+ universalDeploy: true,
56
+ }),
57
+ FPCContract.deploy(wallet, bananaCoinAddress, admin).send({
58
+ from: admin,
59
+ contractAddressSalt: BANANA_FPC_SALT,
60
+ universalDeploy: true,
61
+ }),
58
62
  ]);
59
63
 
60
64
  log(`BananaCoin: ${bananaCoin.address}`);
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env -S node --no-warnings
2
- import { getInitialTestAccountsData } from '@aztec/accounts/testing/lazy';
2
+ import { getInitialTestAccountsData } from '@aztec/accounts/testing';
3
3
  import { AztecNodeService } from '@aztec/aztec-node';
4
4
  import { type AztecNodeConfig, getConfigEnvVars } from '@aztec/aztec-node/config';
5
5
  import { Fr } from '@aztec/aztec.js/fields';
6
6
  import { createLogger } from '@aztec/aztec.js/log';
7
- import { type BlobSinkClientInterface, createBlobSinkClient } from '@aztec/blob-sink/client';
7
+ import { type BlobClientInterface, createBlobClient } from '@aztec/blob-client/client';
8
8
  import { GENESIS_ARCHIVE_ROOT } from '@aztec/constants';
9
9
  import { createEthereumChain } from '@aztec/ethereum/chain';
10
10
  import { waitForPublicClient } from '@aztec/ethereum/client';
@@ -34,6 +34,7 @@ import { foundry } from 'viem/chains';
34
34
  import { createAccountLogs } from '../cli/util.js';
35
35
  import { DefaultMnemonic } from '../mnemonic.js';
36
36
  import { AnvilTestWatcher } from '../testing/anvil_test_watcher.js';
37
+ import { EpochTestSettler } from '../testing/epoch_test_settler.js';
37
38
  import { getBananaFPCAddress, setupBananaFPC } from './banana_fpc.js';
38
39
  import { getSponsoredFPCAddress } from './sponsored_fpc.js';
39
40
 
@@ -50,7 +51,6 @@ export async function deployContractsToL1(
50
51
  aztecNodeConfig: AztecNodeConfig,
51
52
  privateKey: Hex,
52
53
  opts: {
53
- assumeProvenThroughBlockNumber?: number;
54
54
  genesisArchiveRoot?: Fr;
55
55
  feeJuicePortalInitialBalance?: bigint;
56
56
  } = {},
@@ -97,7 +97,11 @@ export async function createLocalNetwork(config: Partial<LocalNetworkConfig> = {
97
97
  if ((config.l1RpcUrls?.length || 0) > 1) {
98
98
  logger.warn(`Multiple L1 RPC URLs provided. Local networks will only use the first one: ${l1RpcUrl}`);
99
99
  }
100
- const aztecNodeConfig: AztecNodeConfig = { ...getConfigEnvVars(), ...config };
100
+
101
+ const aztecNodeConfig: AztecNodeConfig = {
102
+ ...getConfigEnvVars(),
103
+ ...config,
104
+ };
101
105
  const hdAccount = mnemonicToAccount(config.l1Mnemonic || DefaultMnemonic);
102
106
  if (
103
107
  aztecNodeConfig.publisherPrivateKeys == undefined ||
@@ -134,18 +138,20 @@ export async function createLocalNetwork(config: Partial<LocalNetworkConfig> = {
134
138
  : [];
135
139
  const { genesisArchiveRoot, prefilledPublicData, fundingNeeded } = await getGenesisValues(fundedAddresses);
136
140
 
137
- let watcher: AnvilTestWatcher | undefined = undefined;
138
141
  const dateProvider = new TestDateProvider();
142
+
143
+ let cheatcodes: EthCheatCodes | undefined;
144
+ let rollupAddress: EthAddress | undefined;
145
+ let watcher: AnvilTestWatcher | undefined;
139
146
  if (!aztecNodeConfig.p2pEnabled) {
140
- const l1ContractAddresses = await deployContractsToL1(
147
+ ({ rollupAddress } = await deployContractsToL1(
141
148
  aztecNodeConfig,
142
149
  aztecNodeConfig.validatorPrivateKeys.getValue()[0],
143
150
  {
144
- assumeProvenThroughBlockNumber: Number.MAX_SAFE_INTEGER,
145
151
  genesisArchiveRoot,
146
152
  feeJuicePortalInitialBalance: fundingNeeded,
147
153
  },
148
- );
154
+ ));
149
155
 
150
156
  const chain =
151
157
  aztecNodeConfig.l1RpcUrls.length > 0
@@ -157,31 +163,38 @@ export async function createLocalNetwork(config: Partial<LocalNetworkConfig> = {
157
163
  transport: fallback([httpViemTransport(l1RpcUrl)]) as any,
158
164
  });
159
165
 
160
- watcher = new AnvilTestWatcher(
161
- new EthCheatCodes([l1RpcUrl], dateProvider),
162
- l1ContractAddresses.rollupAddress,
163
- publicClient,
164
- dateProvider,
165
- );
166
+ cheatcodes = new EthCheatCodes([l1RpcUrl], dateProvider);
167
+
168
+ watcher = new AnvilTestWatcher(cheatcodes, rollupAddress, publicClient, dateProvider);
166
169
  watcher.setisLocalNetwork(true);
170
+ watcher.setIsMarkingAsProven(false); // Do not mark as proven in the watcher. It's marked in the epochTestSettler after the out hash is set.
171
+
167
172
  await watcher.start();
168
173
  }
169
174
 
170
175
  const telemetry = await initTelemetryClient(getTelemetryClientConfig());
171
- // Create a local blob sink client inside the local network, no http connectivity
172
- const blobSinkClient = createBlobSinkClient();
173
- const node = await createAztecNode(
174
- aztecNodeConfig,
175
- { telemetry, blobSinkClient, dateProvider },
176
- { prefilledPublicData },
177
- );
176
+ // Create a local blob client client inside the local network, no http connectivity
177
+ const blobClient = createBlobClient();
178
+ const node = await createAztecNode(aztecNodeConfig, { telemetry, blobClient, dateProvider }, { prefilledPublicData });
179
+
180
+ let epochTestSettler: EpochTestSettler | undefined;
181
+ if (!aztecNodeConfig.p2pEnabled) {
182
+ epochTestSettler = new EpochTestSettler(
183
+ cheatcodes!,
184
+ rollupAddress!,
185
+ node.getBlockSource(),
186
+ logger.createChild('epoch-settler'),
187
+ { pollingIntervalMs: 200 },
188
+ );
189
+ await epochTestSettler.start();
190
+ }
178
191
 
179
192
  if (initialAccounts.length) {
180
193
  const PXEConfig = { proverEnabled: aztecNodeConfig.realProofs };
181
194
  const wallet = await TestWallet.create(node, PXEConfig);
182
195
 
183
196
  userLog('Setting up funded test accounts...');
184
- const accountManagers = await deployFundedSchnorrAccounts(wallet, node, initialAccounts);
197
+ const accountManagers = await deployFundedSchnorrAccounts(wallet, initialAccounts);
185
198
  const accountsWithSecrets = accountManagers.map((manager, i) => ({
186
199
  account: manager,
187
200
  secretKey: initialAccounts[i].secret,
@@ -200,6 +213,7 @@ export async function createLocalNetwork(config: Partial<LocalNetworkConfig> = {
200
213
  const stop = async () => {
201
214
  await node.stop();
202
215
  await watcher?.stop();
216
+ await epochTestSettler?.stop();
203
217
  };
204
218
 
205
219
  return { node, stop };
@@ -211,7 +225,7 @@ export async function createLocalNetwork(config: Partial<LocalNetworkConfig> = {
211
225
  */
212
226
  export async function createAztecNode(
213
227
  config: Partial<AztecNodeConfig> = {},
214
- deps: { telemetry?: TelemetryClient; blobSinkClient?: BlobSinkClientInterface; dateProvider?: DateProvider } = {},
228
+ deps: { telemetry?: TelemetryClient; blobClient?: BlobClientInterface; dateProvider?: DateProvider } = {},
215
229
  options: { prefilledPublicData?: PublicDataTreeLeaf[] } = {},
216
230
  ) {
217
231
  // TODO(#12272): will clean this up. This is criminal.
@@ -0,0 +1,71 @@
1
+ import { Fr } from '@aztec/aztec.js/fields';
2
+ import { type EthCheatCodes, RollupCheatCodes } from '@aztec/ethereum/test';
3
+ import { type EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
4
+ import type { Logger } from '@aztec/foundation/log';
5
+ import { EpochMonitor } from '@aztec/prover-node';
6
+ import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
7
+ import { computeL2ToL1MembershipWitnessFromMessagesInEpoch } from '@aztec/stdlib/messaging';
8
+
9
+ export class EpochTestSettler {
10
+ private rollupCheatCodes: RollupCheatCodes;
11
+ private epochMonitor?: EpochMonitor;
12
+
13
+ constructor(
14
+ cheatcodes: EthCheatCodes,
15
+ rollupAddress: EthAddress,
16
+ private l2BlockSource: L2BlockSource,
17
+ private log: Logger,
18
+ private options: { pollingIntervalMs: number; provingDelayMs?: number },
19
+ ) {
20
+ this.rollupCheatCodes = new RollupCheatCodes(cheatcodes, { rollupAddress });
21
+ }
22
+
23
+ async start() {
24
+ const { epochDuration } = await this.rollupCheatCodes.getConfig();
25
+ this.epochMonitor = new EpochMonitor(this.l2BlockSource, { epochDuration: Number(epochDuration) }, this.options);
26
+ this.epochMonitor.start(this);
27
+ }
28
+
29
+ async stop() {
30
+ await this.epochMonitor?.stop();
31
+ }
32
+
33
+ async handleEpochReadyToProve(epoch: EpochNumber): Promise<boolean> {
34
+ const checkpointedBlocks = await this.l2BlockSource.getCheckpointedBlocksForEpoch(epoch);
35
+ const blocks = checkpointedBlocks.map(b => b.block);
36
+ this.log.info(
37
+ `Settling epoch ${epoch} with blocks ${blocks[0]?.header.getBlockNumber()} to ${blocks.at(-1)?.header.getBlockNumber()}`,
38
+ { blocks: blocks.map(b => b.toBlockInfo()) },
39
+ );
40
+ const messagesInEpoch: Fr[][][][] = [];
41
+ let previousSlotNumber = SlotNumber.ZERO;
42
+ let checkpointIndex = -1;
43
+
44
+ for (const block of blocks) {
45
+ const slotNumber = block.header.globalVariables.slotNumber;
46
+ if (slotNumber !== previousSlotNumber) {
47
+ checkpointIndex++;
48
+ messagesInEpoch[checkpointIndex] = [];
49
+ previousSlotNumber = slotNumber;
50
+ }
51
+ messagesInEpoch[checkpointIndex].push(block.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs));
52
+ }
53
+
54
+ const [firstMessage] = messagesInEpoch.flat(3);
55
+ if (firstMessage) {
56
+ const { root: outHash } = computeL2ToL1MembershipWitnessFromMessagesInEpoch(messagesInEpoch, firstMessage);
57
+ await this.rollupCheatCodes.insertOutbox(epoch, outHash.toBigInt());
58
+ } else {
59
+ this.log.info(`No L2 to L1 messages in epoch ${epoch}`);
60
+ }
61
+
62
+ const lastCheckpoint = checkpointedBlocks.at(-1)?.checkpointNumber;
63
+ if (lastCheckpoint !== undefined) {
64
+ await this.rollupCheatCodes.markAsProven(lastCheckpoint);
65
+ } else {
66
+ this.log.warn(`No checkpoint found for epoch ${epoch}`);
67
+ }
68
+
69
+ return true;
70
+ }
71
+ }
@@ -1,3 +1,4 @@
1
1
  export { AnvilTestWatcher } from './anvil_test_watcher.js';
2
2
  export { EthCheatCodes, RollupCheatCodes } from '@aztec/ethereum/test';
3
3
  export { CheatCodes } from './cheat_codes.js';
4
+ export { EpochTestSettler } from './epoch_test_settler.js';
@@ -1,3 +0,0 @@
1
- import type { LogFn } from '@aztec/foundation/log';
2
- export declare function startBlobSink(options: any, signalHandlers: (() => Promise<void>)[], userLog: LogFn): Promise<void>;
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhcnRfYmxvYl9zaW5rLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2xpL2NtZHMvc3RhcnRfYmxvYl9zaW5rLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU9BLE9BQU8sS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBS25ELHdCQUFzQixhQUFhLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxjQUFjLEVBQUUsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsT0FBTyxFQUFFLEtBQUssaUJBNEN4RyJ9
@@ -1 +0,0 @@
1
- {"version":3,"file":"start_blob_sink.d.ts","sourceRoot":"","sources":["../../../src/cli/cmds/start_blob_sink.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAKnD,wBAAsB,aAAa,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,iBA4CxG"}