@aztec/aztec 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.
Files changed (114) hide show
  1. package/dest/bin/index.js +2 -2
  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 +28 -10
  5. package/dest/cli/aztec_start_options.d.ts +2 -2
  6. package/dest/cli/aztec_start_options.d.ts.map +1 -1
  7. package/dest/cli/aztec_start_options.js +15 -9
  8. package/dest/cli/cli.js +3 -3
  9. package/dest/cli/cmds/compile.d.ts +1 -1
  10. package/dest/cli/cmds/compile.d.ts.map +1 -1
  11. package/dest/cli/cmds/compile.js +10 -15
  12. package/dest/cli/cmds/profile.d.ts +1 -1
  13. package/dest/cli/cmds/profile.d.ts.map +1 -1
  14. package/dest/cli/cmds/profile.js +1 -1
  15. package/dest/cli/cmds/profile_flamegraph.d.ts +1 -1
  16. package/dest/cli/cmds/profile_flamegraph.d.ts.map +1 -1
  17. package/dest/cli/cmds/profile_flamegraph.js +2 -1
  18. package/dest/cli/cmds/profile_gates.d.ts +2 -2
  19. package/dest/cli/cmds/profile_gates.d.ts.map +1 -1
  20. package/dest/cli/cmds/profile_gates.js +23 -4
  21. package/dest/cli/cmds/standby.d.ts +32 -0
  22. package/dest/cli/cmds/standby.d.ts.map +1 -0
  23. package/dest/cli/cmds/standby.js +97 -0
  24. package/dest/cli/cmds/start_archiver.d.ts +2 -2
  25. package/dest/cli/cmds/start_archiver.d.ts.map +1 -1
  26. package/dest/cli/cmds/start_archiver.js +4 -2
  27. package/dest/cli/cmds/start_node.d.ts +3 -2
  28. package/dest/cli/cmds/start_node.d.ts.map +1 -1
  29. package/dest/cli/cmds/start_node.js +26 -36
  30. package/dest/cli/cmds/start_prover_agent.d.ts +1 -1
  31. package/dest/cli/cmds/start_prover_agent.d.ts.map +1 -1
  32. package/dest/cli/cmds/start_prover_agent.js +5 -17
  33. package/dest/cli/cmds/start_prover_broker.d.ts +1 -1
  34. package/dest/cli/cmds/start_prover_broker.d.ts.map +1 -1
  35. package/dest/cli/cmds/start_prover_broker.js +14 -8
  36. package/dest/cli/cmds/start_txe.d.ts +2 -2
  37. package/dest/cli/cmds/start_txe.d.ts.map +1 -1
  38. package/dest/cli/cmds/start_txe.js +4 -3
  39. package/dest/cli/cmds/utils/collect_crate_dirs.d.ts +21 -0
  40. package/dest/cli/cmds/utils/collect_crate_dirs.d.ts.map +1 -0
  41. package/dest/cli/cmds/utils/collect_crate_dirs.js +114 -0
  42. package/dest/cli/cmds/utils/needs_recompile.d.ts +10 -0
  43. package/dest/cli/cmds/utils/needs_recompile.d.ts.map +1 -0
  44. package/dest/cli/cmds/utils/needs_recompile.js +90 -0
  45. package/dest/cli/cmds/utils/warn_if_aztec_version_mismatch.d.ts +4 -0
  46. package/dest/cli/cmds/utils/warn_if_aztec_version_mismatch.d.ts.map +1 -0
  47. package/dest/cli/cmds/utils/warn_if_aztec_version_mismatch.js +62 -0
  48. package/dest/cli/util.d.ts +3 -5
  49. package/dest/cli/util.d.ts.map +1 -1
  50. package/dest/cli/util.js +40 -81
  51. package/dest/examples/token.js +4 -4
  52. package/dest/local-network/banana_fpc.js +1 -1
  53. package/dest/local-network/local-network.d.ts +3 -4
  54. package/dest/local-network/local-network.d.ts.map +1 -1
  55. package/dest/local-network/local-network.js +21 -8
  56. package/dest/testing/anvil_test_watcher.d.ts +7 -3
  57. package/dest/testing/anvil_test_watcher.d.ts.map +1 -1
  58. package/dest/testing/anvil_test_watcher.js +40 -14
  59. package/dest/testing/cheat_codes.d.ts +11 -15
  60. package/dest/testing/cheat_codes.d.ts.map +1 -1
  61. package/dest/testing/cheat_codes.js +34 -32
  62. package/dest/testing/epoch_test_settler.d.ts +1 -1
  63. package/dest/testing/epoch_test_settler.d.ts.map +1 -1
  64. package/dest/testing/epoch_test_settler.js +3 -4
  65. package/dest/testing/index.d.ts +3 -2
  66. package/dest/testing/index.d.ts.map +1 -1
  67. package/dest/testing/index.js +1 -0
  68. package/dest/testing/token_allowed_setup.d.ts +7 -0
  69. package/dest/testing/token_allowed_setup.d.ts.map +1 -0
  70. package/dest/testing/token_allowed_setup.js +20 -0
  71. package/package.json +34 -34
  72. package/scripts/add_crate.sh +52 -0
  73. package/scripts/aztec.sh +9 -2
  74. package/scripts/init.sh +18 -24
  75. package/scripts/new.sh +45 -22
  76. package/scripts/setup_workspace.sh +12 -67
  77. package/scripts/templates/blank/contract/Nargo.toml +6 -0
  78. package/scripts/templates/blank/contract/src/main.nr +10 -0
  79. package/scripts/templates/blank/test/Nargo.toml +7 -0
  80. package/scripts/templates/blank/test/src/lib.nr +11 -0
  81. package/scripts/templates/counter/contract/Nargo.toml +7 -0
  82. package/scripts/templates/counter/contract/src/main.nr +48 -0
  83. package/scripts/templates/counter/test/Nargo.toml +7 -0
  84. package/scripts/templates/counter/test/src/lib.nr +32 -0
  85. package/src/bin/index.ts +2 -2
  86. package/src/cli/aztec_start_action.ts +17 -10
  87. package/src/cli/aztec_start_options.ts +22 -14
  88. package/src/cli/cli.ts +3 -3
  89. package/src/cli/cmds/compile.ts +12 -18
  90. package/src/cli/cmds/profile.ts +2 -1
  91. package/src/cli/cmds/profile_flamegraph.ts +2 -1
  92. package/src/cli/cmds/profile_gates.ts +22 -5
  93. package/src/cli/cmds/standby.ts +132 -0
  94. package/src/cli/cmds/start_archiver.ts +8 -2
  95. package/src/cli/cmds/start_node.ts +40 -34
  96. package/src/cli/cmds/start_prover_agent.ts +5 -8
  97. package/src/cli/cmds/start_prover_broker.ts +16 -16
  98. package/src/cli/cmds/start_txe.ts +5 -3
  99. package/src/cli/cmds/utils/collect_crate_dirs.ts +118 -0
  100. package/src/cli/cmds/utils/needs_recompile.ts +98 -0
  101. package/src/cli/cmds/utils/warn_if_aztec_version_mismatch.ts +77 -0
  102. package/src/cli/util.ts +43 -76
  103. package/src/examples/token.ts +6 -4
  104. package/src/local-network/banana_fpc.ts +1 -1
  105. package/src/local-network/local-network.ts +18 -8
  106. package/src/testing/anvil_test_watcher.ts +44 -13
  107. package/src/testing/cheat_codes.ts +42 -36
  108. package/src/testing/epoch_test_settler.ts +3 -4
  109. package/src/testing/index.ts +2 -1
  110. package/src/testing/token_allowed_setup.ts +19 -0
  111. package/dest/cli/release_version.d.ts +0 -2
  112. package/dest/cli/release_version.d.ts.map +0 -1
  113. package/dest/cli/release_version.js +0 -14
  114. package/src/cli/release_version.ts +0 -21
