@aztec/aztec-node 0.7.10 → 0.8.7

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 (38) hide show
  1. package/README.md +1 -1
  2. package/dest/aztec-node/config.d.ts +4 -1
  3. package/dest/aztec-node/config.d.ts.map +1 -1
  4. package/dest/aztec-node/config.js +3 -1
  5. package/dest/aztec-node/db.d.ts +13 -0
  6. package/dest/aztec-node/db.d.ts.map +1 -0
  7. package/dest/aztec-node/db.js +43 -0
  8. package/dest/aztec-node/http_rpc_server.d.ts +9 -0
  9. package/dest/aztec-node/http_rpc_server.d.ts.map +1 -0
  10. package/dest/aztec-node/http_rpc_server.js +30 -0
  11. package/dest/aztec-node/server.d.ts +35 -44
  12. package/dest/aztec-node/server.d.ts.map +1 -1
  13. package/dest/aztec-node/server.js +74 -70
  14. package/dest/bin/index.d.ts +9 -0
  15. package/dest/bin/index.d.ts.map +1 -0
  16. package/dest/bin/index.js +53 -0
  17. package/dest/index.d.ts +1 -1
  18. package/dest/index.d.ts.map +1 -1
  19. package/dest/index.js +2 -2
  20. package/package.json +66 -11
  21. package/src/aztec-node/config.ts +8 -1
  22. package/src/aztec-node/db.ts +60 -0
  23. package/src/aztec-node/http_rpc_server.ts +46 -0
  24. package/src/aztec-node/server.ts +70 -75
  25. package/src/bin/index.ts +67 -0
  26. package/src/index.ts +1 -1
  27. package/.dockerignore +0 -4
  28. package/.eslintrc.cjs +0 -1
  29. package/.tsbuildinfo +0 -1
  30. package/dest/aztec-node/http-node.d.ts +0 -149
  31. package/dest/aztec-node/http-node.d.ts.map +0 -1
  32. package/dest/aztec-node/http-node.js +0 -334
  33. package/dest/aztec-node/http-node.test.d.ts +0 -2
  34. package/dest/aztec-node/http-node.test.d.ts.map +0 -1
  35. package/dest/aztec-node/http-node.test.js +0 -386
  36. package/src/aztec-node/http-node.test.ts +0 -519
  37. package/src/aztec-node/http-node.ts +0 -388
  38. package/tsconfig.json +0 -38
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":";AAKA,OAAO,MAAM,MAAM,YAAY,CAAC;AAiBhC;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,mBAMnD"}
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env -S node --no-warnings
2
+ import { createDebugLogger } from '@aztec/foundation/log';
3
+ import http from 'http';
4
+ import Router from 'koa-router';
5
+ import { AztecNodeService, createAztecNodeRpcServer, getConfigEnvVars } from '../index.js';
6
+ const { AZTEC_NODE_PORT = 8081, API_PREFIX = '' } = process.env;
7
+ const logger = createDebugLogger('aztec:node');
8
+ /**
9
+ * Creates the node from provided config
10
+ */
11
+ async function createAndDeployAztecNode() {
12
+ const aztecNodeConfig = { ...getConfigEnvVars() };
13
+ return await AztecNodeService.createAndSync(aztecNodeConfig);
14
+ }
15
+ /**
16
+ * Creates a router for helper API endpoints of the Private eXecution Environment (PXE).
17
+ * @param apiPrefix - The prefix to use for all api requests
18
+ * @returns - The router for handling status requests.
19
+ */
20
+ export function createStatusRouter(apiPrefix) {
21
+ const router = new Router({ prefix: `${apiPrefix}` });
22
+ router.get('/status', (ctx) => {
23
+ ctx.status = 200;
24
+ });
25
+ return router;
26
+ }
27
+ /**
28
+ * Create and start a new Aztec Node HTTP Server
29
+ */
30
+ async function main() {
31
+ logger.info(`Setting up Aztec Node...`);
32
+ const aztecNode = await createAndDeployAztecNode();
33
+ const shutdown = async () => {
34
+ logger.info('Shutting down...');
35
+ await aztecNode.stop();
36
+ process.exit(0);
37
+ };
38
+ process.once('SIGINT', shutdown);
39
+ process.once('SIGTERM', shutdown);
40
+ const rpcServer = createAztecNodeRpcServer(aztecNode);
41
+ const app = rpcServer.getApp(API_PREFIX);
42
+ const apiRouter = createStatusRouter(API_PREFIX);
43
+ app.use(apiRouter.routes());
44
+ app.use(apiRouter.allowedMethods());
45
+ const httpServer = http.createServer(app.callback());
46
+ httpServer.listen(+AZTEC_NODE_PORT);
47
+ logger.info(`Aztec Node JSON-RPC Server listening on port ${AZTEC_NODE_PORT}`);
48
+ }
49
+ main().catch(err => {
50
+ logger.error(err);
51
+ process.exit(1);
52
+ });
53
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYmluL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFDQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUUxRCxPQUFPLElBQUksTUFBTSxNQUFNLENBQUM7QUFFeEIsT0FBTyxNQUFNLE1BQU0sWUFBWSxDQUFDO0FBRWhDLE9BQU8sRUFBbUIsZ0JBQWdCLEVBQUUsd0JBQXdCLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFNUcsTUFBTSxFQUFFLGVBQWUsR0FBRyxJQUFJLEVBQUUsVUFBVSxHQUFHLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUM7QUFFaEUsTUFBTSxNQUFNLEdBQUcsaUJBQWlCLENBQUMsWUFBWSxDQUFDLENBQUM7QUFFL0M7O0dBRUc7QUFDSCxLQUFLLFVBQVUsd0JBQXdCO0lBQ3JDLE1BQU0sZUFBZSxHQUFvQixFQUFFLEdBQUcsZ0JBQWdCLEVBQUUsRUFBRSxDQUFDO0lBRW5FLE9BQU8sTUFBTSxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLENBQUM7QUFDL0QsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsa0JBQWtCLENBQUMsU0FBaUI7SUFDbEQsTUFBTSxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsRUFBRSxNQUFNLEVBQUUsR0FBRyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDdEQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxHQUFnQixFQUFFLEVBQUU7UUFDekMsR0FBRyxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUM7SUFDbkIsQ0FBQyxDQUFDLENBQUM7SUFDSCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxLQUFLLFVBQVUsSUFBSTtJQUNqQixNQUFNLENBQUMsSUFBSSxDQUFDLDBCQUEwQixDQUFDLENBQUM7SUFFeEMsTUFBTSxTQUFTLEdBQUcsTUFBTSx3QkFBd0IsRUFBRSxDQUFDO0lBRW5ELE1BQU0sUUFBUSxHQUFHLEtBQUssSUFBSSxFQUFFO1FBQzFCLE1BQU0sQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUNoQyxNQUFNLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN2QixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xCLENBQUMsQ0FBQztJQUVGLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ2pDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBRWxDLE1BQU0sU0FBUyxHQUFHLHdCQUF3QixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3RELE1BQU0sR0FBRyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDekMsTUFBTSxTQUFTLEdBQUcsa0JBQWtCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDakQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUM1QixHQUFHLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDO0lBRXBDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDckQsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ3BDLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0RBQWdELGVBQWUsRUFBRSxDQUFDLENBQUM7QUFDakYsQ0FBQztBQUVELElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRTtJQUNqQixNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2xCLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEIsQ0FBQyxDQUFDLENBQUMifQ==
package/dest/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export * from './aztec-node/config.js';
2
2
  export * from './aztec-node/server.js';
