@aztec-labs/aztec-node 6.0.0-nightly.20260829
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 +15 -0
- package/dest/aztec-node/block_response_helpers.d.ts +25 -0
- package/dest/aztec-node/block_response_helpers.d.ts.map +1 -0
- package/dest/aztec-node/block_response_helpers.js +112 -0
- package/dest/aztec-node/config.d.ts +52 -0
- package/dest/aztec-node/config.d.ts.map +1 -0
- package/dest/aztec-node/config.js +129 -0
- package/dest/aztec-node/node_metrics.d.ts +12 -0
- package/dest/aztec-node/node_metrics.d.ts.map +1 -0
- package/dest/aztec-node/node_metrics.js +36 -0
- package/dest/aztec-node/node_public_calls_simulator.d.ts +108 -0
- package/dest/aztec-node/node_public_calls_simulator.d.ts.map +1 -0
- package/dest/aztec-node/node_public_calls_simulator.js +380 -0
- package/dest/aztec-node/public_data_overrides.d.ts +13 -0
- package/dest/aztec-node/public_data_overrides.d.ts.map +1 -0
- package/dest/aztec-node/public_data_overrides.js +21 -0
- package/dest/aztec-node/register_node_rpc_handlers.d.ts +11 -0
- package/dest/aztec-node/register_node_rpc_handlers.d.ts.map +1 -0
- package/dest/aztec-node/register_node_rpc_handlers.js +48 -0
- package/dest/aztec-node/server.d.ts +281 -0
- package/dest/aztec-node/server.d.ts.map +1 -0
- package/dest/aztec-node/server.js +1235 -0
- package/dest/bin/index.d.ts +3 -0
- package/dest/bin/index.d.ts.map +1 -0
- package/dest/bin/index.js +57 -0
- package/dest/factory.d.ts +33 -0
- package/dest/factory.d.ts.map +1 -0
- package/dest/factory.js +539 -0
- package/dest/index.d.ts +5 -0
- package/dest/index.d.ts.map +1 -0
- package/dest/index.js +4 -0
- package/dest/modules/block_parameter.d.ts +25 -0
- package/dest/modules/block_parameter.d.ts.map +1 -0
- package/dest/modules/block_parameter.js +100 -0
- package/dest/modules/node_block_provider.d.ts +19 -0
- package/dest/modules/node_block_provider.d.ts.map +1 -0
- package/dest/modules/node_block_provider.js +112 -0
- package/dest/modules/node_tx_receipt.d.ts +24 -0
- package/dest/modules/node_tx_receipt.d.ts.map +1 -0
- package/dest/modules/node_tx_receipt.js +70 -0
- package/dest/modules/node_world_state_queries.d.ts +65 -0
- package/dest/modules/node_world_state_queries.d.ts.map +1 -0
- package/dest/modules/node_world_state_queries.js +270 -0
- package/dest/sentinel/config.d.ts +9 -0
- package/dest/sentinel/config.d.ts.map +1 -0
- package/dest/sentinel/config.js +39 -0
- package/dest/sentinel/factory.d.ts +11 -0
- package/dest/sentinel/factory.d.ts.map +1 -0
- package/dest/sentinel/factory.js +24 -0
- package/dest/sentinel/index.d.ts +3 -0
- package/dest/sentinel/index.d.ts.map +1 -0
- package/dest/sentinel/index.js +1 -0
- package/dest/sentinel/sentinel.d.ts +217 -0
- package/dest/sentinel/sentinel.d.ts.map +1 -0
- package/dest/sentinel/sentinel.js +551 -0
- package/dest/sentinel/store.d.ts +35 -0
- package/dest/sentinel/store.d.ts.map +1 -0
- package/dest/sentinel/store.js +182 -0
- package/dest/test/index.d.ts +31 -0
- package/dest/test/index.d.ts.map +1 -0
- package/dest/test/index.js +1 -0
- package/package.json +118 -0
- package/src/aztec-node/block_response_helpers.ts +161 -0
- package/src/aztec-node/config.ts +216 -0
- package/src/aztec-node/node_metrics.ts +49 -0
- package/src/aztec-node/node_public_calls_simulator.ts +437 -0
- package/src/aztec-node/public_data_overrides.ts +35 -0
- package/src/aztec-node/register_node_rpc_handlers.ts +45 -0
- package/src/aztec-node/server.ts +1155 -0
- package/src/bin/index.ts +77 -0
- package/src/factory.ts +704 -0
- package/src/index.ts +4 -0
- package/src/modules/block_parameter.ts +93 -0
- package/src/modules/node_block_provider.ts +149 -0
- package/src/modules/node_tx_receipt.ts +115 -0
- package/src/modules/node_world_state_queries.ts +373 -0
- package/src/sentinel/README.md +103 -0
- package/src/sentinel/config.ts +49 -0
- package/src/sentinel/factory.ts +46 -0
- package/src/sentinel/index.ts +8 -0
- package/src/sentinel/sentinel.ts +694 -0
- package/src/sentinel/store.ts +193 -0
- package/src/test/index.ts +32 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env -S node --no-warnings
|
|
2
|
+
import { createNamespacedSafeJsonRpcServer, startHttpRpcServer } from '@aztec-labs/foundation/json-rpc/server';
|
|
3
|
+
import { createLogger } from '@aztec-labs/foundation/log';
|
|
4
|
+
import { getRpcCorsAllowedOrigins } from '@aztec-labs/stdlib/config';
|
|
5
|
+
import { getOtelJsonRpcDiagnosticsMiddleware, getOtelJsonRpcPropagationMiddleware, getOtelJsonRpcServerMetricsMiddleware } from '@aztec-labs/telemetry-client';
|
|
6
|
+
import { createAztecNodeService, getConfigEnvVars, registerAztecNodeRpcHandlers } from '../index.js';
|
|
7
|
+
const { AZTEC_NODE_PORT = 8081, API_PREFIX = '' } = process.env;
|
|
8
|
+
const logger = createLogger('node');
|
|
9
|
+
/**
|
|
10
|
+
* Creates the node from provided config
|
|
11
|
+
*/ async function createAndDeployAztecNode(aztecNodeConfig) {
|
|
12
|
+
return await createAztecNodeService(aztecNodeConfig);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Create and start a new Aztec Node HTTP Server
|
|
16
|
+
*/ async function main() {
|
|
17
|
+
logger.info(`Setting up Aztec Node...`);
|
|
18
|
+
const aztecNodeConfig = {
|
|
19
|
+
...getConfigEnvVars()
|
|
20
|
+
};
|
|
21
|
+
const aztecNode = await createAndDeployAztecNode(aztecNodeConfig);
|
|
22
|
+
const shutdown = async ()=>{
|
|
23
|
+
logger.info('Shutting down...');
|
|
24
|
+
await aztecNode.stop();
|
|
25
|
+
process.exit(0);
|
|
26
|
+
};
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
28
|
+
process.once('SIGINT', shutdown);
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
30
|
+
process.once('SIGTERM', shutdown);
|
|
31
|
+
const services = {};
|
|
32
|
+
registerAztecNodeRpcHandlers(aztecNode, services, undefined, {
|
|
33
|
+
p2pHealthMinPeers: aztecNodeConfig.p2pHealthMinPeers
|
|
34
|
+
});
|
|
35
|
+
const rpcServer = createNamespacedSafeJsonRpcServer(services, {
|
|
36
|
+
diagnostic: getOtelJsonRpcDiagnosticsMiddleware(),
|
|
37
|
+
middlewares: [
|
|
38
|
+
getOtelJsonRpcServerMetricsMiddleware(),
|
|
39
|
+
getOtelJsonRpcPropagationMiddleware()
|
|
40
|
+
],
|
|
41
|
+
maxBatchSize: aztecNodeConfig.rpcMaxBatchSize,
|
|
42
|
+
maxBodySizeBytes: aztecNodeConfig.rpcMaxBodySize,
|
|
43
|
+
corsAllowedHeaders: aztecNodeConfig.rpcCorsAllowedHeaders,
|
|
44
|
+
corsAllowedOrigins: getRpcCorsAllowedOrigins(aztecNodeConfig)
|
|
45
|
+
});
|
|
46
|
+
await startHttpRpcServer(rpcServer, {
|
|
47
|
+
port: +AZTEC_NODE_PORT,
|
|
48
|
+
apiPrefix: API_PREFIX,
|
|
49
|
+
keepAliveTimeoutMs: aztecNodeConfig.rpcHttpKeepAliveTimeoutMs,
|
|
50
|
+
headersTimeoutMs: aztecNodeConfig.rpcHttpHeadersTimeoutMs
|
|
51
|
+
});
|
|
52
|
+
logger.info(`Aztec Node JSON-RPC Server listening on port ${AZTEC_NODE_PORT}`);
|
|
53
|
+
}
|
|
54
|
+
main().catch((err)=>{
|
|
55
|
+
logger.error(err);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type Logger } from '@aztec-labs/foundation/log';
|
|
2
|
+
import { DateProvider } from '@aztec-labs/foundation/timer';
|
|
3
|
+
import { type P2PClientDeps } from '@aztec-labs/p2p';
|
|
4
|
+
import { type ProverNodeDeps } from '@aztec-labs/prover-node';
|
|
5
|
+
import { type SequencerPublisher } from '@aztec-labs/sequencer-client';
|
|
6
|
+
import type { GenesisData } from '@aztec-labs/stdlib/world-state';
|
|
7
|
+
import { type TelemetryClient } from '@aztec-labs/telemetry-client';
|
|
8
|
+
import type { SlashingProtectionDatabase } from '@aztec-labs/validator-ha-signer/types';
|
|
9
|
+
import { type AztecNodeConfig } from './aztec-node/config.js';
|
|
10
|
+
import { AztecNodeService } from './aztec-node/server.js';
|
|
11
|
+
/** Dependencies that can be injected when creating a node, mostly to override defaults in tests. */
|
|
12
|
+
export interface CreateAztecNodeDeps {
|
|
13
|
+
telemetry?: TelemetryClient;
|
|
14
|
+
logger?: Logger;
|
|
15
|
+
publisher?: SequencerPublisher;
|
|
16
|
+
dateProvider?: DateProvider;
|
|
17
|
+
p2pClientDeps?: P2PClientDeps;
|
|
18
|
+
proverNodeDeps?: Partial<ProverNodeDeps>;
|
|
19
|
+
slashingProtectionDb?: SlashingProtectionDatabase;
|
|
20
|
+
}
|
|
21
|
+
/** Options controlling which subsystems are started when creating a node. */
|
|
22
|
+
export interface CreateAztecNodeOptions {
|
|
23
|
+
genesis?: GenesisData;
|
|
24
|
+
dontStartSequencer?: boolean;
|
|
25
|
+
dontStartProverNode?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Initializes the Aztec Node, waiting for its components to sync.
|
|
29
|
+
* @param inputConfig - The configuration to be used by the aztec node.
|
|
30
|
+
* @returns A fully synced Aztec Node for use in development/testing.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createAztecNodeService(inputConfig: AztecNodeConfig, deps?: CreateAztecNodeDeps, options?: CreateAztecNodeOptions): Promise<AztecNodeService>;
|
|
33
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2ZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBWUEsT0FBTyxFQUFFLEtBQUssTUFBTSxFQUFnQixNQUFNLDRCQUE0QixDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUk1RCxPQUFPLEVBQUUsS0FBSyxhQUFhLEVBQW1CLE1BQU0saUJBQWlCLENBQUM7QUFDdEUsT0FBTyxFQUFtQixLQUFLLGNBQWMsRUFBb0IsTUFBTSx5QkFBeUIsQ0FBQztBQUVqRyxPQUFPLEVBSUwsS0FBSyxrQkFBa0IsRUFDeEIsTUFBTSw4QkFBOEIsQ0FBQztBQWlCdEMsT0FBTyxLQUFLLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDbEUsT0FBTyxFQUFFLEtBQUssZUFBZSxFQUFzQixNQUFNLDhCQUE4QixDQUFDO0FBVXhGLE9BQU8sS0FBSyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFJeEYsT0FBTyxFQUFFLEtBQUssZUFBZSxFQUE4QixNQUFNLHdCQUF3QixDQUFDO0FBQzFGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRzFELG9HQUFvRztBQUNwRyxNQUFNLFdBQVcsbUJBQW1CO0lBQ2xDLFNBQVMsQ0FBQyxFQUFFLGVBQWUsQ0FBQztJQUM1QixNQUFNLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDaEIsU0FBUyxDQUFDLEVBQUUsa0JBQWtCLENBQUM7SUFDL0IsWUFBWSxDQUFDLEVBQUUsWUFBWSxDQUFDO0lBQzVCLGFBQWEsQ0FBQyxFQUFFLGFBQWEsQ0FBQztJQUM5QixjQUFjLENBQUMsRUFBRSxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDekMsb0JBQW9CLENBQUMsRUFBRSwwQkFBMEIsQ0FBQztDQUNuRDtBQUVELDZFQUE2RTtBQUM3RSxNQUFNLFdBQVcsc0JBQXNCO0lBQ3JDLE9BQU8sQ0FBQyxFQUFFLFdBQVcsQ0FBQztJQUN0QixrQkFBa0IsQ0FBQyxFQUFFLE9BQU8sQ0FBQztJQUM3QixtQkFBbUIsQ0FBQyxFQUFFLE9BQU8sQ0FBQztDQUMvQjtBQUVEOzs7O0dBSUc7QUFDSCx3QkFBc0Isc0JBQXNCLENBQzFDLFdBQVcsRUFBRSxlQUFlLEVBQzVCLElBQUksR0FBRSxtQkFBd0IsRUFDOUIsT0FBTyxHQUFFLHNCQUEyQixHQUNuQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0E2a0IzQiJ9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAI5D,OAAO,EAAE,KAAK,aAAa,EAAmB,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAmB,KAAK,cAAc,EAAoB,MAAM,yBAAyB,CAAC;AAEjG,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,8BAA8B,CAAC;AAiBtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,8BAA8B,CAAC;AAUxF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AAIxF,OAAO,EAAE,KAAK,eAAe,EAA8B,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,oGAAoG;AACpG,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACzC,oBAAoB,CAAC,EAAE,0BAA0B,CAAC;CACnD;AAED,6EAA6E;AAC7E,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,eAAe,EAC5B,IAAI,GAAE,mBAAwB,EAC9B,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,gBAAgB,CAAC,CA6kB3B"}
|
package/dest/factory.js
ADDED
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
import { createArchiver } from '@aztec-labs/archiver';
|
|
2
|
+
import { BBCircuitVerifier, BatchChonkVerifier, QueuedIVCVerifier } from '@aztec-labs/bb-prover';
|
|
3
|
+
import { TestCircuitVerifier } from '@aztec-labs/bb-prover/test';
|
|
4
|
+
import { createBlobClientWithFileStores } from '@aztec-labs/blob-client/client';
|
|
5
|
+
import { Blob, getKzg } from '@aztec-labs/blob-lib';
|
|
6
|
+
import { EpochCache } from '@aztec-labs/epoch-cache';
|
|
7
|
+
import { createEthereumChain } from '@aztec-labs/ethereum/chain';
|
|
8
|
+
import { getPublicClient, makeL1HttpTransport } from '@aztec-labs/ethereum/client';
|
|
9
|
+
import { RegistryContract, RollupContract } from '@aztec-labs/ethereum/contracts';
|
|
10
|
+
import { pickL1ContractAddresses } from '@aztec-labs/ethereum/l1-contract-addresses';
|
|
11
|
+
import { compactArray } from '@aztec-labs/foundation/collection';
|
|
12
|
+
import { createLogger } from '@aztec-labs/foundation/log';
|
|
13
|
+
import { DateProvider } from '@aztec-labs/foundation/timer';
|
|
14
|
+
import { KeystoreManager, loadKeystores, mergeKeystores } from '@aztec-labs/node-keystore';
|
|
15
|
+
import { trySnapshotSync } from '@aztec-labs/node-lib/actions';
|
|
16
|
+
import { createForwarderL1TxUtilsFromSigners, createL1TxUtilsFromSigners } from '@aztec-labs/node-lib/factories';
|
|
17
|
+
import { createP2PClient } from '@aztec-labs/p2p';
|
|
18
|
+
import { createProverNode } from '@aztec-labs/prover-node';
|
|
19
|
+
import { createKeyStoreForProver } from '@aztec-labs/prover-node/config';
|
|
20
|
+
import { FeeProviderImpl, GlobalVariableBuilder, SequencerClient } from '@aztec-labs/sequencer-client';
|
|
21
|
+
import { createAutomineSequencer } from '@aztec-labs/sequencer-client/automine';
|
|
22
|
+
import { AvmSimulatorPool } from '@aztec-labs/simulator/server';
|
|
23
|
+
import { AttestationsBlockWatcher, AttestedInvalidProposalWatcher, BroadcastedInvalidCheckpointProposalWatcher, CheckpointEquivocationWatcher, DataWithholdingWatcher, createSlasher } from '@aztec-labs/slasher';
|
|
24
|
+
import { CheckpointReexecutionTracker } from '@aztec-labs/stdlib/checkpoint';
|
|
25
|
+
import { tryStop } from '@aztec-labs/stdlib/interfaces/server';
|
|
26
|
+
import { InMemoryDebugLogStore, NullDebugLogStore } from '@aztec-labs/stdlib/logs';
|
|
27
|
+
import { getPackageVersion } from '@aztec-labs/stdlib/update-checker';
|
|
28
|
+
import { getTelemetryClient } from '@aztec-labs/telemetry-client';
|
|
29
|
+
import { FullNodeCheckpointsBuilder as CheckpointsBuilder, FullNodeCheckpointsBuilder, NodeKeystoreAdapter, ValidatorClient, createProposalHandler, createValidatorClient } from '@aztec-labs/validator-client';
|
|
30
|
+
import { createWorldState, createWorldStateSynchronizer } from '@aztec-labs/world-state';
|
|
31
|
+
import { createPublicClient } from 'viem';
|
|
32
|
+
import { createKeyStoreForValidator } from './aztec-node/config.js';
|
|
33
|
+
import { AztecNodeService } from './aztec-node/server.js';
|
|
34
|
+
import { createSentinel } from './sentinel/factory.js';
|
|
35
|
+
/**
|
|
36
|
+
* Initializes the Aztec Node, waiting for its components to sync.
|
|
37
|
+
* @param inputConfig - The configuration to be used by the aztec node.
|
|
38
|
+
* @returns A fully synced Aztec Node for use in development/testing.
|
|
39
|
+
*/ export async function createAztecNodeService(inputConfig, deps = {}, options = {}) {
|
|
40
|
+
const config = {
|
|
41
|
+
...inputConfig
|
|
42
|
+
}; // Copy the config so we dont mutate the input object
|
|
43
|
+
const log = deps.logger ?? createLogger('node');
|
|
44
|
+
// Initialise the bb.js sync WASM singleton here, before any subsystem runs.
|
|
45
|
+
const { BarretenbergSync } = await import('@aztec/bb.js');
|
|
46
|
+
await BarretenbergSync.initSingleton();
|
|
47
|
+
// Warm the KZG trusted-setup singleton before any subsystem runs. getKzg() synchronously builds
|
|
48
|
+
// its precomputation tables on first use (~2s locally, blocking the event loop; 12-15s under
|
|
49
|
+
// production CPU limits). If that first use is instead the archiver reconstructing blobs or the
|
|
50
|
+
// proposal handler uploading them, the stalled loop overruns the gossipsub mcache window and
|
|
51
|
+
// attestation forwarding is skipped. Paying it here keeps it off the gossip path. Idempotent, so
|
|
52
|
+
// it is a no-op for sequencers (warmed in Sequencer.init) and for tests that pre-warm via
|
|
53
|
+
// warmBlobKzg.
|
|
54
|
+
getKzg(log);
|
|
55
|
+
const packageVersion = getPackageVersion();
|
|
56
|
+
const telemetry = deps.telemetry ?? getTelemetryClient();
|
|
57
|
+
const dateProvider = deps.dateProvider ?? new DateProvider();
|
|
58
|
+
const ethereumChain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
|
|
59
|
+
// Build a key store from file if given or from environment otherwise.
|
|
60
|
+
// We keep the raw KeyStore available so we can merge with prover keys if enableProverNode is set.
|
|
61
|
+
let keyStoreManager;
|
|
62
|
+
const keyStoreProvided = config.keyStoreDirectory !== undefined && config.keyStoreDirectory.length > 0;
|
|
63
|
+
if (keyStoreProvided) {
|
|
64
|
+
const keyStores = loadKeystores(config.keyStoreDirectory);
|
|
65
|
+
keyStoreManager = new KeystoreManager(mergeKeystores(keyStores));
|
|
66
|
+
} else {
|
|
67
|
+
const rawKeyStores = [];
|
|
68
|
+
const validatorKeyStore = createKeyStoreForValidator(config);
|
|
69
|
+
if (validatorKeyStore) {
|
|
70
|
+
rawKeyStores.push(validatorKeyStore);
|
|
71
|
+
}
|
|
72
|
+
if (config.enableProverNode) {
|
|
73
|
+
const proverKeyStore = createKeyStoreForProver(config);
|
|
74
|
+
if (proverKeyStore) {
|
|
75
|
+
rawKeyStores.push(proverKeyStore);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (rawKeyStores.length > 0) {
|
|
79
|
+
keyStoreManager = new KeystoreManager(rawKeyStores.length === 1 ? rawKeyStores[0] : mergeKeystores(rawKeyStores));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
await keyStoreManager?.validateSigners();
|
|
83
|
+
// If we are a validator, verify our configuration before doing too much more.
|
|
84
|
+
if (!config.disableValidator) {
|
|
85
|
+
if (keyStoreManager === undefined) {
|
|
86
|
+
throw new Error('Failed to create key store, a requirement for running a validator');
|
|
87
|
+
}
|
|
88
|
+
if (!keyStoreProvided && process.env.NODE_ENV !== 'test') {
|
|
89
|
+
log.warn("Keystore created from env: it's recommended to use a file-based key store for production");
|
|
90
|
+
}
|
|
91
|
+
ValidatorClient.validateKeyStoreConfiguration(keyStoreManager, log);
|
|
92
|
+
}
|
|
93
|
+
// validate that the actual chain id matches that specified in configuration
|
|
94
|
+
if (config.l1ChainId !== ethereumChain.chainInfo.id) {
|
|
95
|
+
throw new Error(`RPC URL configured for chain id ${ethereumChain.chainInfo.id} but expected id ${config.l1ChainId}`);
|
|
96
|
+
}
|
|
97
|
+
const publicClient = createPublicClient({
|
|
98
|
+
chain: ethereumChain.chainInfo,
|
|
99
|
+
transport: makeL1HttpTransport(config.l1RpcUrls, {
|
|
100
|
+
timeout: config.l1HttpTimeoutMS
|
|
101
|
+
}),
|
|
102
|
+
pollingInterval: config.viemPollingIntervalMS
|
|
103
|
+
});
|
|
104
|
+
const l1ContractsAddresses = await RegistryContract.collectAddresses(publicClient, config.registryAddress, config.rollupVersion ?? 'canonical');
|
|
105
|
+
Object.assign(config, l1ContractsAddresses);
|
|
106
|
+
const rollupContract = new RollupContract(publicClient, config.rollupAddress.toString());
|
|
107
|
+
const [l1GenesisTime, slotDuration, epochDuration, rollupVersionFromRollup, rollupManaLimit] = await Promise.all([
|
|
108
|
+
rollupContract.getL1GenesisTime(),
|
|
109
|
+
rollupContract.getSlotDuration(),
|
|
110
|
+
rollupContract.getEpochDuration(),
|
|
111
|
+
rollupContract.getVersion(),
|
|
112
|
+
rollupContract.getManaLimit().then(Number)
|
|
113
|
+
]);
|
|
114
|
+
config.rollupVersion ??= Number(rollupVersionFromRollup);
|
|
115
|
+
if (config.rollupVersion !== Number(rollupVersionFromRollup)) {
|
|
116
|
+
log.warn(`Registry looked up and returned a rollup with version (${config.rollupVersion}), but this does not match with version detected from the rollup directly: (${rollupVersionFromRollup}).`);
|
|
117
|
+
}
|
|
118
|
+
const blobClient = await createBlobClientWithFileStores(config, log.createChild('blob-client'));
|
|
119
|
+
// attempt snapshot sync if possible
|
|
120
|
+
await trySnapshotSync(config, log);
|
|
121
|
+
const epochCache = await EpochCache.create(config.rollupAddress, config, {
|
|
122
|
+
dateProvider
|
|
123
|
+
});
|
|
124
|
+
// Track started resources so we can clean up on partial failure during node creation.
|
|
125
|
+
const started = [];
|
|
126
|
+
try {
|
|
127
|
+
config.skipOrphanProposedBlockPruning ||= !!config.useAutomineSequencer;
|
|
128
|
+
checkConfigMatchesRollup(config, {
|
|
129
|
+
slotDuration: Number(slotDuration),
|
|
130
|
+
epochDuration: Number(epochDuration)
|
|
131
|
+
});
|
|
132
|
+
// Create world-state first so we can retrieve the initial header before constructing the archiver.
|
|
133
|
+
const nativeWs = await createWorldState(config, options.genesis);
|
|
134
|
+
const initialHeader = nativeWs.getInitialHeader();
|
|
135
|
+
const initialBlockHash = await initialHeader.hash();
|
|
136
|
+
// AVM execution backend for public simulation: a pool of bb-avm-sim processes reaching the world state
|
|
137
|
+
// over its IPC socket. Owned here and threaded into the public-processor consumers (node, checkpoint
|
|
138
|
+
// builders, prover node); disposed on stop via the started-resources cleanup.
|
|
139
|
+
log.info('WSDB ready, creating AVM simulator pool');
|
|
140
|
+
const avmSimulator = await AvmSimulatorPool.spawn({
|
|
141
|
+
wsdbIpcPath: nativeWs.getIpcPath(),
|
|
142
|
+
logger: (msg)=>log.debug(msg)
|
|
143
|
+
});
|
|
144
|
+
started.push({
|
|
145
|
+
stop: ()=>avmSimulator[Symbol.asyncDispose]()
|
|
146
|
+
});
|
|
147
|
+
const archiver = await createArchiver(config, {
|
|
148
|
+
blobClient,
|
|
149
|
+
epochCache,
|
|
150
|
+
telemetry,
|
|
151
|
+
dateProvider
|
|
152
|
+
}, {
|
|
153
|
+
blockUntilSync: !config.skipArchiverInitialSync
|
|
154
|
+
}, initialHeader, initialBlockHash);
|
|
155
|
+
started.push(archiver);
|
|
156
|
+
// The synchronizer takes ownership of the native world-state from here
|
|
157
|
+
const worldStateSynchronizer = await createWorldStateSynchronizer(config, archiver, nativeWs, telemetry);
|
|
158
|
+
started.push(worldStateSynchronizer);
|
|
159
|
+
const useRealVerifiers = config.realProofs || config.debugForceTxProofVerification;
|
|
160
|
+
let peerProofVerifier;
|
|
161
|
+
let rpcProofVerifier;
|
|
162
|
+
if (useRealVerifiers) {
|
|
163
|
+
peerProofVerifier = await BatchChonkVerifier.new(config, config.bbChonkVerifyMaxBatch, 'peer');
|
|
164
|
+
const rpcVerifier = await BBCircuitVerifier.new(config);
|
|
165
|
+
rpcProofVerifier = new QueuedIVCVerifier(rpcVerifier, config.numConcurrentIVCVerifiers);
|
|
166
|
+
} else {
|
|
167
|
+
peerProofVerifier = new TestCircuitVerifier(config.proverTestVerificationDelayMs);
|
|
168
|
+
rpcProofVerifier = new TestCircuitVerifier(config.proverTestVerificationDelayMs);
|
|
169
|
+
}
|
|
170
|
+
started.push(peerProofVerifier, rpcProofVerifier);
|
|
171
|
+
let debugLogStore;
|
|
172
|
+
if (!config.realProofs) {
|
|
173
|
+
log.warn(`Aztec node is accepting fake proofs`);
|
|
174
|
+
debugLogStore = new InMemoryDebugLogStore();
|
|
175
|
+
log.info('Aztec node started in test mode (realProofs set to false) hence debug logs from public functions will be collected and served');
|
|
176
|
+
} else {
|
|
177
|
+
debugLogStore = new NullDebugLogStore();
|
|
178
|
+
}
|
|
179
|
+
const globalVariableBuilderConfig = {
|
|
180
|
+
rollupAddress: config.rollupAddress,
|
|
181
|
+
ethereumSlotDuration: config.ethereumSlotDuration,
|
|
182
|
+
rollupVersion: BigInt(config.rollupVersion),
|
|
183
|
+
l1GenesisTime,
|
|
184
|
+
slotDuration: Number(slotDuration)
|
|
185
|
+
};
|
|
186
|
+
const globalVariableBuilder = new GlobalVariableBuilder(publicClient, globalVariableBuilderConfig);
|
|
187
|
+
const feeProvider = new FeeProviderImpl(dateProvider, publicClient, globalVariableBuilderConfig);
|
|
188
|
+
await feeProvider.start();
|
|
189
|
+
started.push(feeProvider);
|
|
190
|
+
const collectOffenses = !config.disableValidator || config.enableOffenseCollection;
|
|
191
|
+
// A prover node may still be proving an epoch whose blocks have already finalized on L1. Its proof
|
|
192
|
+
// submission window spans (proofSubmissionEpochs + 1) epochs, so its tx pool must keep finalized txs
|
|
193
|
+
// for at least that long to re-fetch them for proving and failure upload. Operators may configure a
|
|
194
|
+
// larger margin but not a smaller one.
|
|
195
|
+
if (config.enableProverNode) {
|
|
196
|
+
const proofSubmissionEpochs = await rollupContract.getProofSubmissionEpochs();
|
|
197
|
+
const proverRetentionFloorSlots = (proofSubmissionEpochs + 1) * Number(epochDuration);
|
|
198
|
+
const configuredSlots = config.keepFinalizedTxsForSlots ?? 0;
|
|
199
|
+
if (proverRetentionFloorSlots > configuredSlots) {
|
|
200
|
+
log.warn(`Increasing keepFinalizedTxsForSlots from ${configuredSlots} to ${proverRetentionFloorSlots} ` + `(proof submission window of ${proofSubmissionEpochs + 1} epochs) to retain finalized txs for proving`);
|
|
201
|
+
config.keepFinalizedTxsForSlots = proverRetentionFloorSlots;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// create the tx pool and the p2p client, which will need the l2 block source
|
|
205
|
+
const p2pClient = await createP2PClient(config, archiver, peerProofVerifier, worldStateSynchronizer, epochCache, feeProvider, packageVersion, dateProvider, telemetry, deps.p2pClientDeps, initialBlockHash);
|
|
206
|
+
started.push(p2pClient);
|
|
207
|
+
archiver.setCheckpointProposalPresence(p2pClient);
|
|
208
|
+
// We'll accumulate sentinel watchers here
|
|
209
|
+
const watchers = [];
|
|
210
|
+
// Create FullNodeCheckpointsBuilder for block proposal handling and tx validation.
|
|
211
|
+
// Override maxTxsPerCheckpoint with the validator-specific limit if set.
|
|
212
|
+
const validatorCheckpointsBuilder = new FullNodeCheckpointsBuilder({
|
|
213
|
+
...config,
|
|
214
|
+
l1GenesisTime,
|
|
215
|
+
slotDuration: Number(slotDuration),
|
|
216
|
+
rollupManaLimit,
|
|
217
|
+
maxTxsPerCheckpoint: config.validateMaxTxsPerCheckpoint
|
|
218
|
+
}, worldStateSynchronizer, archiver, dateProvider, avmSimulator, telemetry);
|
|
219
|
+
let validatorClient;
|
|
220
|
+
// The proposal handler (validator-owned or standalone) tracks invalid-proposal/equivocation slots and
|
|
221
|
+
// feeds the attested-invalid-proposal watcher, so the watcher works on non-validator nodes too.
|
|
222
|
+
let proposalHandler;
|
|
223
|
+
// Tracks successful checkpoint re-execution by a checkpoint proposal handler.
|
|
224
|
+
const reexecutionTracker = new CheckpointReexecutionTracker();
|
|
225
|
+
if (!config.disableValidator) {
|
|
226
|
+
// Create validator client if required
|
|
227
|
+
validatorClient = await createValidatorClient(config, {
|
|
228
|
+
checkpointsBuilder: validatorCheckpointsBuilder,
|
|
229
|
+
worldState: worldStateSynchronizer,
|
|
230
|
+
p2pClient,
|
|
231
|
+
telemetry,
|
|
232
|
+
dateProvider,
|
|
233
|
+
epochCache,
|
|
234
|
+
blockSource: archiver,
|
|
235
|
+
l1ToL2MessageSource: archiver,
|
|
236
|
+
keyStoreManager,
|
|
237
|
+
blobClient,
|
|
238
|
+
reexecutionTracker,
|
|
239
|
+
slashingProtectionDb: deps.slashingProtectionDb
|
|
240
|
+
});
|
|
241
|
+
// If we have a validator client, register it as a source of offenses for the slasher,
|
|
242
|
+
// and have it register callbacks on the p2p client *before* we start it, otherwise messages
|
|
243
|
+
// like attestations or auths will fail.
|
|
244
|
+
if (validatorClient) {
|
|
245
|
+
watchers.push(validatorClient);
|
|
246
|
+
const vc = validatorClient;
|
|
247
|
+
const getValidatorAddresses = ()=>vc.getValidatorAddresses().map((a)=>a.toString());
|
|
248
|
+
proposalHandler = validatorClient.getProposalHandler();
|
|
249
|
+
proposalHandler.register(p2pClient, true, archiver, getValidatorAddresses);
|
|
250
|
+
if (!options.dontStartSequencer) {
|
|
251
|
+
await validatorClient.registerHandlers();
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// If there's no validator client, create a ProposalHandler to handle block and checkpoint proposals
|
|
256
|
+
// for monitoring or reexecution. Reexecution (default) allows us to follow the pending chain,
|
|
257
|
+
// while non-reexecution is used for validating the proposals and collecting their txs.
|
|
258
|
+
// Checkpoint proposals rebuild blobs if the blob client can upload blobs.
|
|
259
|
+
if (!validatorClient) {
|
|
260
|
+
const reexecute = !!config.alwaysReexecuteBlockProposals;
|
|
261
|
+
log.info(`Setting up proposal handler` + (reexecute ? ' with reexecution of proposals' : ''));
|
|
262
|
+
proposalHandler = createProposalHandler(config, {
|
|
263
|
+
checkpointsBuilder: validatorCheckpointsBuilder,
|
|
264
|
+
worldState: worldStateSynchronizer,
|
|
265
|
+
epochCache,
|
|
266
|
+
blockSource: archiver,
|
|
267
|
+
l1ToL2MessageSource: archiver,
|
|
268
|
+
p2pClient,
|
|
269
|
+
blobClient,
|
|
270
|
+
dateProvider,
|
|
271
|
+
telemetry,
|
|
272
|
+
reexecutionTracker
|
|
273
|
+
});
|
|
274
|
+
proposalHandler.register(p2pClient, reexecute, archiver);
|
|
275
|
+
}
|
|
276
|
+
// Start world state and wait for it to sync to the archiver.
|
|
277
|
+
await worldStateSynchronizer.start();
|
|
278
|
+
// Start p2p. Note that it depends on world state to be running.
|
|
279
|
+
await p2pClient.start();
|
|
280
|
+
let dataWithholdingWatcher;
|
|
281
|
+
let attestationsBlockWatcher;
|
|
282
|
+
let attestedInvalidProposalWatcher;
|
|
283
|
+
let broadcastedInvalidCheckpointProposalWatcher;
|
|
284
|
+
let checkpointEquivocationWatcher;
|
|
285
|
+
const validatorsSentinel = await createSentinel(epochCache, archiver, p2pClient, reexecutionTracker, config);
|
|
286
|
+
if (validatorsSentinel) {
|
|
287
|
+
watchers.push(validatorsSentinel);
|
|
288
|
+
}
|
|
289
|
+
if (collectOffenses) {
|
|
290
|
+
// The watcher's only evidence is the absence of gossiped txs in the local pool, so it cannot make a
|
|
291
|
+
// valid claim on a node that runs no p2p stack at all. Skipped entirely rather than gated at runtime.
|
|
292
|
+
if (config.p2pEnabled) {
|
|
293
|
+
dataWithholdingWatcher = new DataWithholdingWatcher(epochCache, archiver, p2pClient.getTxProvider(), p2pClient, reexecutionTracker, {
|
|
294
|
+
chainId: config.l1ChainId,
|
|
295
|
+
rollupAddress: config.rollupAddress
|
|
296
|
+
}, config);
|
|
297
|
+
watchers.push(dataWithholdingWatcher);
|
|
298
|
+
} else {
|
|
299
|
+
log.verbose('Skipping data-withholding watcher since p2p is disabled');
|
|
300
|
+
}
|
|
301
|
+
broadcastedInvalidCheckpointProposalWatcher = new BroadcastedInvalidCheckpointProposalWatcher(p2pClient, archiver, epochCache, config);
|
|
302
|
+
watchers.push(broadcastedInvalidCheckpointProposalWatcher);
|
|
303
|
+
// The proposal handler (validator-owned or standalone) is the source of invalid-proposal/equivocation
|
|
304
|
+
// slots, so the watcher runs on non-validator offense collectors too.
|
|
305
|
+
if (proposalHandler) {
|
|
306
|
+
attestedInvalidProposalWatcher = new AttestedInvalidProposalWatcher(p2pClient, proposalHandler, archiver, epochCache, config, {
|
|
307
|
+
log: log.createChild('attested-invalid-proposal-watcher')
|
|
308
|
+
});
|
|
309
|
+
watchers.push(attestedInvalidProposalWatcher);
|
|
310
|
+
}
|
|
311
|
+
checkpointEquivocationWatcher = new CheckpointEquivocationWatcher(archiver, epochCache, config);
|
|
312
|
+
watchers.push(checkpointEquivocationWatcher);
|
|
313
|
+
attestationsBlockWatcher = new AttestationsBlockWatcher(archiver, epochCache, config, log.getBindings());
|
|
314
|
+
watchers.push(attestationsBlockWatcher);
|
|
315
|
+
}
|
|
316
|
+
const watchersToStart = compactArray([
|
|
317
|
+
validatorsSentinel,
|
|
318
|
+
dataWithholdingWatcher,
|
|
319
|
+
attestationsBlockWatcher,
|
|
320
|
+
broadcastedInvalidCheckpointProposalWatcher,
|
|
321
|
+
attestedInvalidProposalWatcher,
|
|
322
|
+
checkpointEquivocationWatcher
|
|
323
|
+
]);
|
|
324
|
+
const startedWatchers = [];
|
|
325
|
+
const stopStartedWatchers = async ()=>{
|
|
326
|
+
for (const watcher of startedWatchers){
|
|
327
|
+
await tryStop(watcher);
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
// Start p2p-related services once the archiver has completed sync
|
|
331
|
+
void archiver.waitForInitialSync().then(async ()=>{
|
|
332
|
+
for (const watcher of watchersToStart){
|
|
333
|
+
await watcher.start();
|
|
334
|
+
startedWatchers.push(watcher);
|
|
335
|
+
}
|
|
336
|
+
log.info(`All p2p services started`);
|
|
337
|
+
}).catch((err)=>log.error('Failed to start p2p services after archiver sync', err));
|
|
338
|
+
started.push({
|
|
339
|
+
stop: stopStartedWatchers
|
|
340
|
+
});
|
|
341
|
+
// Validator enabled, create/start relevant service
|
|
342
|
+
let sequencer;
|
|
343
|
+
let automineSequencer;
|
|
344
|
+
let slasherClient;
|
|
345
|
+
// The slasher can run standalone to collect offenses for non-validators; it only writes to L1 when a
|
|
346
|
+
// proposer is elected (which requires a sequencer), so running it read-only on a non-validator is safe.
|
|
347
|
+
if (collectOffenses) {
|
|
348
|
+
const validatorAddresses = keyStoreManager ? NodeKeystoreAdapter.fromKeyStoreManager(keyStoreManager).getAddresses() : [];
|
|
349
|
+
slasherClient = await createSlasher(config, pickL1ContractAddresses(config), getPublicClient(config), watchers, dateProvider, epochCache, validatorAddresses, undefined);
|
|
350
|
+
await slasherClient.start();
|
|
351
|
+
started.push(slasherClient);
|
|
352
|
+
}
|
|
353
|
+
if (!config.disableValidator && validatorClient) {
|
|
354
|
+
const l1TxUtils = config.sequencerPublisherForwarderAddress ? await createForwarderL1TxUtilsFromSigners(publicClient, keyStoreManager.createAllValidatorPublisherSigners(), config.sequencerPublisherForwarderAddress, {
|
|
355
|
+
...config,
|
|
356
|
+
scope: 'sequencer'
|
|
357
|
+
}, {
|
|
358
|
+
telemetry,
|
|
359
|
+
logger: log.createChild('l1-tx-utils'),
|
|
360
|
+
dateProvider,
|
|
361
|
+
kzg: Blob.getViemKzgInstance()
|
|
362
|
+
}) : await createL1TxUtilsFromSigners(publicClient, keyStoreManager.createAllValidatorPublisherSigners(), {
|
|
363
|
+
...config,
|
|
364
|
+
scope: 'sequencer'
|
|
365
|
+
}, {
|
|
366
|
+
telemetry,
|
|
367
|
+
logger: log.createChild('l1-tx-utils'),
|
|
368
|
+
dateProvider,
|
|
369
|
+
kzg: Blob.getViemKzgInstance()
|
|
370
|
+
});
|
|
371
|
+
// Create a funder L1TxUtils from the keystore funding account (if configured)
|
|
372
|
+
const fundingSigner = keyStoreManager?.createFundingSigner();
|
|
373
|
+
let funderL1TxUtils;
|
|
374
|
+
if (fundingSigner) {
|
|
375
|
+
const [funder] = await createL1TxUtilsFromSigners(publicClient, [
|
|
376
|
+
fundingSigner
|
|
377
|
+
], {
|
|
378
|
+
...config,
|
|
379
|
+
scope: 'sequencer'
|
|
380
|
+
}, {
|
|
381
|
+
telemetry,
|
|
382
|
+
logger: log.createChild('l1-tx-utils:funder'),
|
|
383
|
+
dateProvider
|
|
384
|
+
});
|
|
385
|
+
funderL1TxUtils = funder;
|
|
386
|
+
}
|
|
387
|
+
// Create and start the sequencer client
|
|
388
|
+
const checkpointsBuilder = new CheckpointsBuilder({
|
|
389
|
+
...config,
|
|
390
|
+
l1GenesisTime,
|
|
391
|
+
slotDuration: Number(slotDuration),
|
|
392
|
+
rollupManaLimit
|
|
393
|
+
}, worldStateSynchronizer, archiver, dateProvider, avmSimulator, telemetry, debugLogStore);
|
|
394
|
+
if (config.useAutomineSequencer) {
|
|
395
|
+
// Test-only path: deterministic, queue-driven sequencer for non-block-building e2e tests.
|
|
396
|
+
// See `AUTOMINE_E2E_OPTS` in `end-to-end/src/fixtures/fixtures.ts`.
|
|
397
|
+
automineSequencer = await createAutomineSequencer({
|
|
398
|
+
config,
|
|
399
|
+
l1TxUtils,
|
|
400
|
+
funderL1TxUtils,
|
|
401
|
+
publicClient,
|
|
402
|
+
rollupContract,
|
|
403
|
+
epochCache,
|
|
404
|
+
blobClient,
|
|
405
|
+
telemetry,
|
|
406
|
+
dateProvider,
|
|
407
|
+
keyStoreManager: keyStoreManager,
|
|
408
|
+
validatorClient,
|
|
409
|
+
checkpointsBuilder,
|
|
410
|
+
globalVariableBuilder,
|
|
411
|
+
worldStateSynchronizer,
|
|
412
|
+
archiver,
|
|
413
|
+
p2pClient,
|
|
414
|
+
l1Constants: {
|
|
415
|
+
l1GenesisTime,
|
|
416
|
+
slotDuration: Number(slotDuration),
|
|
417
|
+
ethereumSlotDuration: config.ethereumSlotDuration,
|
|
418
|
+
rollupManaLimit
|
|
419
|
+
},
|
|
420
|
+
autoSettle: config.automineEnableProveEpoch,
|
|
421
|
+
log
|
|
422
|
+
});
|
|
423
|
+
} else {
|
|
424
|
+
sequencer = await SequencerClient.new(config, {
|
|
425
|
+
...deps,
|
|
426
|
+
epochCache,
|
|
427
|
+
l1TxUtils,
|
|
428
|
+
funderL1TxUtils,
|
|
429
|
+
validatorClient,
|
|
430
|
+
p2pClient,
|
|
431
|
+
worldStateSynchronizer,
|
|
432
|
+
slasherClient,
|
|
433
|
+
checkpointsBuilder,
|
|
434
|
+
l2BlockSource: archiver,
|
|
435
|
+
l1ToL2MessageSource: archiver,
|
|
436
|
+
telemetry,
|
|
437
|
+
dateProvider,
|
|
438
|
+
blobClient,
|
|
439
|
+
nodeKeyStore: keyStoreManager,
|
|
440
|
+
globalVariableBuilder
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
if (!options.dontStartSequencer && sequencer) {
|
|
445
|
+
await sequencer.start();
|
|
446
|
+
started.push(sequencer);
|
|
447
|
+
log.verbose(`Sequencer started`);
|
|
448
|
+
} else if (sequencer) {
|
|
449
|
+
log.warn(`Sequencer created but not started`);
|
|
450
|
+
}
|
|
451
|
+
if (!options.dontStartSequencer && automineSequencer) {
|
|
452
|
+
await automineSequencer.start();
|
|
453
|
+
started.push({
|
|
454
|
+
stop: ()=>automineSequencer.stop()
|
|
455
|
+
});
|
|
456
|
+
log.verbose(`AutomineSequencer started`);
|
|
457
|
+
} else if (automineSequencer) {
|
|
458
|
+
log.warn(`AutomineSequencer created but not started`);
|
|
459
|
+
}
|
|
460
|
+
// Create prover node subsystem if enabled
|
|
461
|
+
let proverNode;
|
|
462
|
+
if (config.enableProverNode) {
|
|
463
|
+
proverNode = await createProverNode(config, {
|
|
464
|
+
...deps.proverNodeDeps,
|
|
465
|
+
telemetry,
|
|
466
|
+
dateProvider,
|
|
467
|
+
archiver,
|
|
468
|
+
worldStateSynchronizer,
|
|
469
|
+
p2pClient,
|
|
470
|
+
epochCache,
|
|
471
|
+
blobClient,
|
|
472
|
+
keyStoreManager,
|
|
473
|
+
avmSimulator
|
|
474
|
+
});
|
|
475
|
+
if (!options.dontStartProverNode) {
|
|
476
|
+
await proverNode.start();
|
|
477
|
+
started.push(proverNode);
|
|
478
|
+
log.info(`Prover node subsystem started`);
|
|
479
|
+
} else {
|
|
480
|
+
log.info(`Prover node subsystem created but not started`);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
const node = new AztecNodeService({
|
|
484
|
+
config,
|
|
485
|
+
p2pClient,
|
|
486
|
+
blockSource: archiver,
|
|
487
|
+
logsSource: archiver,
|
|
488
|
+
contractDataSource: archiver,
|
|
489
|
+
l1ToL2MessageSource: archiver,
|
|
490
|
+
worldStateSynchronizer,
|
|
491
|
+
sequencer,
|
|
492
|
+
proverNode,
|
|
493
|
+
slasherClient,
|
|
494
|
+
validatorsSentinel,
|
|
495
|
+
stopStartedWatchers,
|
|
496
|
+
l1ChainId: ethereumChain.chainInfo.id,
|
|
497
|
+
version: config.rollupVersion,
|
|
498
|
+
globalVariableBuilder,
|
|
499
|
+
rollupContract,
|
|
500
|
+
feeProvider,
|
|
501
|
+
epochCache,
|
|
502
|
+
packageVersion,
|
|
503
|
+
peerProofVerifier,
|
|
504
|
+
rpcProofVerifier,
|
|
505
|
+
telemetry,
|
|
506
|
+
log,
|
|
507
|
+
blobClient,
|
|
508
|
+
validatorClient,
|
|
509
|
+
keyStoreManager,
|
|
510
|
+
debugLogStore,
|
|
511
|
+
automineSequencer,
|
|
512
|
+
avmSimulator
|
|
513
|
+
});
|
|
514
|
+
return node;
|
|
515
|
+
} catch (err) {
|
|
516
|
+
log.error('Failed during node creation, stopping started resources', err);
|
|
517
|
+
for (const resource of started.reverse()){
|
|
518
|
+
await tryStop(resource);
|
|
519
|
+
}
|
|
520
|
+
throw err;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Verifies the node's configured L1 timing matches the rollup contract it is pointed at, for the fields the
|
|
525
|
+
* node's own config carries. Each comparison is guarded against an undefined config value, so a config that
|
|
526
|
+
* does not carry a field is not checked. Throws a single error listing every mismatch. Runs in the shared
|
|
527
|
+
* startup path for every node role.
|
|
528
|
+
*/ function checkConfigMatchesRollup(config, rollup) {
|
|
529
|
+
const mismatches = [];
|
|
530
|
+
if (config.aztecSlotDuration !== undefined && config.aztecSlotDuration !== rollup.slotDuration) {
|
|
531
|
+
mismatches.push(`aztecSlotDuration is ${config.aztecSlotDuration} but the rollup reports ${rollup.slotDuration}`);
|
|
532
|
+
}
|
|
533
|
+
if (config.aztecEpochDuration !== undefined && config.aztecEpochDuration !== rollup.epochDuration) {
|
|
534
|
+
mismatches.push(`aztecEpochDuration is ${config.aztecEpochDuration} but the rollup reports ${rollup.epochDuration}`);
|
|
535
|
+
}
|
|
536
|
+
if (mismatches.length > 0) {
|
|
537
|
+
throw new Error(`The node's configured L1 timing does not match the rollup contract it is pointed at: ${mismatches.join('; ')}`);
|
|
538
|
+
}
|
|
539
|
+
}
|
package/dest/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export * from './aztec-node/config.js';
|
|
2
|
+
export * from './aztec-node/register_node_rpc_handlers.js';
|
|
3
|
+
export * from './aztec-node/server.js';
|
|
4
|
+
export * from './factory.js';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsNENBQTRDLENBQUM7QUFDM0QsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxjQUFjLGNBQWMsQ0FBQyJ9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,4CAA4C,CAAC;AAC3D,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC"}
|
package/dest/index.js
ADDED