@@ -0,0 +1,6 @@
1
+ [package]
2
+ name = "__CRATE_NAME___contract"
3
+ type = "contract"
4
+
5
+ [dependencies]
6
+ aztec = { git="https://github.com/AztecProtocol/aztec-nr", tag="v__AZTEC_VERSION__", directory="aztec" }
@@ -0,0 +1,10 @@
1
+ use aztec::macros::aztec;
2
+
3
+ #[aztec]
4
+ pub contract Main {
5
+ use aztec::macros::functions::{external, initializer};
6
+
7
+ #[initializer]
8
+ #[external("private")]
9
+ fn constructor() {}
10
+ }
@@ -0,0 +1,7 @@
1
+ [package]
2
+ name = "__CRATE_NAME___test"
3
+ type = "lib"
4
+
5
+ [dependencies]
6
+ aztec = { git="https://github.com/AztecProtocol/aztec-nr", tag="v__AZTEC_VERSION__", directory="aztec" }
7
+ __CRATE_NAME___contract = { path = "../__CRATE_NAME___contract" }
@@ -0,0 +1,11 @@
1
+ use aztec::test::helpers::test_environment::TestEnvironment;
2
+ use __CRATE_NAME___contract::Main;
3
+
4
+ #[test]
5
+ unconstrained fn test_constructor() {
6
+ let mut env = TestEnvironment::new();
7
+ let deployer = env.create_light_account();
8
+
9
+ let _contract_address = env.deploy("@__CRATE_NAME___contract/Main")
10
+ .with_private_initializer(deployer, Main::interface().constructor());
11
+ }
@@ -0,0 +1,7 @@
1
+ [package]
2
+ name = "__CRATE_NAME___contract"
3
+ type = "contract"
4
+
5
+ [dependencies]
6
+ aztec = { git="https://github.com/AztecProtocol/aztec-nr", tag="v__AZTEC_VERSION__", directory="aztec" }
7
+ balance_set = { git="https://github.com/AztecProtocol/aztec-nr", tag="v__AZTEC_VERSION__", directory="balance-set" }
@@ -0,0 +1,48 @@
1
+ use aztec::macros::aztec;
2
+
3
+ #[aztec]
4
+ pub contract Counter {
5
+ use aztec::{
6
+ macros::{functions::{external, initializer}, storage::storage},
7
+ messages::message_delivery::MessageDelivery,
8
+ protocol::address::AztecAddress,
9
+ state_vars::Owned,
10
+ };
11
+ use balance_set::BalanceSet;
12
+
13
+ #[storage]
14
+ struct Storage<Context> {
15
+ // Each owner has their own counter, stored as private encrypted notes.
16
+ // Owned: dictates who will receive the encrypted notes.
17
+ // BalanceSet: manages the underlying notes, providing add/sub/balance_of.
18
+ counters: Owned<BalanceSet<Context>, Context>,
19
+ }
20
+
21
+ // Sets the owner's counter to an initial value.
22
+ //
23
+ // #[external("private")]: executes on the user's device, inputs are hidden from everyone.
24
+ #[initializer]
25
+ #[external("private")]
26
+ fn constructor(initial_value: u128, owner: AztecAddress) {
27
+ // Delivers the note to the recipient onchain with provable correctness.
28
+ // Without delivery, the recipient can't find or decrypt the note.
29
+ self.storage.counters.at(owner).add(initial_value).deliver(
30
+ MessageDelivery.ONCHAIN_CONSTRAINED,
31
+ );
32
+ }
33
+
34
+ // Adds 1 to the owner's counter.
35
+ #[external("private")]
36
+ fn increment(owner: AztecAddress) {
37
+ self.storage.counters.at(owner).add(1).deliver(MessageDelivery.ONCHAIN_CONSTRAINED);
38
+ }
39
+
40
+ // Returns the current value of the owner's counter.
41
+ //
42
+ // #[external("utility")]: runs off-chain, no transaction created, no cost.
43
+ // Only the owner can decrypt and read their own counter.
44
+ #[external("utility")]
45
+ unconstrained fn get_counter(owner: AztecAddress) -> u128 {
46
+ self.storage.counters.at(owner).balance_of()
47
+ }
48
+ }
@@ -0,0 +1,7 @@
1
+ [package]
2
+ name = "__CRATE_NAME___test"
3
+ type = "lib"
4
+
5
+ [dependencies]
6
+ aztec = { git="https://github.com/AztecProtocol/aztec-nr", tag="v__AZTEC_VERSION__", directory="aztec" }
7
+ __CRATE_NAME___contract = { path = "../__CRATE_NAME___contract" }
@@ -0,0 +1,32 @@
1
+ use aztec::{protocol::address::AztecAddress, test::helpers::test_environment::TestEnvironment};
2
+ use __CRATE_NAME___contract::Counter;
3
+
4
+ unconstrained fn setup(initial_value: u128) -> (TestEnvironment, AztecAddress, AztecAddress) {
5
+ let mut env = TestEnvironment::new();
6
+ let owner = env.create_light_account();
7
+
8
+ let contract_address = env.deploy("@__CRATE_NAME___contract/Counter")
9
+ .with_private_initializer(owner, Counter::interface().constructor(initial_value, owner));
10
+
11
+ (env, contract_address, owner)
12
+ }
13
+
14
+ #[test]
15
+ unconstrained fn test_constructor() {
16
+ let initial_value = 5;
17
+ let (env, contract_address, owner) = setup(initial_value);
18
+
19
+ let counter = env.execute_utility(Counter::at(contract_address).get_counter(owner));
20
+ assert_eq(counter, initial_value);
21
+ }
22
+
23
+ #[test]
24
+ unconstrained fn test_increment() {
25
+ let initial_value = 5;
26
+ let (mut env, contract_address, owner) = setup(initial_value);
27
+
28
+ env.call_private(owner, Counter::at(contract_address).increment(owner));
29
+
30
+ let counter = env.execute_utility(Counter::at(contract_address).get_counter(owner));
31
+ assert_eq(counter, initial_value + 1);
32
+ }
package/src/bin/index.ts CHANGED
@@ -11,6 +11,7 @@ import { injectCommands as injectMiscCommands } from '@aztec/cli/misc';
11
11
  import { injectCommands as injectValidatorKeysCommands } from '@aztec/cli/validator_keys';