3
- export * from './aztec-node/http-node.js';
3
+ export * from './aztec-node/http_rpc_server.js';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC"}
package/dest/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export * from './aztec-node/config.js';
2
2
  export * from './aztec-node/server.js';
3
- export * from './aztec-node/http-node.js';
4
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsMkJBQTJCLENBQUMifQ==
3
+ export * from './aztec-node/http_rpc_server.js';
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsaUNBQWlDLENBQUMifQ==
package/package.json CHANGED
@@ -1,19 +1,74 @@
1
1
  {
2
2
  "name": "@aztec/aztec-node",
3
- "version": "0.7.10",
4
- "exports": "./dest/index.js",
3
+ "version": "0.8.7",
5
4
  "main": "dest/index.js",
6
5
  "type": "module",
6
+ "exports": "./dest/index.js",
7
+ "bin": "./dest/bin/index.js",
8
+ "typedocOptions": {
9
+ "entryPoints": [
10
+ "./src/index.ts"
11
+ ],
12
+ "name": "Aztec Node",
13
+ "tsconfig": "./tsconfig.json"
14
+ },
15
+ "scripts": {
16
+ "start": "node --no-warnings ./dest/bin",
17
+ "build": "yarn clean && tsc -b",
18
+ "build:dev": "tsc -b --watch",
19
+ "clean": "rm -rf ./dest .tsbuildinfo",
20
+ "formatting": "run -T prettier --check ./src && run -T eslint ./src",
21
+ "formatting:fix": "run -T prettier -w ./src",
22
+ "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --passWithNoTests"
23
+ },
24
+ "inherits": [
25
+ "../package.common.json"
26
+ ],
27
+ "jest": {
28
+ "preset": "ts-jest/presets/default-esm",
29
+ "moduleNameMapper": {
30
+ "^(\\.{1,2}/.*)\\.m?js$": "$1"
31
+ },
32
+ "testRegex": "./src/.*\\.test\\.(js|mjs|ts)$",
33
+ "rootDir": "./src"
34
+ },
7
35
  "dependencies": {
8
- "@aztec/archiver": "0.7.10",
9
- "@aztec/circuits.js": "0.7.10",
10
- "@aztec/foundation": "0.7.10",
11
- "@aztec/l1-artifacts": "0.7.10",
12
- "@aztec/merkle-tree": "0.7.10",
13
- "@aztec/p2p": "0.7.10",
14
- "@aztec/sequencer-client": "0.7.10",
15
- "@aztec/types": "0.7.10",
16
- "@aztec/world-state": "0.7.10",
36
+ "@aztec/archiver": "0.8.7",
37
+ "@aztec/circuits.js": "0.8.7",
38
+ "@aztec/ethereum": "0.8.7",
39
+ "@aztec/foundation": "0.8.7",
40
+ "@aztec/l1-artifacts": "0.8.7",
41
+ "@aztec/merkle-tree": "0.8.7",
42
+ "@aztec/p2p": "0.8.7",
43
+ "@aztec/sequencer-client": "0.8.7",
44
+ "@aztec/types": "0.8.7",
45
+ "@aztec/world-state": "0.8.7",
46
+ "koa": "^2.14.2",
47
+ "koa-router": "^12.0.0",
48
+ "levelup": "^5.1.1",
49
+ "memdown": "^6.1.1",
17
50
  "tslib": "^2.4.0"
51
+ },
52
+ "devDependencies": {
53
+ "@jest/globals": "^29.5.0",
54
+ "@rushstack/eslint-patch": "^1.1.4",
55
+ "@types/jest": "^29.5.0",
56
+ "@types/leveldown": "^4.0.4",
57
+ "@types/levelup": "^5.1.2",
58
+ "@types/memdown": "^3.0.0",
59
+ "@types/node": "^18.7.23",
60
+ "jest": "^29.5.0",
61
+ "ts-jest": "^29.1.0",
62
+ "ts-node": "^10.9.1",
63
+ "typescript": "^5.0.4"
64
+ },
65
+ "files": [
66
+ "dest",
67
+ "src",
68
+ "!*.test.*"
69
+ ],
70
+ "types": "./dest/index.d.ts",
71
+ "engines": {
72
+ "node": ">=18"
18
73
  }
19
74
  }
