@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.
- package/README.md +1 -1
- package/dest/aztec-node/config.d.ts +4 -1
- package/dest/aztec-node/config.d.ts.map +1 -1
- package/dest/aztec-node/config.js +3 -1
- package/dest/aztec-node/db.d.ts +13 -0
- package/dest/aztec-node/db.d.ts.map +1 -0
- package/dest/aztec-node/db.js +43 -0
- package/dest/aztec-node/http_rpc_server.d.ts +9 -0
- package/dest/aztec-node/http_rpc_server.d.ts.map +1 -0
- package/dest/aztec-node/http_rpc_server.js +30 -0
- package/dest/aztec-node/server.d.ts +35 -44
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +74 -70
- package/dest/bin/index.d.ts +9 -0
- package/dest/bin/index.d.ts.map +1 -0
- package/dest/bin/index.js +53 -0
- package/dest/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -2
- package/package.json +66 -11
- package/src/aztec-node/config.ts +8 -1
- package/src/aztec-node/db.ts +60 -0
- package/src/aztec-node/http_rpc_server.ts +46 -0
- package/src/aztec-node/server.ts +70 -75
- package/src/bin/index.ts +67 -0
- package/src/index.ts +1 -1
- package/.dockerignore +0 -4
- package/.eslintrc.cjs +0 -1
- package/.tsbuildinfo +0 -1
- package/dest/aztec-node/http-node.d.ts +0 -149
- package/dest/aztec-node/http-node.d.ts.map +0 -1
- package/dest/aztec-node/http-node.js +0 -334
- package/dest/aztec-node/http-node.test.d.ts +0 -2
- package/dest/aztec-node/http-node.test.d.ts.map +0 -1
- package/dest/aztec-node/http-node.test.js +0 -386
- package/src/aztec-node/http-node.test.ts +0 -519
- package/src/aztec-node/http-node.ts +0 -388
- 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
package/dest/index.d.ts.map
CHANGED
|
@@ -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,
|
|
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/
|
|
4
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
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
|
|
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
|
|
9
|
-
"@aztec/circuits.js": "0.7
|
|
10
|
-
"@aztec/
|
|
11
|
-
"@aztec/
|
|
12
|
-
"@aztec/
|
|
13
|
-
"@aztec/
|
|
14
|
-
"@aztec/
|
|
15
|
-
"@aztec/
|
|
16
|
-
"@aztec/
|
|
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
|
}
|
package/src/aztec-node/config.ts
CHANGED
|
@@ -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 &
|
|
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
|
+
}
|
package/src/aztec-node/server.ts
CHANGED
|
@@ -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
|
-
|
|
41
|
+
ServerWorldStateSynchronizer,
|
|
42
42
|
WorldStateConfig,
|
|
43
|
-
|
|
43
|
+
WorldStateSynchronizer,
|
|
44
44
|
computePublicDataTreeLeafIndex,
|
|
45
45
|
getConfigEnvVars as getWorldStateConfig,
|
|
46
46
|
} from '@aztec/world-state';
|
|
47
47
|
|
|
48
|
-
import
|
|
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
|
|
61
|
-
protected
|
|
62
|
-
protected
|
|
63
|
-
protected
|
|
64
|
-
protected
|
|
65
|
-
protected
|
|
66
|
-
protected
|
|
67
|
-
protected
|
|
68
|
-
protected
|
|
69
|
-
protected
|
|
70
|
-
protected
|
|
71
|
-
protected
|
|
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
|
-
*
|
|
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.
|
|
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
|
|
93
|
-
const merkleTrees = await MerkleTrees.new(
|
|
91
|
+
const db = await openDb(config);
|
|
92
|
+
const merkleTrees = await MerkleTrees.new(db, await CircuitsWasm.get());
|
|
94
93
|
const worldStateConfig: WorldStateConfig = getWorldStateConfig();
|
|
95
|
-
const
|
|
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(),
|
|
97
|
+
await Promise.all([p2pClient.start(), worldStateSynchronizer.start()]);
|
|
99
98
|
|
|
100
99
|
// now create the sequencer
|
|
101
|
-
const sequencer =
|
|
102
|
-
|
|
103
|
-
p2pClient,
|
|
104
|
-
|
|
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
|
-
|
|
112
|
+
worldStateSynchronizer,
|
|
117
113
|
sequencer,
|
|
118
114
|
config.chainId,
|
|
119
115
|
config.version,
|
|
120
116
|
getGlobalVariableBuilder(config),
|
|
121
|
-
|
|
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
|
-
|
|
236
|
+
this.log.info(`Stopping`);
|
|
237
|
+
await this.sequencer?.stop();
|
|
233
238
|
await this.p2pClient.stop();
|
|
234
|
-
await this.
|
|
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
|
|
258
|
-
* @param
|
|
259
|
-
* @
|
|
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
|
|
262
|
-
const committedDb = await this
|
|
263
|
-
return committedDb.findLeafIndex(
|
|
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
|
|
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
|
|
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
|
|
300
|
+
const index = (await this.findLeafIndex(MerkleTreeId.L1_TO_L2_MESSAGES_TREE, messageKey.toBuffer()))!;
|
|
305
301
|
const message = await this.l1ToL2MessageSource.getConfirmedL1ToL2Message(messageKey);
|
|
306
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
411
|
+
async #getWorldState() {
|
|
417
412
|
try {
|
|
418
413
|
// Attempt to sync the world state if necessary
|
|
419
|
-
await this
|
|
414
|
+
await this.#syncWorldState();
|
|
420
415
|
} catch (err) {
|
|
421
416
|
this.log.error(`Error getting world state: ${err}`);
|
|
422
417
|
}
|
|
423
|
-
return this.
|
|
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
|
-
|
|
425
|
+
async #syncWorldState() {
|
|
431
426
|
const blockSourceHeight = await this.blockSource.getBlockNumber();
|
|
432
|
-
await this.
|
|
427
|
+
await this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
|
|
433
428
|
}
|
|
434
429
|
}
|
package/src/bin/index.ts
ADDED
|
@@ -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
|
+
});
|