12
12
  import { getActiveNetworkName } from '@aztec/foundation/config';
13
13
  import { createConsoleLogger, createLogger } from '@aztec/foundation/log';
14
+ import { getPackageVersion } from '@aztec/stdlib/update-checker';
14
15
 
15
16
  import { Command } from 'commander';
16
17
 
@@ -18,7 +19,6 @@ import { injectCompileCommand } from '../cli/cmds/compile.js';
18
19
  import { injectMigrateCommand } from '../cli/cmds/migrate_ha_db.js';
19
20
  import { injectProfileCommand } from '../cli/cmds/profile.js';
20
21
  import { injectAztecCommands } from '../cli/index.js';
21
- import { getCliVersion } from '../cli/release_version.js';
22
22
 
23
23
  const NETWORK_FLAG = 'network';
24
24
 
@@ -47,7 +47,7 @@ async function main() {
47
47
  await enrichEnvironmentWithNetworkConfig(networkName);
48
48
  enrichEnvironmentWithChainName(networkName);
49
49
 
50
- const cliVersion = getCliVersion();
50
+ const cliVersion = getPackageVersion() ?? 'unknown';
51
51
  let program = new Command('aztec');
52
52
  program.description('Aztec command line interface').version(cliVersion).enablePositionalOptions();
53
53
  program = injectAztecCommands(program, userLog, debugLogger);
@@ -1,3 +1,4 @@
1
+ import { getActiveNetworkName } from '@aztec/foundation/config';
1
2
  import {
2
3
  type NamespacedApiHandlers,
3
4
  createNamespacedSafeJsonRpcServer,
@@ -6,14 +7,14 @@ import {
6
7
  } from '@aztec/foundation/json-rpc/server';
7
8
  import type { LogFn, Logger } from '@aztec/foundation/log';
8
9
  import type { ChainConfig } from '@aztec/stdlib/config';
9
- import { AztecNodeApiSchema } from '@aztec/stdlib/interfaces/client';
10
+ import { AztecNodeAdminApiSchema, AztecNodeApiSchema, AztecNodeDebugApiSchema } from '@aztec/stdlib/interfaces/client';
11
+ import { getPackageVersion } from '@aztec/stdlib/update-checker';
10
12
  import { getVersioningMiddleware } from '@aztec/stdlib/versioning';
11
13
  import { getOtelJsonRpcPropagationMiddleware } from '@aztec/telemetry-client';
12
14
 
13
15
  import { createLocalNetwork } from '../local-network/index.js';
14
16
  import { github, splash } from '../splash.js';
15
17
  import { resolveAdminApiKey } from './admin_api_key_store.js';
16
- import { getCliVersion } from './release_version.js';
17
18
  import { extractNamespacedOptions, installSignalHandlers } from './util.js';
18
19
  import { getVersions } from './versioning.js';
19
20
 
@@ -22,14 +23,13 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg
22
23
  const signalHandlers: Array<() => Promise<void>> = [];
23
24
  const services: NamespacedApiHandlers = {};
24
25
  const adminServices: NamespacedApiHandlers = {};
26
+ const packageVersion = getPackageVersion();
25
27
  let config: ChainConfig | undefined = undefined;
26
28
 
27
29
  if (options.localNetwork) {
28
- const cliVersion = getCliVersion();
29
- const localNetwork = extractNamespacedOptions(options, 'local-network');
30
- localNetwork.testAccounts = true;
30
+ const localNetwork = extractNamespacedOptions(options, 'localNetwork');
31
31
  userLog(`${splash}\n${github}\n\n`);
32
- userLog(`Setting up Aztec local network ${cliVersion}, please stand by...`);
32
+ userLog(`Setting up Aztec local network ${packageVersion ?? 'unknown'}, please stand by...`);
33
33
 
34
34
  const { node, stop } = await createLocalNetwork(
35
35
  {
@@ -49,6 +49,8 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg
49
49
  // Start Node and PXE JSON-RPC server
50
50
  signalHandlers.push(stop);
51
51
  services.node = [node, AztecNodeApiSchema];
52
+ adminServices.node = [node, AztecNodeAdminApiSchema];
53
+ services.nodeDebug = [node, AztecNodeDebugApiSchema];
52
54
  } else {
53
55
  // Route --prover-node through startNode
54
56
  if (options.proverNode && !options.node) {
@@ -57,7 +59,11 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg
57
59
 
58
60
  if (options.node) {
59
61
  const { startNode } = await import('./cmds/start_node.js');
60
- ({ config } = await startNode(options, signalHandlers, services, adminServices, userLog));
62
+ const networkName = getActiveNetworkName(options.network);
63
+ ({ config } = await startNode(options, signalHandlers, services, adminServices, userLog, networkName));
64
+ if (options.nodeDebug && services.node) {
65
+ services.nodeDebug = [services.node[0], AztecNodeDebugApiSchema];
66
+ }
61
67
  } else if (options.bot) {
62
68
  const { startBot } = await import('./cmds/start_bot.js');
63
69
  await startBot(options, signalHandlers, services, userLog);
@@ -75,7 +81,7 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg
75
81
  await startProverBroker(options, signalHandlers, services, userLog);
76
82
  } else if (options.txe) {
77
83
  const { startTXE } = await import('./cmds/start_txe.js');
78
- await startTXE(options, debugLogger);
84
+ await startTXE(options, signalHandlers, debugLogger);
79
85
  } else if (options.sequencer) {
80
86
  userLog(`Cannot run a standalone sequencer without a node`);
81
87
  process.exit(1);
@@ -87,13 +93,14 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg
87
93
 
88
94
  installSignalHandlers(debugLogger.info, signalHandlers);
89
95
  const versions = getVersions(config);
96
+ const versioningOpts = { packageVersion };
90
97
 
91
98
  // Start the main JSON-RPC server
92
99
  if (Object.entries(services).length > 0) {
93
100
  const rpcServer = createNamespacedSafeJsonRpcServer(services, {
94
101
  http200OnError: false,
95
102
  log: debugLogger,
96
- middlewares: [getOtelJsonRpcPropagationMiddleware(), getVersioningMiddleware(versions)],
103
+ middlewares: [getOtelJsonRpcPropagationMiddleware(), getVersioningMiddleware(versions, versioningOpts)],
97
104
  maxBatchSize: options.rpcMaxBatchSize,
98
105
  maxBodySizeBytes: options.rpcMaxBodySize,
99
106
  });
@@ -103,7 +110,7 @@ export async function aztecStart(options: any, userLog: LogFn, debugLogger: Logg
103
110
 
104
111
  // If there are any admin services, start a separate JSON-RPC server for them
105
112
  if (Object.entries(adminServices).length > 0) {
106
- const adminMiddlewares = [getOtelJsonRpcPropagationMiddleware(), getVersioningMiddleware(versions)];
113
+ const adminMiddlewares = [getOtelJsonRpcPropagationMiddleware(), getVersioningMiddleware(versions, versioningOpts)];
107
114
 
108
115
  // Resolve the admin API key (auto-generated and persisted, or opt-out)
109
116
  const apiKeyResolution = await resolveAdminApiKey(
@@ -12,7 +12,6 @@ import {
12
12
  isBooleanConfigValue,
13
13
  omitConfigMappings,
14
14
  } from '@aztec/foundation/config';
15
- import { dataConfigMappings } from '@aztec/kv-store/config';
16
15
  import { sharedNodeConfigMappings } from '@aztec/node-lib/config';
17
16
  import { bootnodeConfigMappings, p2pConfigMappings } from '@aztec/p2p/config';
18
17
  import { proverAgentConfigMappings, proverBrokerConfigMappings } from '@aztec/prover-client/broker/config';
@@ -20,6 +19,7 @@ import { proverNodeConfigMappings } from '@aztec/prover-node/config';
20
19
  import { allPxeConfigMappings } from '@aztec/pxe/config';
21
20
  import { sequencerClientConfigMappings } from '@aztec/sequencer-client/config';
22
21
  import { chainConfigMappings, nodeRpcConfigMappings } from '@aztec/stdlib/config';
22
+ import { dataConfigMappings } from '@aztec/stdlib/kv-store';
23
23
  import { telemetryClientConfigMappings } from '@aztec/telemetry-client/config';
24
24
  import { worldStateConfigMappings } from '@aztec/world-state/config';
25
25
 
@@ -36,7 +36,7 @@ export interface AztecStartOption {
36
36
  parseVal?: (val: string) => any;
37
37
  }
38
38
 
39
- export const getOptions = (namespace: string, configMappings: Record<string, ConfigMapping>) => {
39
+ export const getOptions = (namespace: string, configMappings: Record<string, ConfigMapping<unknown>>) => {
40
40
  const options: AztecStartOption[] = [];
41
41
  for (const [key, { env, defaultValue: def, parseEnv, description, printDefault, fallback }] of Object.entries(
42
42
  configMappings,
@@ -58,7 +58,11 @@ export const getOptions = (namespace: string, configMappings: Record<string, Con
58
58
  return options;
59
59
  };
60
60
 
61
- const configToFlag = (flag: string, configMapping: ConfigMapping, overrideDefaultValue?: any): AztecStartOption => {
61
+ const configToFlag = (
62
+ flag: string,
63
+ configMapping: ConfigMapping<unknown>,
64
+ overrideDefaultValue?: any,
65
+ ): AztecStartOption => {
62
66
  if (!configMapping.isBoolean) {
63
67
  flag += ' <value>';
64
68
  }
@@ -105,8 +109,7 @@ export const aztecStartOptions: { [key: string]: AztecStartOption[] } = {
105
109
  env: 'NETWORK',
106
110
  },
107
111
 
108
- configToFlag('--auto-update', sharedNodeConfigMappings.autoUpdate),
109
- configToFlag('--auto-update-url', sharedNodeConfigMappings.autoUpdateUrl),
112
+ configToFlag('--enable-version-check', sharedNodeConfigMappings.enableVersionCheck),
110
113
 
111
114
  configToFlag('--sync-mode', sharedNodeConfigMappings.syncMode),
112
115
  configToFlag('--snapshots-urls', sharedNodeConfigMappings.snapshotsUrls),
@@ -126,6 +129,12 @@ export const aztecStartOptions: { [key: string]: AztecStartOption[] } = {
126
129
  defaultValue: DefaultMnemonic,
127
130
  env: 'MNEMONIC',
128
131
  },
132
+ {
133
+ flag: '--local-network.testAccounts',
134
+ description: 'Deploy test accounts on local network start',
135
+ env: 'TEST_ACCOUNTS',
136
+ ...booleanConfigHelper(true),
137
+ },
129
138
  ],
130
139
  API: [
131
140
  {
@@ -166,6 +175,13 @@ export const aztecStartOptions: { [key: string]: AztecStartOption[] } = {
166
175
  env: 'AZTEC_RESET_ADMIN_API_KEY',
167
176
  parseVal: val => val === 'true' || val === '1',
168
177
  },
178
+ {
179
+ flag: '--node-debug',
180
+ description: 'Expose debug endpoints (e.g. mineBlock) on the main RPC port',
181
+ defaultValue: false,
182
+ env: 'AZTEC_NODE_DEBUG',
183
+ parseVal: val => val === undefined || val === 'true' || val === '1',
184
+ },
169
185
  {
170
186
  flag: '--api-prefix <value>',
171
187
  description: 'Prefix for API routes on any service that is started',
@@ -310,15 +326,7 @@ export const aztecStartOptions: { [key: string]: AztecStartOption[] } = {
310
326
  },
311
327
  ...getOptions('bot', botConfigMappings),
312
328
  ],
313
- PXE: [
314
- {
315
- flag: '--pxe',
316
- description: 'Starts Aztec PXE with options',
317
- defaultValue: undefined,
318
- env: undefined,
319
- },
320
- ...getOptions('pxe', allPxeConfigMappings),
321
- ],
329
+ PXE: [...getOptions('pxe', allPxeConfigMappings)],
322
330
  TXE: [
323
331
  {
324
332
  flag: '--txe',
package/src/cli/cli.ts CHANGED
@@ -37,9 +37,9 @@ export function injectAztecCommands(program: Command, userLog: LogFn, debugLogge
37
37
  `
38
38
  Additional commands:
39
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
- test [options] starts a TXE and runs "nargo test" using it as the oracle resolver.
40
+ init creates a new Aztec Noir workspace in the current directory.
41
+ new <name> creates a new Aztec Noir workspace in its own directory (or creates a new contract-test crates pair and adds it to the current workspace if run in workspace).
42
+ test [options] starts a TXE and runs "nargo test" using it as the oracle resolver.
43
43
  `,
44
44
  );
45
45
  }
@@ -1,12 +1,15 @@
1
+ import { findBbBinary } from '@aztec/bb.js';
1
2
  import type { LogFn } from '@aztec/foundation/log';
2
3
 
3
4
  import { execFileSync } from 'child_process';
4
5
  import type { Command } from 'commander';
5
- import { readFile, writeFile } from 'fs/promises';
6
+ import { readFile } from 'fs/promises';
6
7
  import { join } from 'path';
7
8
 
8
9
  import { readArtifactFiles } from './utils/artifacts.js';
10
+ import { needsRecompile } from './utils/needs_recompile.js';
9
11
  import { run } from './utils/spawn.js';
12
+ import { warnIfAztecVersionMismatch } from './utils/warn_if_aztec_version_mismatch.js';
10
13
 
11
14
  /** Returns paths to contract artifacts in the target directory. */
12
15
  async function collectContractArtifacts(): Promise<string[]> {
@@ -22,19 +25,6 @@ async function collectContractArtifacts(): Promise<string[]> {
22
25
  return files.filter(f => Array.isArray(f.content.functions)).map(f => f.filePath);
23
26
  }
24
27
 
25
- /** Strips the `__aztec_nr_internals__` prefix from function names in contract artifacts. */
26
- async function stripInternalPrefixes(artifactPaths: string[]): Promise<void> {
27
- for (const path of artifactPaths) {
28
- const artifact = JSON.parse(await readFile(path, 'utf-8'));
29
- for (const fn of artifact.functions) {
30
- if (typeof fn.name === 'string') {
31
- fn.name = fn.name.replace(/^__aztec_nr_internals__/, '');
32
- }
33
- }
34
- await writeFile(path, JSON.stringify(artifact, null, 2) + '\n');
35
- }
36
- }
37
-
38
28
  /** Returns the set of package names that are contract crates in the current workspace. */
39
29
  async function getContractPackageNames(): Promise<Set<string>> {
40
30
  const contractNames = new Set<string>();
@@ -137,8 +127,15 @@ async function checkNoTestsInContracts(nargo: string, log: LogFn): Promise<void>
137
127
 
138
128
  /** Compiles Aztec Noir contracts and postprocesses artifacts. */
139
129
  async function compileAztecContract(nargoArgs: string[], log: LogFn): Promise<void> {
130
+ await warnIfAztecVersionMismatch(log);
131
+
132
+ if (!(await needsRecompile())) {
133
+ log('No source changes detected, skipping compilation.');
134
+ return;
135
+ }
136
+
140
137
  const nargo = process.env.NARGO ?? 'nargo';
141
- const bb = process.env.BB ?? 'bb';
138
+ const bb = process.env.BB ?? findBbBinary() ?? 'bb';
142
139
 
143
140
  await run(nargo, ['compile', ...nargoArgs]);
144
141
 
@@ -151,9 +148,6 @@ async function compileAztecContract(nargoArgs: string[], log: LogFn): Promise<vo
151
148
  log('Postprocessing contracts...');
152
149
  const bbArgs = artifacts.flatMap(a => ['-i', a]);
153
150
  await run(bb, ['aztec_process', ...bbArgs]);
154
-
155
- // TODO: This should be part of bb aztec_process!
156
- await stripInternalPrefixes(artifacts);
157
151
  }
158
152
 
159
153
  log('Compilation complete!');
@@ -11,8 +11,9 @@ export function injectProfileCommand(program: Command, log: LogFn): Command {
11
11
  profile
12
12
  .command('gates')
13
13
  .argument('[target-dir]', 'Path to the compiled artifacts directory', './target')
14
+ .option('--json', 'Output gate counts as JSON instead of a table', false)
14
15
  .description('Display gate counts for all compiled Aztec artifacts in a target directory.')
15
- .action((targetDir: string) => profileGates(targetDir, log));
16
+ .action((targetDir: string, options: { json: boolean }) => profileGates(targetDir, options.json, log));
16
17
 
17
18
  profile
18
19
  .command('flamegraph')
@@ -1,3 +1,4 @@
1
+ import { findBbBinary } from '@aztec/bb.js';
1
2
  import type { LogFn } from '@aztec/foundation/log';
2
3
 
3
4
  import { readFile, rename, rm, writeFile } from 'fs/promises';
@@ -33,7 +34,7 @@ export async function profileFlamegraph(artifactPath: string, functionName: stri
33
34
  await writeFile(functionArtifact, makeFunctionArtifact(artifact, func));
34
35
 
35
36
  const profiler = process.env.PROFILER_PATH ?? 'noir-profiler';
36
- const bb = process.env.BB ?? 'bb';
37
+ const bb = process.env.BB ?? findBbBinary() ?? 'bb';
37
38
 
38
39
  await run(profiler, [
39
40
  'gates',
@@ -1,3 +1,4 @@
1
+ import { findBbBinary } from '@aztec/bb.js';
1
2
  import { asyncPool } from '@aztec/foundation/async-pool';
2
3
  import type { LogFn } from '@aztec/foundation/log';
3
4
 
@@ -5,12 +6,13 @@ import { execFile as execFileCb } from 'child_process';
5
6
  import { rm } from 'fs/promises';
6
7
  import { promisify } from 'util';
7
8
 
8
- import { MAX_CONCURRENT, discoverArtifacts } from './profile_utils.js';
9
+ import { type DiscoveredArtifact, MAX_CONCURRENT, discoverArtifacts } from './profile_utils.js';
9
10
 
10
11
  const execFile = promisify(execFileCb);
11
12
 
12
13
  interface GateCountResult {
13
14
  name: string;
15
+ type: DiscoveredArtifact['type'];
14
16
  gateCount: number;
15
17
  }
16
18
 
@@ -31,24 +33,39 @@ async function getGateCount(bb: string, artifactPath: string): Promise<number> {
31
33
  }
32
34
 
33
35
  /** Profiles all compiled artifacts in a target directory and prints gate counts. */
34
- export async function profileGates(targetDir: string, log: LogFn): Promise<void> {
35
- const bb = process.env.BB ?? 'bb';
36
+ export async function profileGates(targetDir: string, json: boolean, log: LogFn): Promise<void> {
37
+ const bb = process.env.BB ?? findBbBinary() ?? 'bb';
36
38
  const { artifacts, tmpDir } = await discoverArtifacts(targetDir);
37
39
 
38
40
  if (artifacts.length === 0) {
39
- log('No artifacts found in target directory.');
41
+ if (json) {
42
+ log('[]');
43
+ } else {
44
+ log('No artifacts found in target directory.');
45
+ }
40
46
  return;
41
47
  }
42
48
 
43
49
  try {
44
50
  const results: GateCountResult[] = await asyncPool(MAX_CONCURRENT, artifacts, async artifact => ({
45
51
  name: artifact.name,
52
+ type: artifact.type,
46
53
  gateCount: await getGateCount(bb, artifact.filePath),
47
54
  }));
48
55
  results.sort((a, b) => a.name.localeCompare(b.name));
49
56
 
50
57
  if (results.length === 0) {
51
- log('No constrained circuits found.');
58
+ if (json) {
59
+ log('[]');
60
+ } else {
61
+ log('No constrained circuits found.');
62
+ }
63
+ return;
64
+ }
65
+
66
+ if (json) {
67
+ const entries = results.map(r => ({ name: r.name, type: r.type, gates: r.gateCount }));
68
+ log(JSON.stringify(entries, null, 2));
52
69
  return;
53
70
  }
54
71
 
@@ -0,0 +1,132 @@
1
+ import { getInitialTestAccountsData } from '@aztec/accounts/testing';
2
+ import type { Fr } from '@aztec/aztec.js/fields';
3
+ import { getSponsoredFPCAddress } from '@aztec/cli/cli-utils';
4
+ import { getPublicClient } from '@aztec/ethereum/client';
5
+ import type { GenesisStateConfig } from '@aztec/ethereum/config';
6
+ import { RegistryContract, RollupContract } from '@aztec/ethereum/contracts';
7
+ import type { EthAddress } from '@aztec/foundation/eth-address';
8
+ import { startHttpRpcServer } from '@aztec/foundation/json-rpc/server';
9
+ import type { LogFn } from '@aztec/foundation/log';
10
+ import { retryUntil } from '@aztec/foundation/retry';
11
+ import { AztecAddress } from '@aztec/stdlib/aztec-address';
12
+ import { getGenesisValues } from '@aztec/world-state/testing';
13
+
14
+ import Koa from 'koa';
15
+
16
+ const ROLLUP_POLL_INTERVAL_S = 60;
17
+
18
+ /**
19
+ * Computes the expected genesis archive root from the genesis state config.
20
+ * Reads test accounts and sponsored FPC addresses as specified, then computes
21
+ * the genesis values including the archive root and prefilled public data.
22
+ */
23
+ export async function computeExpectedGenesisRoot(config: GenesisStateConfig, userLog: LogFn) {
24
+ const testAccounts = config.testAccounts ? (await getInitialTestAccountsData()).map(a => a.address) : [];
25
+ const sponsoredFPCAccounts = config.sponsoredFPC ? [await getSponsoredFPCAddress()] : [];
26
+ const prefundAddresses = (config.prefundAddresses ?? []).map(a => AztecAddress.fromString(a));
27
+ const initialFundedAccounts = testAccounts.concat(sponsoredFPCAccounts).concat(prefundAddresses);
28
+
29
+ userLog(`Initial funded accounts: ${initialFundedAccounts.map(a => a.toString()).join(', ')}`);
30
+
31
+ const { genesisArchiveRoot, genesis } = await getGenesisValues(initialFundedAccounts);
32
+
33
+ userLog(`Genesis archive root: ${genesisArchiveRoot.toString()}`);
34
+
35
+ return { genesisArchiveRoot, genesis };
36
+ }
37
+
38
+ async function checkRollupCompatibility(
39
+ rollup: RollupContract,
40
+ expected: { genesisArchiveRoot: Fr; vkTreeRoot: Fr; protocolContractsHash: Fr },
41
+ ): Promise<string[]> {
42
+ const mismatches: string[] = [];
43
+ const [l1Genesis, l1Vk, l1Protocol] = await Promise.all([
44
+ rollup.getGenesisArchiveTreeRoot(),
45
+ rollup.getVkTreeRoot(),
46
+ rollup.getProtocolContractsHash(),
47
+ ]);
48
+ if (!l1Genesis.equals(expected.genesisArchiveRoot)) {
49
+ mismatches.push(`genesis archive root (expected ${expected.genesisArchiveRoot}, got ${l1Genesis})`);
50
+ }
51
+ if (!l1Vk.equals(expected.vkTreeRoot)) {
52
+ mismatches.push(`VK tree root (expected ${expected.vkTreeRoot}, got ${l1Vk})`);
53
+ }
54
+ if (!l1Protocol.equals(expected.protocolContractsHash)) {
55
+ mismatches.push(`protocol contracts hash (expected ${expected.protocolContractsHash}, got ${l1Protocol})`);
56
+ }
57
+ return mismatches;
58
+ }
59
+
60
+ /**
61
+ * Waits until the canonical rollup's genesis archive root, VK tree root, and protocol contracts hash
62
+ * all match the expected local values. If the rollup is not yet compatible (e.g. during L1 contract upgrades),
63
+ * enters standby mode: starts a lightweight HTTP server for K8s liveness probes and polls every 60s
64
+ * until a compatible rollup appears.
65
+ */
66
+ export async function waitForCompatibleRollup(
67
+ config: {
68
+ l1RpcUrls: string[];
69
+ l1ChainId: number;
70
+ l1Contracts: { registryAddress: EthAddress };
71
+ rollupVersion?: number;
72
+ },
73
+ expected: { genesisArchiveRoot: Fr; vkTreeRoot: Fr; protocolContractsHash: Fr },
74
+ port: number | undefined,
75
+ userLog: LogFn,
76
+ ): Promise<void> {
77
+ const publicClient = getPublicClient(config);
78
+ const rollupVersion: number | 'canonical' = config.rollupVersion ?? 'canonical';
79
+
80
+ const registry = new RegistryContract(publicClient, config.l1Contracts.registryAddress);
81
+ const rollupAddress = await registry.getRollupAddress(rollupVersion);
82
+ const rollup = new RollupContract(publicClient, rollupAddress.toString());
83
+
84
+ let mismatches: string[];
85
+ try {
86
+ mismatches = await checkRollupCompatibility(rollup, expected);
87
+ } catch (err: any) {
88
+ throw new Error(`Could not retrieve rollup config from canonical rollup at ${rollupAddress}: ${err.message}`);
89
+ }
90
+
91
+ if (mismatches.length === 0) {
92
+ return;
93
+ }
94
+
95
+ userLog(
96
+ `Rollup at ${rollupAddress} is incompatible: ${mismatches.join('; ')}. ` +
97
+ `Entering standby mode. Will poll every ${ROLLUP_POLL_INTERVAL_S}s for a compatible rollup...`,
98
+ );
99
+
100
+ const standbyServer = await startHttpRpcServer({ getApp: () => new Koa(), isHealthy: () => true }, { port });
101
+ userLog(`Standby status server listening on port ${standbyServer.port}`);
102
+
103
+ try {
104
+ await retryUntil(
105
+ async () => {
106
+ const currentRollupAddress = await registry.getRollupAddress(rollupVersion);
107
+ const currentRollup = new RollupContract(publicClient, currentRollupAddress.toString());
108
+
109
+ let currentMismatches: string[];
110
+ try {
111
+ currentMismatches = await checkRollupCompatibility(currentRollup, expected);
112
+ } catch {
113
+ userLog(`Failed to fetch rollup config from rollup at ${currentRollupAddress}. Retrying...`);
114
+ return undefined;
115
+ }
116
+
117
+ if (currentMismatches.length === 0) {
118
+ userLog(`Compatible rollup found at ${currentRollupAddress}. Exiting standby mode.`);
119
+ return true;
120
+ }
121
+
122
+ userLog(`Still waiting. Rollup at ${currentRollupAddress}: ${currentMismatches.join('; ')}.`);
123
+ return undefined;
124
+ },
125
+ 'compatible rollup',
126
+ 0,
127
+ ROLLUP_POLL_INTERVAL_S,
128
+ );
129
+ } finally {
130
+ await new Promise<void>((resolve, reject) => standbyServer.close(err => (err ? reject(err) : resolve())));
131
+ }
132
+ }