@@ -6,18 +6,25 @@ import { getConfigEnvVars as getWorldStateVars } from '@aztec/world-state';
6
6
  /**
7
7
  * The configuration the aztec node.
8
8
  */
9
- export type AztecNodeConfig = ArchiverConfig & SequencerClientConfig & P2PConfig;
9
+ export type AztecNodeConfig = ArchiverConfig &
10
+ SequencerClientConfig &
11
+ P2PConfig & {
12
+ /** Whether the sequencer is disabled for this node. */
13
+ disableSequencer: boolean;
14
+ };
10
15
 
11
16
  /**
12
17
  * Returns the config of the aztec node from environment variables with reasonable defaults.
13
18
  * @returns A valid aztec node config.
14
19
  */
15
20
  export function getConfigEnvVars(): AztecNodeConfig {
21
+ const { SEQ_DISABLED } = process.env;
16
22
  const allEnvVars: AztecNodeConfig = {
17
23
  ...getSequencerVars(),
18
24
  ...getArchiverVars(),
19
25
  ...getP2PConfigEnvVars(),
20
26
  ...getWorldStateVars(),
27
+ disableSequencer: !!SEQ_DISABLED,
21
28
  };
22
29
 
23
30
  return allEnvVars;
@@ -0,0 +1,60 @@
1
+ import { LevelDown, default as leveldown } from 'leveldown';
2
+ import { LevelUp, default as levelup } from 'levelup';
3
+ import { MemDown, default as memdown } from 'memdown';
4
+ import { join } from 'node:path';
5
+
6
+ import { AztecNodeConfig } from './config.js';
7
+
8
+ export const createMemDown = () => (memdown as any)() as MemDown<any, any>;
9
+ export const createLevelDown = (path: string) => (leveldown as any)(path) as LevelDown;
10
+
11
+ const DB_SUBDIR = 'aztec-node';
12
+ const NODE_METADATA_KEY = '@@aztec_node_metadata';
13
+
14
+ /**
15
+ * The metadata for an aztec node.
16
+ */
17
+ type NodeMetadata = {
18
+ /**
19
+ * The address of the rollup contract on L1
20
+ */
21
+ rollupContractAddress: string;
22
+ };
23
+
24
+ /**
25
+ * Opens the database for the aztec node.
26
+ * @param config - The configuration to be used by the aztec node.
27
+ * @returns The database for the aztec node.
28
+ */
29
+ export async function openDb(config: AztecNodeConfig): Promise<LevelUp> {
30
+ const nodeMetadata: NodeMetadata = {
31
+ rollupContractAddress: config.l1Contracts.rollupAddress.toString(),
32
+ };
33
+
34
+ const db = levelup(config.dataDirectory ? createLevelDown(join(config.dataDirectory, DB_SUBDIR)) : createMemDown());
35
+ const prevNodeMetadata = await getNodeMetadata(db);
36
+
37
+ // if the rollup addresses are different, wipe the local database and start over
38
+ if (nodeMetadata.rollupContractAddress !== prevNodeMetadata.rollupContractAddress) {
39
+ await db.clear();
40
+ }
41
+
42
+ await db.put(NODE_METADATA_KEY, JSON.stringify(nodeMetadata));
43
+ return db;
44
+ }
45
+
46
+ /**
47
+ * Gets the metadata for the aztec node.
48
+ * @param db - The database for the aztec node.
49
+ * @returns Node metadata.
50
+ */
51
+ async function getNodeMetadata(db: LevelUp): Promise<NodeMetadata> {
52
+ try {
53
+ const value: Buffer = await db.get(NODE_METADATA_KEY);
54
+ return JSON.parse(value.toString('utf-8'));
55
+ } catch {
56
+ return {
57
+ rollupContractAddress: '',
58
+ };
59
+ }
60
+ }
@@ -0,0 +1,46 @@
1
+ import { HistoricBlockData } from '@aztec/circuits.js';
2
+ import { AztecAddress } from '@aztec/foundation/aztec-address';
3
+ import { EthAddress } from '@aztec/foundation/eth-address';
4
+ import { Fr } from '@aztec/foundation/fields';
5
+ import { JsonRpcServer } from '@aztec/foundation/json-rpc/server';
6
+ import {
7
+ AztecNode,
8
+ ContractData,
9
+ ExtendedContractData,
10
+ L1ToL2MessageAndIndex,
11
+ L2Block,
12
+ L2BlockL2Logs,
13
+ L2Tx,
14
+ SiblingPath,
15
+ Tx,
16
+ TxHash,
17
+ } from '@aztec/types';
18
+
19
+ /**
20
+ * Wrap an AztecNode instance with a JSON RPC HTTP server.
21
+ * @param node - The AztecNode
22
+ * @returns An JSON-RPC HTTP server
23
+ */
24
+ export function createAztecNodeRpcServer(node: AztecNode) {
25
+ const rpc = new JsonRpcServer(
26
+ node,
27
+ {
28
+ AztecAddress,
29
+ EthAddress,
30
+ ExtendedContractData,
31
+ ContractData,
32
+ Fr,
33
+ HistoricBlockData,
34
+ L2Block,
35
+ L2Tx,
36
+ TxHash,
37
+ SiblingPath,
38
+ L1ToL2MessageAndIndex,
39
+ },
40
+ { Tx, L2BlockL2Logs },
41
+ false,
42
+ // disable methods not part of the AztecNode interface
43
+ ['start', 'stop'],
44
+ );
45
+ return rpc;
46
+ }
@@ -2,13 +2,13 @@ import { Archiver } from '@aztec/archiver';
2
2
  import {
3
3
  CONTRACT_TREE_HEIGHT,
4
4
  CircuitsWasm,
5
- EthAddress,
6
5
  Fr,
7
6
  GlobalVariables,
8
7
  HistoricBlockData,
9
8
  L1_TO_L2_MSG_TREE_HEIGHT,
10
9
  PRIVATE_DATA_TREE_HEIGHT,
11
10
  } from '@aztec/circuits.js';
11
+ import { L1ContractAddresses } from '@aztec/ethereum';
12
12
  import { AztecAddress } from '@aztec/foundation/aztec-address';
13
13
  import { createDebugLogger } from '@aztec/foundation/log';
14
14
  import { InMemoryTxPool, P2P, createP2PClient } from '@aztec/p2p';
@@ -38,42 +38,41 @@ import {
38
38
  } from '@aztec/types';
39
39
  import {
40
40
  MerkleTrees,
41
- ServerWorldStateSynchroniser,
41
+ ServerWorldStateSynchronizer,
42
42
  WorldStateConfig,
43
- WorldStateSynchroniser,
43
+ WorldStateSynchronizer,
44
44
  computePublicDataTreeLeafIndex,
45
45
  getConfigEnvVars as getWorldStateConfig,
46
46
  } from '@aztec/world-state';
47
47
 
48
- import { default as levelup } from 'levelup';
49
- import { MemDown, default as memdown } from 'memdown';
48
+ import levelup from 'levelup';
50
49
 
51
50
  import { AztecNodeConfig } from './config.js';
52
-
53
- export const createMemDown = () => (memdown as any)() as MemDown<any, any>;
51
+ import { openDb } from './db.js';
54
52
 
55
53
  /**
56
54
  * The aztec node.
57
55
  */
58
56
  export class AztecNodeService implements AztecNode {
59
57
  constructor(
60
- protected p2pClient: P2P,
61
- protected blockSource: L2BlockSource,
62
- protected encryptedLogsSource: L2LogsSource,
63
- protected unencryptedLogsSource: L2LogsSource,
64
- protected contractDataSource: ContractDataSource,
65
- protected l1ToL2MessageSource: L1ToL2MessageSource,
66
- protected worldStateSynchroniser: WorldStateSynchroniser,
67
- protected sequencer: SequencerClient,
68
- protected chainId: number,
69
- protected version: number,
70
- protected globalVariableBuilder: GlobalVariableBuilder,
71
- protected merkleTreesDb: levelup.LevelUp,
58
+ protected readonly config: AztecNodeConfig,
59
+ protected readonly p2pClient: P2P,
60
+ protected readonly blockSource: L2BlockSource,
61
+ protected readonly encryptedLogsSource: L2LogsSource,
62
+ protected readonly unencryptedLogsSource: L2LogsSource,
63
+ protected readonly contractDataSource: ContractDataSource,
64
+ protected readonly l1ToL2MessageSource: L1ToL2MessageSource,
65
+ protected readonly worldStateSynchronizer: WorldStateSynchronizer,
66
+ protected readonly sequencer: SequencerClient | undefined,
67
+ protected readonly chainId: number,
68
+ protected readonly version: number,
69
+ protected readonly globalVariableBuilder: GlobalVariableBuilder,
70
+ protected readonly merkleTreesDb: levelup.LevelUp,
72
71
  private log = createDebugLogger('aztec:node'),
73
72
  ) {}
74
73
 
75
74
  /**
76
- * Initialises the Aztec Node, wait for component to sync.
75
+ * initializes the Aztec Node, wait for component to sync.
77
76
  * @param config - The configuration to be used by the aztec node.
78
77
  * @returns - A fully synced Aztec Node for use in development/testing.
79
78
  */
@@ -83,45 +82,58 @@ export class AztecNodeService implements AztecNode {
83
82
 
84
83
  // we identify the P2P transaction protocol by using the rollup contract address.
85
84
  // this may well change in future
86
- config.transactionProtocol = `/aztec/tx/${config.rollupContract.toString()}`;
85
+ config.transactionProtocol = `/aztec/tx/${config.l1Contracts.rollupAddress.toString()}`;
87
86
 
88
87
  // create the tx pool and the p2p client, which will need the l2 block source
89
88
  const p2pClient = await createP2PClient(config, new InMemoryTxPool(), archiver);
90
89
 
91
90
  // now create the merkle trees and the world state syncher
92
- const merkleTreesDb = levelup(createMemDown());
93
- const merkleTrees = await MerkleTrees.new(merkleTreesDb, await CircuitsWasm.get());
91
+ const db = await openDb(config);
92
+ const merkleTrees = await MerkleTrees.new(db, await CircuitsWasm.get());
94
93
  const worldStateConfig: WorldStateConfig = getWorldStateConfig();
95
- const worldStateSynchroniser = new ServerWorldStateSynchroniser(merkleTrees, archiver, worldStateConfig);
94
+ const worldStateSynchronizer = await ServerWorldStateSynchronizer.new(db, merkleTrees, archiver, worldStateConfig);
96
95
 
97
96
  // start both and wait for them to sync from the block source
98
- await Promise.all([p2pClient.start(), worldStateSynchroniser.start()]);
97
+ await Promise.all([p2pClient.start(), worldStateSynchronizer.start()]);
99
98
 
100
99
  // now create the sequencer
101
- const sequencer = await SequencerClient.new(
102
- config,
103
- p2pClient,
104
- worldStateSynchroniser,
105
- archiver,
106
- archiver,
107
- archiver,
108
- );
100
+ const sequencer = config.disableSequencer
101
+ ? undefined
102
+ : await SequencerClient.new(config, p2pClient, worldStateSynchronizer, archiver, archiver, archiver);
103
+
109
104
  return new AztecNodeService(
105
+ config,
110
106
  p2pClient,
111
107
  archiver,
112
108
  archiver,
113
109
  archiver,
114
110
  archiver,
115
111
  archiver,
116
- worldStateSynchroniser,
112
+ worldStateSynchronizer,
117
113
  sequencer,
118
114
  config.chainId,
119
115
  config.version,
120
116
  getGlobalVariableBuilder(config),
121
- merkleTreesDb,
117
+ db,
122
118
  );
123
119
  }
124
120
 
121
+ /**
122
+ * Returns the sequencer client instance.
123
+ * @returns The sequencer client instance.
124
+ */
125
+ public getSequencer(): SequencerClient | undefined {
126
+ return this.sequencer;
127
+ }
128
+
129
+ /**
130
+ * Method to return the currently deployed L1 contract addresses.
131
+ * @returns - The currently deployed L1 contract addresses.
132
+ */
133
+ public getL1ContractAddresses(): Promise<L1ContractAddresses> {
134
+ return Promise.resolve(this.config.l1Contracts);
135
+ }
136
+
125
137
  /**
126
138
  * Method to determine if the node is ready to accept transactions.
127
139
  * @returns - Flag indicating the readiness for tx submission.
@@ -173,14 +185,6 @@ export class AztecNodeService implements AztecNode {
173
185
  return Promise.resolve(this.chainId);
174
186
  }
175
187
 
176
- /**
177
- * Method to fetch the rollup contract address at the base-layer.
178
- * @returns The rollup address.
179
- */
180
- public getRollupAddress(): Promise<EthAddress> {
181
- return this.blockSource.getRollupAddress();
182
- }
183
-
184
188
  /**
185
189
  * Get the extended contract data for this contract.
186
190
  * @param contractAddress - The contract data address.
@@ -229,9 +233,10 @@ export class AztecNodeService implements AztecNode {
229
233
  * Method to stop the aztec node.
230
234
  */
231
235
  public async stop() {
232
- await this.sequencer.stop();
236
+ this.log.info(`Stopping`);
237
+ await this.sequencer?.stop();
233
238
  await this.p2pClient.stop();
234
- await this.worldStateSynchroniser.stop();
239
+ await this.worldStateSynchronizer.stop();
235
240
  await this.blockSource.stop();
236
241
  this.log.info(`Stopped`);
237
242
  }
@@ -254,13 +259,14 @@ export class AztecNodeService implements AztecNode {
254
259
  }
255
260
 
256
261
  /**
257
- * Find the index of the given contract.
258
- * @param leafValue - The value to search for.
259
- * @returns The index of the given leaf in the contracts tree or undefined if not found.
262
+ * Find the index of the given leaf in the given tree.
263
+ * @param treeId - The tree to search in.
264
+ * @param leafValue - The value to search for
265
+ * @returns The index of the given leaf in the given tree or undefined if not found.
260
266
  */
261
- public async findContractIndex(leafValue: Buffer): Promise<bigint | undefined> {
262
- const committedDb = await this.getWorldState();
263
- return committedDb.findLeafIndex(MerkleTreeId.CONTRACT_TREE, leafValue);
267
+ public async findLeafIndex(treeId: MerkleTreeId, leafValue: Buffer): Promise<bigint | undefined> {
268
+ const committedDb = await this.#getWorldState();
269
+ return committedDb.findLeafIndex(treeId, leafValue);
264
270
  }
265
271
 
266
272
  /**
@@ -269,27 +275,17 @@ export class AztecNodeService implements AztecNode {
269
275
  * @returns The sibling path for the leaf index.
270
276
  */
271
277
  public async getContractPath(leafIndex: bigint): Promise<SiblingPath<typeof CONTRACT_TREE_HEIGHT>> {
272
- const committedDb = await this.getWorldState();
278
+ const committedDb = await this.#getWorldState();
273
279
  return committedDb.getSiblingPath(MerkleTreeId.CONTRACT_TREE, leafIndex);
274
280
  }
275
281
 
276
- /**
277
- * Find the index of the given commitment.
278
- * @param leafValue - The value to search for.
279
- * @returns The index of the given leaf in the private data tree or undefined if not found.
280
- */
281
- public async findCommitmentIndex(leafValue: Buffer): Promise<bigint | undefined> {
282
- const committedDb = await this.getWorldState();
283
- return committedDb.findLeafIndex(MerkleTreeId.PRIVATE_DATA_TREE, leafValue);
284
- }
285
-
286
282
  /**
287
283
  * Returns the sibling path for the given index in the data tree.
288
284
  * @param leafIndex - The index of the leaf for which the sibling path is required.
289
285
  * @returns The sibling path for the leaf index.
290
286
  */
291
287
  public async getDataTreePath(leafIndex: bigint): Promise<SiblingPath<typeof PRIVATE_DATA_TREE_HEIGHT>> {
292
- const committedDb = await this.getWorldState();
288
+ const committedDb = await this.#getWorldState();
293
289
  return committedDb.getSiblingPath(MerkleTreeId.PRIVATE_DATA_TREE, leafIndex);
294
290
  }
295
291
 
@@ -301,10 +297,9 @@ export class AztecNodeService implements AztecNode {
301
297
  */
302
298
  public async getL1ToL2MessageAndIndex(messageKey: Fr): Promise<L1ToL2MessageAndIndex> {
303
299
  // todo: #697 - make this one lookup.
304
- const committedDb = await this.getWorldState();
300
+ const index = (await this.findLeafIndex(MerkleTreeId.L1_TO_L2_MESSAGES_TREE, messageKey.toBuffer()))!;
305
301
  const message = await this.l1ToL2MessageSource.getConfirmedL1ToL2Message(messageKey);
306
- const index = (await committedDb.findLeafIndex(MerkleTreeId.L1_TO_L2_MESSAGES_TREE, messageKey.toBuffer()))!;
307
- return Promise.resolve({ message, index });
302
+ return Promise.resolve(new L1ToL2MessageAndIndex(index, message));
308
303
  }
309
304
 
310
305
  /**
@@ -313,7 +308,7 @@ export class AztecNodeService implements AztecNode {
313
308
  * @returns The sibling path.
314
309
  */
315
310
  public async getL1ToL2MessagesTreePath(leafIndex: bigint): Promise<SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>> {
316
- const committedDb = await this.getWorldState();
311
+ const committedDb = await this.#getWorldState();
317
312
  return committedDb.getSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGES_TREE, leafIndex);
318
313
  }
319
314
 
@@ -325,7 +320,7 @@ export class AztecNodeService implements AztecNode {
325
320
  * Note: Aztec's version of `eth_getStorageAt`.
326
321
  */
327
322
  public async getPublicStorageAt(contract: AztecAddress, slot: bigint): Promise<Buffer | undefined> {
328
- const committedDb = await this.getWorldState();
323
+ const committedDb = await this.#getWorldState();
329
324
  const leafIndex = computePublicDataTreeLeafIndex(contract, new Fr(slot), await CircuitsWasm.get());
330
325
  return committedDb.getLeafValue(MerkleTreeId.PUBLIC_DATA_TREE, leafIndex);
331
326
  }
@@ -335,7 +330,7 @@ export class AztecNodeService implements AztecNode {
335
330
  * @returns The current committed roots for the data trees.
336
331
  */
337
332
  public async getTreeRoots(): Promise<Record<MerkleTreeId, Fr>> {
338
- const committedDb = await this.getWorldState();
333
+ const committedDb = await this.#getWorldState();
339
334
  const getTreeRoot = async (id: MerkleTreeId) => Fr.fromBuffer((await committedDb.getTreeInfo(id)).root);
340
335
 
341
336
  const [privateDataTree, nullifierTree, contractTree, l1ToL2MessagesTree, blocksTree, publicDataTree] =
@@ -363,7 +358,7 @@ export class AztecNodeService implements AztecNode {
363
358
  * @returns The current committed block data.
364
359
  */
365
360
  public async getHistoricBlockData(): Promise<HistoricBlockData> {
366
- const committedDb = await this.getWorldState();
361
+ const committedDb = await this.#getWorldState();
367
362
  const [roots, globalsHash] = await Promise.all([this.getTreeRoots(), committedDb.getLatestGlobalVariablesHash()]);
368
363
 
369
364
  return new HistoricBlockData(
@@ -413,22 +408,22 @@ export class AztecNodeService implements AztecNode {
413
408
  * Returns an instance of MerkleTreeOperations having first ensured the world state is fully synched
414
409
  * @returns An instance of a committed MerkleTreeOperations
415
410
  */
416
- private async getWorldState() {
411
+ async #getWorldState() {
417
412
  try {
418
413
  // Attempt to sync the world state if necessary
419
- await this.syncWorldState();
414
+ await this.#syncWorldState();
420
415
  } catch (err) {
421
416
  this.log.error(`Error getting world state: ${err}`);
422
417
  }
423
- return this.worldStateSynchroniser.getCommitted();
418
+ return this.worldStateSynchronizer.getCommitted();
424
419
  }
425
420
 
426
421
  /**
427
422
  * Ensure we fully sync the world state
428
423
  * @returns A promise that fulfils once the world state is synced
429
424
  */
430
- private async syncWorldState() {
425
+ async #syncWorldState() {
431
426
  const blockSourceHeight = await this.blockSource.getBlockNumber();
432
- await this.worldStateSynchroniser.syncImmediate(blockSourceHeight);
427
+ await this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
433
428
  }
434
429
  }
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env -S node --no-warnings
2
+ import { createDebugLogger } from '@aztec/foundation/log';
3
+
4
+ import http from 'http';
5
+ import Koa from 'koa';
6
+ import Router from 'koa-router';
7
+
8
+ import { AztecNodeConfig, AztecNodeService, createAztecNodeRpcServer, getConfigEnvVars } from '../index.js';
9
+
10
+ const { AZTEC_NODE_PORT = 8081, API_PREFIX = '' } = process.env;
11
+
12
+ const logger = createDebugLogger('aztec:node');
13
+
14
+ /**
15
+ * Creates the node from provided config
16
+ */
17
+ async function createAndDeployAztecNode() {
18
+ const aztecNodeConfig: AztecNodeConfig = { ...getConfigEnvVars() };
19
+
20
+ return await AztecNodeService.createAndSync(aztecNodeConfig);
21
+ }
22
+
23
+ /**
24
+ * Creates a router for helper API endpoints of the Private eXecution Environment (PXE).
25
+ * @param apiPrefix - The prefix to use for all api requests
26
+ * @returns - The router for handling status requests.
27
+ */
28
+ export function createStatusRouter(apiPrefix: string) {
29
+ const router = new Router({ prefix: `${apiPrefix}` });
30
+ router.get('/status', (ctx: Koa.Context) => {
31
+ ctx.status = 200;
32
+ });
33
+ return router;
34
+ }
35
+
36
+ /**
37
+ * Create and start a new Aztec Node HTTP Server
38
+ */
39
+ async function main() {
40
+ logger.info(`Setting up Aztec Node...`);
41
+
42
+ const aztecNode = await createAndDeployAztecNode();
43
+
44
+ const shutdown = async () => {
45
+ logger.info('Shutting down...');
46
+ await aztecNode.stop();
47
+ process.exit(0);
48
+ };
49
+
50
+ process.once('SIGINT', shutdown);
51
+ process.once('SIGTERM', shutdown);
52
+
53
+ const rpcServer = createAztecNodeRpcServer(aztecNode);
54
+ const app = rpcServer.getApp(API_PREFIX);
55
+ const apiRouter = createStatusRouter(API_PREFIX);
56
+ app.use(apiRouter.routes());
57
+ app.use(apiRouter.allowedMethods());
58
+
59
+ const httpServer = http.createServer(app.callback());
60
+ httpServer.listen(+AZTEC_NODE_PORT);
61
+ logger.info(`Aztec Node JSON-RPC Server listening on port ${AZTEC_NODE_PORT}`);
62
+ }
63
+
64
+ main().catch(err => {
65
+ logger.error(err);
66
+ process.exit(1);
67
+ });