diff --git a/CHANGELOG.md b/CHANGELOG.md index 496312b0c..c28612f40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,14 +33,13 @@ - [BREAKING] Modified `TransactionHeader` serialization to allow converting back into the native type after serialization ([#1759](https://github.com/0xMiden/node/issues/1759)). - Removed `chain_tip` requirement from mempool subscription request ([#1771](https://github.com/0xMiden/node/pull/1771)). - Moved bootstrap procedure to `miden-node validator bootstrap` command ([#1764](https://github.com/0xMiden/node/pull/1764)). +- [BREAKING] Removed `bundled` command; each component is now started as a separate process. Added `ntx-builder` CLI subcommand. Added `docker-compose.yml` for local multi-process deployment ([#1765](https://github.com/0xMiden/node/pull/1765)). - NTX Builder now deactivates network accounts which crash repeatedly (configurable via `--ntx-builder.max-account-crashes`, default 10) ([#1712](https://github.com/0xMiden/miden-node/pull/1712)). ### Fixes - Fixed network monitor looping on stale wallet nonce after node restarts by re-syncing wallet state from RPC after repeated failures ([#1748](https://github.com/0xMiden/node/pull/1748)). -- Fixed `bundled start` panicking due to duplicate `data_directory` clap argument name between `BundledCommand::Start` and `NtxBuilderConfig` ([#1732](https://github.com/0xMiden/node/pull/1732)). -- Fixed `bundled bootstrap` requiring `--validator.key.hex` or `--validator.key.kms-id` despite a default key being configured ([#1732](https://github.com/0xMiden/node/pull/1732)). - Fixed incorrectly classifying private notes with the network attachment as network notes ([#1378](https://github.com/0xMiden/node/pull/1738)). - Fixed accept header version negotiation rejecting all pre-release versions; pre-release label matching is now lenient, accepting any numeric suffix within the same label (e.g. `alpha.3` accepts `alpha.1`) ([#1755](https://github.com/0xMiden/node/pull/1755)). diff --git a/Makefile b/Makefile index 33ab72a88..9127ce631 100644 --- a/Makefile +++ b/Makefile @@ -127,6 +127,24 @@ install-network-monitor: ## Installs network monitor binary # --- docker -------------------------------------------------------------------------------------- +.PHONY: compose-genesis +compose-genesis: ## Wipes node volumes and creates a fresh genesis block + $(CONTAINER_RUNTIME) compose down --volumes --remove-orphans + $(CONTAINER_RUNTIME) volume rm -f miden-node_genesis-data miden-node_store-data miden-node_validator-data miden-node_ntx-builder-data miden-node_accounts + $(CONTAINER_RUNTIME) compose --profile genesis run --rm genesis + +.PHONY: compose-up +compose-up: ## Starts all node components via docker compose + $(CONTAINER_RUNTIME) compose up -d + +.PHONY: compose-down +compose-down: ## Stops and removes all node containers via docker compose + $(CONTAINER_RUNTIME) compose down + +.PHONY: compose-logs +compose-logs: ## Follows logs for all node components via docker compose + $(CONTAINER_RUNTIME) compose logs -f + .PHONY: docker-build-node docker-build-node: ## Builds the Miden node using Docker (override with CONTAINER_RUNTIME=podman) @CREATED=$$(date) && \ diff --git a/bin/node/.env b/bin/node/.env index 51a04794f..51cfaa3f1 100644 --- a/bin/node/.env +++ b/bin/node/.env @@ -1,8 +1,7 @@ # For more info use -h on the relevant commands: -# miden-node bundled start -h +# miden-node start -h MIDEN_NODE_BLOCK_PRODUCER_URL= MIDEN_NODE_VALIDATOR_URL= -MIDEN_NODE_NTX_BUILDER_URL= MIDEN_NODE_BATCH_PROVER_URL= MIDEN_NODE_BLOCK_PROVER_URL= MIDEN_NODE_NTX_PROVER_URL= diff --git a/bin/node/Dockerfile b/bin/node/Dockerfile index bf41b46d3..e6f387b3e 100644 --- a/bin/node/Dockerfile +++ b/bin/node/Dockerfile @@ -28,7 +28,7 @@ COPY . . RUN cargo build --release --locked --bin miden-node # Base line runtime image with runtime dependencies installed. -FROM debian:bullseye-slim AS runtime-base +FROM debian:bookworm-slim AS runtime-base RUN apt-get update && \ apt-get -y upgrade && \ apt-get install -y --no-install-recommends sqlite3 \ diff --git a/bin/node/src/commands/mod.rs b/bin/node/src/commands/mod.rs index a1b6f8be5..0112c8890 100644 --- a/bin/node/src/commands/mod.rs +++ b/bin/node/src/commands/mod.rs @@ -1,9 +1,6 @@ -use std::net::SocketAddr; use std::num::NonZeroUsize; -use std::path::{Path, PathBuf}; use std::time::Duration; -use anyhow::Context; use miden_node_block_producer::{ DEFAULT_BATCH_INTERVAL, DEFAULT_BLOCK_INTERVAL, @@ -14,11 +11,10 @@ use miden_node_utils::clap::duration_to_human_readable_string; use miden_node_validator::ValidatorSigner; use miden_protocol::crypto::dsa::ecdsa_k256_keccak::SecretKey; use miden_protocol::utils::Deserializable; -use tokio::net::TcpListener; use url::Url; pub mod block_producer; -pub mod bundled; +pub mod ntx_builder; pub mod rpc; pub mod store; pub mod validator; @@ -98,137 +94,6 @@ impl ValidatorKey { } } -/// Configuration for the Validator component when run in the bundled mode. -#[derive(clap::Args)] -pub struct BundledValidatorConfig { - /// Insecure, hex-encoded validator secret key for development and testing purposes. - /// Only used when the Validator URL argument is not set. - #[arg( - long = "validator.key", - env = ENV_VALIDATOR_KEY, - value_name = "VALIDATOR_KEY", - default_value = INSECURE_VALIDATOR_KEY_HEX - )] - validator_key: String, - - /// The remote Validator's gRPC URL. If unset, will default to running a Validator - /// in-process. If set, the insecure key argument is ignored. - #[arg(long = "validator.url", env = ENV_VALIDATOR_URL, value_name = "URL")] - validator_url: Option, -} - -impl BundledValidatorConfig { - /// Converts the [`BundledValidatorConfig`] into a URL and an optional [`SocketAddr`]. - /// - /// If the `validator_url` is set, it returns the URL and `None` for the [`SocketAddr`]. - /// - /// If `validator_url` is not set, it binds to a random port on localhost, creates a URL, - /// and returns the URL and the bound [`SocketAddr`]. - async fn to_addresses(&self) -> anyhow::Result<(Url, Option)> { - if let Some(url) = &self.validator_url { - Ok((url.clone(), None)) - } else { - let socket_addr = TcpListener::bind("127.0.0.1:0") - .await - .context("Failed to bind to validator gRPC endpoint")? - .local_addr() - .context("Failed to retrieve the validator's gRPC address")?; - let url = Url::parse(&format!("http://{socket_addr}")) - .context("Failed to parse Validator URL")?; - Ok((url, Some(socket_addr))) - } - } -} - -/// Configuration for the Network Transaction Builder component. -#[derive(clap::Args)] -pub struct NtxBuilderConfig { - /// Disable spawning the network transaction builder. - #[arg(long = "no-ntx-builder", default_value_t = false)] - pub disabled: bool, - - /// The remote transaction prover's gRPC url, used for the ntx builder. If unset, - /// will default to running a prover in-process which is expensive. - #[arg(long = "tx-prover.url", env = ENV_NTX_PROVER_URL, value_name = "URL")] - pub tx_prover_url: Option, - - /// Interval at which to run the network transaction builder's ticker. - #[arg( - long = "ntx-builder.interval", - default_value = &duration_to_human_readable_string(DEFAULT_NTX_TICKER_INTERVAL), - value_parser = humantime::parse_duration, - value_name = "DURATION" - )] - pub ticker_interval: Duration, - - /// Number of note scripts to cache locally. - /// - /// Note scripts not in cache must first be retrieved from the store. - #[arg( - long = "ntx-builder.script-cache-size", - env = ENV_NTX_SCRIPT_CACHE_SIZE, - value_name = "NUM", - default_value_t = DEFAULT_NTX_SCRIPT_CACHE_SIZE - )] - pub script_cache_size: NonZeroUsize, - - /// Duration after which an idle network account will deactivate. - /// - /// An account is considered idle once it has no viable notes to consume. - /// A deactivated account will reactivate if targeted with new notes. - #[arg( - long = "ntx-builder.idle-timeout", - default_value = &duration_to_human_readable_string(DEFAULT_NTX_IDLE_TIMEOUT), - value_parser = humantime::parse_duration, - value_name = "DURATION" - )] - pub idle_timeout: Duration, - - /// Maximum number of crashes before an account deactivated. - /// - /// Once this limit is reached, no new transactions will be created for this account. - #[arg( - long = "ntx-builder.max-account-crashes", - default_value_t = 10, - value_name = "NUM" - )] - pub max_account_crashes: usize, - - /// Directory for the ntx-builder's persistent database. - /// - /// If not set, defaults to the node's data directory. - #[arg(long = "ntx-builder.data-directory", env = ENV_NTX_DATA_DIRECTORY, value_name = "DIR")] - pub ntx_data_directory: Option, -} - -impl NtxBuilderConfig { - /// Converts this CLI config into the ntx-builder's internal config. - /// - /// The `node_data_directory` is used as the default location for the ntx-builder's database - /// if `--ntx-builder.data-directory` is not explicitly set. - pub fn into_builder_config( - self, - store_url: Url, - block_producer_url: Url, - validator_url: Url, - node_data_directory: &Path, - ) -> miden_node_ntx_builder::NtxBuilderConfig { - let data_dir = self.ntx_data_directory.unwrap_or_else(|| node_data_directory.to_path_buf()); - let database_filepath = data_dir.join("ntx-builder.sqlite3"); - - miden_node_ntx_builder::NtxBuilderConfig::new( - store_url, - block_producer_url, - validator_url, - database_filepath, - ) - .with_tx_prover_url(self.tx_prover_url) - .with_script_cache_size(self.script_cache_size) - .with_idle_timeout(self.idle_timeout) - .with_max_account_crashes(self.max_account_crashes) - } -} - /// Configuration for the Block Producer component #[derive(clap::Args)] pub struct BlockProducerConfig { diff --git a/bin/node/src/commands/ntx_builder.rs b/bin/node/src/commands/ntx_builder.rs new file mode 100644 index 000000000..0e92cc653 --- /dev/null +++ b/bin/node/src/commands/ntx_builder.rs @@ -0,0 +1,135 @@ +use std::num::NonZeroUsize; +use std::path::PathBuf; +use std::time::Duration; + +use anyhow::Context; +use miden_node_utils::clap::duration_to_human_readable_string; +use url::Url; + +use super::{ + DEFAULT_NTX_IDLE_TIMEOUT, + DEFAULT_NTX_SCRIPT_CACHE_SIZE, + DEFAULT_NTX_TICKER_INTERVAL, + ENV_BLOCK_PRODUCER_URL, + ENV_ENABLE_OTEL, + ENV_NTX_DATA_DIRECTORY, + ENV_NTX_PROVER_URL, + ENV_NTX_SCRIPT_CACHE_SIZE, + ENV_STORE_NTX_BUILDER_URL, + ENV_VALIDATOR_URL, +}; + +#[derive(clap::Subcommand)] +pub enum NtxBuilderCommand { + /// Starts the network transaction builder component. + Start { + /// The store's ntx-builder service gRPC url. + #[arg(long = "store.url", env = ENV_STORE_NTX_BUILDER_URL, value_name = "URL")] + store_url: Url, + + /// The block-producer's gRPC url. + #[arg(long = "block-producer.url", env = ENV_BLOCK_PRODUCER_URL, value_name = "URL")] + block_producer_url: Url, + + /// The validator's gRPC url. + #[arg(long = "validator.url", env = ENV_VALIDATOR_URL, value_name = "URL")] + validator_url: Url, + + /// The remote transaction prover's gRPC url. If unset, will default to running a + /// prover in-process which is expensive. + #[arg(long = "tx-prover.url", env = ENV_NTX_PROVER_URL, value_name = "URL")] + tx_prover_url: Option, + + /// Interval at which to run the network transaction builder's ticker. + #[arg( + long = "interval", + default_value = &duration_to_human_readable_string(DEFAULT_NTX_TICKER_INTERVAL), + value_parser = humantime::parse_duration, + value_name = "DURATION" + )] + ticker_interval: Duration, + + /// Number of note scripts to cache locally. + /// + /// Note scripts not in cache must first be retrieved from the store. + #[arg( + long = "script-cache-size", + env = ENV_NTX_SCRIPT_CACHE_SIZE, + value_name = "NUM", + default_value_t = DEFAULT_NTX_SCRIPT_CACHE_SIZE + )] + script_cache_size: NonZeroUsize, + + /// Duration after which an idle network account will deactivate. + /// + /// An account is considered idle once it has no viable notes to consume. + /// A deactivated account will reactivate if targeted with new notes. + #[arg( + long = "idle-timeout", + default_value = &duration_to_human_readable_string(DEFAULT_NTX_IDLE_TIMEOUT), + value_parser = humantime::parse_duration, + value_name = "DURATION" + )] + idle_timeout: Duration, + + /// Maximum number of crashes before an account deactivated. + /// + /// Once this limit is reached, no new transactions will be created for this account. + #[arg(long = "max-account-crashes", default_value_t = 10, value_name = "NUM")] + max_account_crashes: usize, + + /// Directory for the ntx-builder's persistent database. + #[arg(long = "data-directory", env = ENV_NTX_DATA_DIRECTORY, value_name = "DIR")] + data_directory: PathBuf, + + /// Enables the exporting of traces for OpenTelemetry. + /// + /// This can be further configured using environment variables as defined in the official + /// OpenTelemetry documentation. See our operator manual for further details. + #[arg(long = "enable-otel", default_value_t = false, env = ENV_ENABLE_OTEL, value_name = "BOOL")] + enable_otel: bool, + }, +} + +impl NtxBuilderCommand { + pub async fn handle(self) -> anyhow::Result<()> { + let Self::Start { + store_url, + block_producer_url, + validator_url, + tx_prover_url, + ticker_interval: _, + script_cache_size, + idle_timeout, + max_account_crashes, + data_directory, + enable_otel: _, + } = self; + + let database_filepath = data_directory.join("ntx-builder.sqlite3"); + + let config = miden_node_ntx_builder::NtxBuilderConfig::new( + store_url, + block_producer_url, + validator_url, + database_filepath, + ) + .with_tx_prover_url(tx_prover_url) + .with_script_cache_size(script_cache_size) + .with_idle_timeout(idle_timeout) + .with_max_account_crashes(max_account_crashes); + + config + .build() + .await + .context("failed to initialize ntx builder")? + .run() + .await + .context("failed while running ntx builder component") + } + + pub fn is_open_telemetry_enabled(&self) -> bool { + let Self::Start { enable_otel, .. } = self; + *enable_otel + } +} diff --git a/bin/node/src/commands/validator.rs b/bin/node/src/commands/validator.rs index 006857889..01bb9ea6f 100644 --- a/bin/node/src/commands/validator.rs +++ b/bin/node/src/commands/validator.rs @@ -164,9 +164,7 @@ impl ValidatorCommand { /// Bootstraps the genesis block: creates accounts, signs the block, and writes artifacts to /// disk. - /// - /// This is extracted as a free function so it can be reused by the bundled bootstrap command. - pub async fn bootstrap_genesis( + async fn bootstrap_genesis( genesis_block_directory: &Path, accounts_directory: &Path, genesis_config: Option<&PathBuf>, diff --git a/bin/node/src/main.rs b/bin/node/src/main.rs index 72582382b..93789b97e 100644 --- a/bin/node/src/main.rs +++ b/bin/node/src/main.rs @@ -33,15 +33,13 @@ pub enum Command { #[command(subcommand)] BlockProducer(commands::block_producer::BlockProducerCommand), - // Commands related to the node's validator component. + /// Commands related to the node's validator component. #[command(subcommand)] Validator(commands::validator::ValidatorCommand), - /// Commands relevant to running all components in the same process. - /// - /// This is the recommended way to run the node at the moment. + /// Commands related to the node's network transaction builder component. #[command(subcommand)] - Bundled(Box), + NtxBuilder(commands::ntx_builder::NtxBuilderCommand), } impl Command { @@ -54,7 +52,7 @@ impl Command { Command::Rpc(subcommand) => subcommand.is_open_telemetry_enabled(), Command::BlockProducer(subcommand) => subcommand.is_open_telemetry_enabled(), Command::Validator(subcommand) => subcommand.is_open_telemetry_enabled(), - Command::Bundled(subcommand) => subcommand.is_open_telemetry_enabled(), + Command::NtxBuilder(subcommand) => subcommand.is_open_telemetry_enabled(), } { OpenTelemetry::Enabled } else { @@ -68,7 +66,7 @@ impl Command { Command::Store(store_command) => store_command.handle().await, Command::BlockProducer(block_producer_command) => block_producer_command.handle().await, Command::Validator(validator) => validator.handle().await, - Command::Bundled(node) => node.handle().await, + Command::NtxBuilder(ntx_builder) => ntx_builder.handle().await, } } } diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..4ce7aa520 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,108 @@ +services: + genesis: + image: miden-node-image + pull_policy: if_not_present + profiles: + - genesis + volumes: + - genesis-data:/genesis + - store-data:/store + - accounts:/accounts + entrypoint: ["/bin/sh", "-c"] + command: + - | + set -e + echo "Bootstrapping validator (creating genesis block)..." + miden-node validator bootstrap \ + --genesis-block-directory /genesis \ + --accounts-directory /accounts + echo "Bootstrapping store..." + miden-node store bootstrap \ + --data-directory /store \ + --genesis-block /genesis/genesis.dat + + store: + image: miden-node-image + pull_policy: if_not_present + volumes: + - store-data:/data + command: + - miden-node + - store + - start + - --rpc.url=http://0.0.0.0:50001 + - --ntx-builder.url=http://0.0.0.0:50002 + - --block-producer.url=http://0.0.0.0:50003 + - --data-directory=/data + - --account_tree.rocksdb.max_cache_size=4294967296 + - --account_tree.rocksdb.max_open_fds=512 + - --nullifier_tree.rocksdb.max_cache_size=4294967296 + - --nullifier_tree.rocksdb.max_open_fds=512 + ports: + - "50001:50001" + - "50002:50002" + - "50003:50003" + + validator: + image: miden-node-image + pull_policy: if_not_present + volumes: + - validator-data:/data + environment: + - MIDEN_NODE_ENABLE_OTEL=false + command: + - miden-node + - validator + - start + - http://0.0.0.0:50101 + - --data-directory=/data + ports: + - "50101:50101" + + block-producer: + image: miden-node-image + pull_policy: if_not_present + command: + - miden-node + - block-producer + - start + - http://0.0.0.0:50201 + - --store.url=http://store:50003 + - --validator.url=http://validator:50101 + ports: + - "50201:50201" + + rpc: + image: miden-node-image + pull_policy: if_not_present + command: + - miden-node + - rpc + - start + - --url=http://0.0.0.0:57291 + - --store.url=http://store:50001 + - --block-producer.url=http://block-producer:50201 + - --validator.url=http://validator:50101 + ports: + - "57291:57291" + + ntx-builder: + image: miden-node-image + pull_policy: if_not_present + volumes: + - ntx-builder-data:/data + command: + - miden-node + - ntx-builder + - start + - --store.url=http://store:50002 + - --block-producer.url=http://block-producer:50201 + - --validator.url=http://validator:50101 + - --data-directory=/data + +volumes: + genesis-data: + store-data: + validator-data: + ntx-builder-data: + accounts: diff --git a/docs/external/src/operator/monitoring.md b/docs/external/src/operator/monitoring.md index 9e3ba945c..fe28c54ff 100644 --- a/docs/external/src/operator/monitoring.md +++ b/docs/external/src/operator/monitoring.md @@ -118,7 +118,7 @@ The available log levels are `trace`, `debug`, `info` (default), `warn`, `error` export RUST_LOG=debug ``` -The verbosity can also be specified by component (when running them as a single process): +The verbosity can also be specified by component: ```sh export RUST_LOG=warn,block-producer=debug,rpc=error @@ -129,10 +129,12 @@ The above would set the general level to `warn`, and the `block-producer` and `r ## Configuration -The OpenTelemetry trace exporter is enabled by adding the `--enable-otel` flag to the node's start command: +The OpenTelemetry trace exporter is enabled by adding the `--enable-otel` flag to each component's start command: ```sh -miden-node bundled start --enable-otel +miden-node store start --enable-otel +miden-node block-producer start --enable-otel +miden-node rpc start --enable-otel ``` The exporter can be configured using environment variables as specified in the official @@ -153,7 +155,7 @@ This is based off Honeycomb's OpenTelemetry ```sh OTEL_EXPORTER_OTLP_ENDPOINT=https://api.honeycomb.io:443 \ OTEL_EXPORTER_OTLP_HEADERS="x-honeycomb-team=your-api-key" \ -miden-node bundled start --enable-otel +miden-node store start --enable-otel ``` ### Honeycomb queries, triggers and board examples diff --git a/docs/external/src/operator/usage.md b/docs/external/src/operator/usage.md index 840bee2cc..a4c4e6809 100644 --- a/docs/external/src/operator/usage.md +++ b/docs/external/src/operator/usage.md @@ -4,10 +4,10 @@ sidebar_position: 4 # Configuration and Usage -As outlined in the [Architecture](./architecture) chapter, the node consists of several components which can be run -separately or as a single bundled process. At present, the recommended way to operate a node is in bundled mode and is -what this guide will focus on. Operating the components separately is very similar and should be relatively -straight-forward to derive from these instructions. +As outlined in the [Architecture](./architecture) chapter, the node consists of several components which are run +as separate processes. The recommended way to operate a node locally is using `docker compose`, which starts each +component in its own container and automatically bootstraps on first run. Operating the components without Docker +is also straightforward using the individual CLI subcommands. This guide focuses on basic usage. To discover more advanced options we recommend exploring the various help menus which can be accessed by appending `--help` to any of the commands. @@ -15,27 +15,19 @@ which can be accessed by appending `--help` to any of the commands. ## Bootstrapping The first step in starting a new Miden network is to initialize the genesis block data. This is a -one-off operation using the `bootstrap` command and by default the genesis block will contain a single -faucet account. +two-step process: first the validator signs and creates the genesis block, then the store initializes +its database from that block. By default the genesis block will contain a single faucet account. ```sh -# Create a folder to store the node's data. -mkdir data - -# Bootstrap the node. -# -# This creates the node's database and initializes it with the genesis data. -# -# The genesis block currently contains a single public faucet account. The -# secret for this account is stored in the `` -# file. This file is not used by the node and should instead by used wherever -# you intend to operate this faucet account. -# -# For example, you could operate a public faucet using our faucet reference -# implementation whose operation is described in a later section. -miden-node bundled bootstrap \ - --data-directory data \ - --accounts-directory . +# Step 1: Validator bootstrap — create the signed genesis block and account files. +miden-node validator bootstrap \ + --genesis-block-directory genesis-data \ + --accounts-directory accounts + +# Step 2: Store bootstrap — initialize the store database from the genesis block. +miden-node store bootstrap \ + --data-directory store-data \ + --genesis-block genesis-data/genesis.dat ``` You can also configure the account and asset data in the genesis block by passing in a toml configuration file. @@ -44,9 +36,9 @@ transactions to achieve the desired state. Any account secrets will be written t the provided `--accounts-directory` path in the process. ```sh -miden-node bundled bootstrap \ - --data-directory data \ - --accounts-directory . \ +miden-node validator bootstrap \ + --genesis-block-directory genesis-data \ + --accounts-directory accounts \ --genesis-config-file genesis.toml ``` @@ -110,18 +102,74 @@ path = "eth_faucet.mac" ## Operation -Start the node with the desired public gRPC server address. +### Using docker compose + +Build the Docker image and start the node. Bootstrap happens automatically on first run: ```sh -miden-node bundled start \ - --data-directory data \ - --rpc.url http://0.0.0.0:57291 +make docker-build-node +make compose-genesis +make compose-up +``` + +Follow logs: + +```sh +make compose-logs +``` + +Stop the node: + +```sh +make compose-down +``` + +Teardown and regenesis: + +```sh +make compose-genesis +``` + +### Running components individually + +Each component can also be started as a standalone process. For example: + +```sh +# Start the store +miden-node store start \ + --rpc.url http://0.0.0.0:50001 \ + --ntx-builder.url http://0.0.0.0:50002 \ + --block-producer.url http://0.0.0.0:50003 \ + --data-directory store-data + +# Start the validator +miden-node validator start http://0.0.0.0:50101 \ + --data-directory validator-data + +# Start the block producer +miden-node block-producer start http://0.0.0.0:50201 \ + --store.url http://127.0.0.1:50003 \ + --validator.url http://127.0.0.1:50101 + +# Start the RPC server +miden-node rpc start \ + --url http://0.0.0.0:57291 \ + --store.url http://127.0.0.1:50001 \ + --block-producer.url http://127.0.0.1:50201 \ + --validator.url http://127.0.0.1:50101 + +# Start the network transaction builder +miden-node ntx-builder start \ + --store.url http://127.0.0.1:50002 \ + --block-producer.url http://127.0.0.1:50201 \ + --validator.url http://127.0.0.1:50101 \ + --data-directory ntx-builder-data ``` ### gRPC server limits and timeouts The RPC component enforces per-request timeouts, per-IP rate limits, and global concurrency caps. Configure these -settings for bundled or standalone RPC with the following options: +settings with the following options: - `--grpc.timeout` (default `10s`): Maximum request duration before the server drops the request. - `--grpc.max_connection_age` (default `30m`): Maximum lifetime of a connection before the server closes it. @@ -153,7 +201,7 @@ are exposed as CLI flags (also available as environment variables): Compaction parallelism is set automatically to the number of available CPU cores. ```sh -miden-node bundled start \ +miden-node store start \ --data-directory data \ --rpc.url http://0.0.0.0:57291 \ --account_tree.rocksdb.max_cache_size 4294967296 \ @@ -165,7 +213,7 @@ miden-node bundled start \ ## Environment variables Most configuration options can also be configured using environment variables as an alternative to providing the values -via the command-line. This is useful for certain deployment options like `docker` or `systemd`, where they can be easier +via the command-line. This is useful for certain deployment options like `docker`, where they can be easier to define or inject instead of changing the underlying command line options. These are especially convenient where multiple different configuration profiles are used. Write the environment