diff --git a/CHANGELOG.md b/CHANGELOG.md index a0c95207b..5f6cd93f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - Added `StoreReplica` gRPC service with endpoints for streaming blocks and proofs ([#1987](https://github.com/0xMiden/node/pull/1987)). - Replaced the network monitor's JavaScript dashboard with a server-rendered Maud + HTMX frontend ([#2024](https://github.com/0xMiden/node/pull/2024)). - [BREAKING] Removed `CheckNullifiers` endpoint ([#2049](https://github.com/0xMiden/node/pull/2049)). +- [BREAKING] Replaced binding URL env vars and CLI flags with sockets ([#2054](https://github.com/0xMiden/node/pull/2054)). ## v0.14.10 (2026-05-29) diff --git a/bin/node/.env b/bin/node/.env index dbb635521..f140e70b5 100644 --- a/bin/node/.env +++ b/bin/node/.env @@ -6,7 +6,7 @@ MIDEN_NODE_ENABLE_OTEL=true MIDEN_NODE_DATA_DIRECTORY= # Block Producer -MIDEN_NODE_BLOCK_PRODUCER_URL= +MIDEN_NODE_BLOCK_PRODUCER_SOCKET= MIDEN_NODE_BLOCK_PRODUCER_STORE_URL= MIDEN_NODE_BLOCK_PRODUCER_VALIDATOR_URL= MIDEN_NODE_BLOCK_PRODUCER_MAX_TXS_PER_BATCH= @@ -15,27 +15,27 @@ MIDEN_NODE_BLOCK_PRODUCER_MEMPOOL_TX_CAPACITY= MIDEN_NODE_BLOCK_PRODUCER_BATCH_PROVER_URL= # Store -MIDEN_NODE_STORE_RPC_URL= +MIDEN_NODE_STORE_RPC_SOCKET= MIDEN_NODE_STORE_UPSTREAM_RPC_URL= -MIDEN_NODE_STORE_NTX_BUILDER_URL= -MIDEN_NODE_STORE_BLOCK_PRODUCER_URL= +MIDEN_NODE_STORE_NTX_BUILDER_SOCKET= +MIDEN_NODE_STORE_BLOCK_PRODUCER_SOCKET= MIDEN_NODE_STORE_BLOCK_PROVER_URL= # RPC -MIDEN_NODE_RPC_URL=http://0.0.0.0:57291 +MIDEN_NODE_RPC_SOCKET=0.0.0.0:57291 MIDEN_NODE_RPC_STORE_URL= MIDEN_NODE_RPC_BLOCK_PRODUCER_URL= MIDEN_NODE_RPC_VALIDATOR_URL= MIDEN_NODE_RPC_NTX_BUILDER_URL= # Validator -MIDEN_NODE_VALIDATOR_URL= +MIDEN_NODE_VALIDATOR_SOCKET= MIDEN_NODE_VALIDATOR_GENESIS_CONFIG_FILE= MIDEN_NODE_VALIDATOR_KEY= MIDEN_NODE_VALIDATOR_KMS_KEY_ID= # NTX Builder -MIDEN_NODE_NTX_BUILDER_URL= +MIDEN_NODE_NTX_BUILDER_SOCKET= MIDEN_NODE_NTX_BUILDER_STORE_URL= MIDEN_NODE_NTX_BUILDER_BLOCK_PRODUCER_URL= MIDEN_NODE_NTX_BUILDER_VALIDATOR_URL= diff --git a/bin/node/src/commands/block_producer.rs b/bin/node/src/commands/block_producer.rs index 7ca830e87..d8babd478 100644 --- a/bin/node/src/commands/block_producer.rs +++ b/bin/node/src/commands/block_producer.rs @@ -1,3 +1,4 @@ +use std::net::SocketAddr; use std::num::NonZeroUsize; use std::time::Duration; @@ -10,12 +11,11 @@ use miden_node_block_producer::{ DEFAULT_MAX_TXS_PER_BATCH, }; use miden_node_utils::clap::{GrpcOptionsInternal, duration_to_human_readable_string}; -use miden_node_utils::grpc::UrlExt; use url::Url; use super::ENV_ENABLE_OTEL; -const ENV_URL: &str = "MIDEN_NODE_BLOCK_PRODUCER_URL"; +const ENV_SOCKET: &str = "MIDEN_NODE_BLOCK_PRODUCER_SOCKET"; const ENV_STORE_URL: &str = "MIDEN_NODE_BLOCK_PRODUCER_STORE_URL"; const ENV_VALIDATOR_URL: &str = "MIDEN_NODE_BLOCK_PRODUCER_VALIDATOR_URL"; const ENV_MAX_TXS_PER_BATCH: &str = "MIDEN_NODE_BLOCK_PRODUCER_MAX_TXS_PER_BATCH"; @@ -30,9 +30,9 @@ const ENV_BATCH_PROVER_URL: &str = "MIDEN_NODE_BLOCK_PRODUCER_BATCH_PROVER_URL"; pub enum BlockProducerCommand { /// Starts the block-producer component. Start { - /// Url at which to serve the gRPC API. - #[arg(env = ENV_URL)] - url: Url, + /// Socket address at which to serve the gRPC API. + #[arg(long = "socket", env = ENV_SOCKET, value_name = "SOCKET")] + socket: SocketAddr, /// The store's block-producer service gRPC url. #[arg(long = "store.url", env = ENV_STORE_URL)] @@ -60,7 +60,7 @@ pub enum BlockProducerCommand { impl BlockProducerCommand { pub async fn handle(self) -> anyhow::Result<()> { let Self::Start { - url, + socket, store_url, validator_url, block_producer, @@ -68,8 +68,7 @@ impl BlockProducerCommand { grpc_options, } = self; - let block_producer_address = - url.to_socket().context("Failed to extract socket address from store URL")?; + let block_producer_address = socket; // Runtime validation for protocol constraints if block_producer.max_batches_per_block > miden_protocol::MAX_BATCHES_PER_BLOCK { @@ -123,7 +122,7 @@ mod tests { #[tokio::test] async fn rejects_too_large_max_batches_per_block() { let cmd = BlockProducerCommand::Start { - url: dummy_url(), + socket: "0.0.0.0:1234".parse().unwrap(), store_url: dummy_url(), validator_url: dummy_url(), block_producer: BlockProducerConfig { @@ -146,7 +145,7 @@ mod tests { #[tokio::test] async fn rejects_too_large_max_txs_per_batch() { let cmd = BlockProducerCommand::Start { - url: dummy_url(), + socket: "0.0.0.0:1234".parse().unwrap(), store_url: dummy_url(), validator_url: dummy_url(), block_producer: BlockProducerConfig { diff --git a/bin/node/src/commands/ntx_builder.rs b/bin/node/src/commands/ntx_builder.rs index f88931347..955fdfbdd 100644 --- a/bin/node/src/commands/ntx_builder.rs +++ b/bin/node/src/commands/ntx_builder.rs @@ -1,17 +1,17 @@ +use std::net::SocketAddr; 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 miden_node_utils::grpc::UrlExt; use tokio::net::TcpListener; use url::Url; use super::ENV_ENABLE_OTEL; use crate::commands::ENV_DATA_DIRECTORY; -const ENV_URL: &str = "MIDEN_NODE_NTX_BUILDER_URL"; +const ENV_SOCKET: &str = "MIDEN_NODE_NTX_BUILDER_SOCKET"; const ENV_STORE_URL: &str = "MIDEN_NODE_NTX_BUILDER_STORE_URL"; const ENV_BLOCK_PRODUCER_URL: &str = "MIDEN_NODE_NTX_BUILDER_BLOCK_PRODUCER_URL"; const ENV_VALIDATOR_URL: &str = "MIDEN_NODE_NTX_BUILDER_VALIDATOR_URL"; @@ -27,9 +27,9 @@ const DEFAULT_MAX_CYCLES: u32 = 1 << 18; pub enum NtxBuilderCommand { /// Starts the network transaction builder component. Start { - /// Url at which to serve the ntx-builder's gRPC API. - #[arg(long = "url", env = ENV_URL, value_name = "URL")] - url: Option, + /// Socket address at which to serve the ntx-builder's gRPC API. + #[arg(long = "socket", env = ENV_SOCKET, value_name = "SOCKET")] + socket: SocketAddr, /// The store's ntx-builder service gRPC url. #[arg(long = "store.url", env = ENV_STORE_URL, value_name = "URL")] @@ -105,7 +105,7 @@ pub enum NtxBuilderCommand { impl NtxBuilderCommand { pub async fn handle(self) -> anyhow::Result<()> { let Self::Start { - url, + socket, store_url, block_producer_url, validator_url, @@ -118,18 +118,9 @@ impl NtxBuilderCommand { enable_otel: _, } = self; - let listener = if let Some(url) = url { - let addr = url - .to_socket() - .context("Failed to extract socket address from ntx-builder URL")?; - Some( - TcpListener::bind(addr) - .await - .context("Failed to bind to ntx-builder's gRPC URL")?, - ) - } else { - None - }; + let listener = TcpListener::bind(socket) + .await + .context("Failed to bind to ntx-builder's gRPC socket")?; let database_filepath = data_directory.join("ntx-builder.sqlite3"); diff --git a/bin/node/src/commands/rpc.rs b/bin/node/src/commands/rpc.rs index b9c6ea7e5..9a11f5be2 100644 --- a/bin/node/src/commands/rpc.rs +++ b/bin/node/src/commands/rpc.rs @@ -1,12 +1,13 @@ +use std::net::SocketAddr; + use anyhow::Context; use miden_node_rpc::Rpc; use miden_node_utils::clap::GrpcOptionsExternal; -use miden_node_utils::grpc::UrlExt; use url::Url; use super::ENV_ENABLE_OTEL; -const ENV_URL: &str = "MIDEN_NODE_RPC_URL"; +const ENV_SOCKET: &str = "MIDEN_NODE_RPC_SOCKET"; const ENV_STORE_URL: &str = "MIDEN_NODE_RPC_STORE_URL"; const ENV_BLOCK_PRODUCER_URL: &str = "MIDEN_NODE_RPC_BLOCK_PRODUCER_URL"; const ENV_VALIDATOR_URL: &str = "MIDEN_NODE_RPC_VALIDATOR_URL"; @@ -16,9 +17,9 @@ const ENV_NTX_BUILDER_URL: &str = "MIDEN_NODE_RPC_NTX_BUILDER_URL"; pub enum RpcCommand { /// Starts the RPC component. Start { - /// Url at which to serve the gRPC API. - #[arg(long = "url", env = ENV_URL, value_name = "URL")] - url: Url, + /// Socket address at which to serve the gRPC API. + #[arg(long = "socket", env = ENV_SOCKET, value_name = "SOCKET")] + socket: SocketAddr, /// The store's RPC service gRPC url. #[arg(long = "store.url", env = ENV_STORE_URL, value_name = "URL")] @@ -52,7 +53,7 @@ pub enum RpcCommand { impl RpcCommand { pub async fn handle(self) -> anyhow::Result<()> { let Self::Start { - url, + socket, store_url, block_producer_url, validator_url, @@ -61,10 +62,9 @@ impl RpcCommand { grpc_options, } = self; - let listener = url.to_socket().context("Failed to extract socket address from RPC URL")?; - let listener = tokio::net::TcpListener::bind(listener) + let listener = tokio::net::TcpListener::bind(socket) .await - .context("Failed to bind to RPC's gRPC URL")?; + .context("Failed to bind to RPC's gRPC socket")?; Rpc { listener, diff --git a/bin/node/src/commands/store.rs b/bin/node/src/commands/store.rs index 53ce60054..3288d8122 100644 --- a/bin/node/src/commands/store.rs +++ b/bin/node/src/commands/store.rs @@ -1,3 +1,4 @@ +use std::net::SocketAddr; use std::num::NonZeroUsize; use std::path::{Path, PathBuf}; @@ -6,7 +7,6 @@ use miden_node_store::genesis::GenesisBlock; use miden_node_store::{DEFAULT_MAX_CONCURRENT_PROOFS, Store, StoreMode}; use miden_node_utils::clap::{GrpcOptionsInternal, StorageOptions}; use miden_node_utils::fs::ensure_empty_directory; -use miden_node_utils::grpc::UrlExt; use miden_protocol::block::SignedBlock; use miden_protocol::utils::serde::Deserializable; use url::Url; @@ -14,10 +14,10 @@ use url::Url; use super::ENV_ENABLE_OTEL; use crate::commands::ENV_DATA_DIRECTORY; -const ENV_URL: &str = "MIDEN_NODE_STORE_RPC_URL"; +const ENV_RPC_SOCKET: &str = "MIDEN_NODE_STORE_RPC_SOCKET"; const ENV_UPSTREAM_URL: &str = "MIDEN_NODE_STORE_UPSTREAM_RPC_URL"; -const ENV_NTX_BUILDER_URL: &str = "MIDEN_NODE_STORE_NTX_BUILDER_URL"; -const ENV_BLOCK_PRODUCER_URL: &str = "MIDEN_NODE_STORE_BLOCK_PRODUCER_URL"; +const ENV_NTX_BUILDER_SOCKET: &str = "MIDEN_NODE_STORE_NTX_BUILDER_SOCKET"; +const ENV_BLOCK_PRODUCER_SOCKET: &str = "MIDEN_NODE_STORE_BLOCK_PRODUCER_SOCKET"; const ENV_BLOCK_PROVER_URL: &str = "MIDEN_NODE_STORE_BLOCK_PROVER_URL"; #[derive(clap::Subcommand)] @@ -39,17 +39,17 @@ pub enum StoreCommand { /// In this mode the store accepts blocks from a block producer via a dedicated gRPC endpoint /// and runs the proof scheduler to generate block proofs. Start { - /// Url at which to serve the store's RPC API. - #[arg(long = "rpc.url", env = ENV_URL, value_name = "URL")] - rpc_url: Url, + /// Socket address at which to serve the store's RPC API. + #[arg(long = "rpc.socket", env = ENV_RPC_SOCKET, value_name = "SOCKET")] + rpc_socket: SocketAddr, - /// Url at which to serve the store's network transaction builder API. - #[arg(long = "ntx-builder.url", env = ENV_NTX_BUILDER_URL, value_name = "URL")] - ntx_builder_url: Url, + /// Socket address at which to serve the store's network transaction builder API. + #[arg(long = "ntx-builder.socket", env = ENV_NTX_BUILDER_SOCKET, value_name = "SOCKET")] + ntx_builder_socket: SocketAddr, - /// Url at which to serve the store's block producer API. - #[arg(long = "block-producer.url", env = ENV_BLOCK_PRODUCER_URL, value_name = "URL")] - block_producer_url: Url, + /// Socket address at which to serve the store's block producer API. + #[arg(long = "block-producer.socket", env = ENV_BLOCK_PRODUCER_SOCKET, value_name = "SOCKET")] + block_producer_socket: SocketAddr, /// The remote block prover's gRPC url. If not provided, a local block prover will be used. #[arg(long = "block-prover.url", env = ENV_BLOCK_PROVER_URL, value_name = "URL")] @@ -87,9 +87,9 @@ pub enum StoreCommand { /// Only the `Rpc` and `StoreReplica` gRPC services are exposed — the `BlockProducer` and /// `NtxBuilder` services are not started and no proof scheduler runs. StartReplica { - /// Url at which to serve the store's RPC API. - #[arg(long = "rpc.url", env = ENV_URL, value_name = "URL")] - url: Url, + /// Socket address at which to serve the store's RPC API. + #[arg(long = "rpc.socket", env = ENV_RPC_SOCKET, value_name = "SOCKET")] + rpc_socket: SocketAddr, /// gRPC URL of the upstream store's `StoreReplica` endpoint to sync blocks from. #[arg(long = "upstream-store.url", env = ENV_UPSTREAM_URL, value_name = "URL")] @@ -120,9 +120,9 @@ impl StoreCommand { bootstrap_store(&data_directory, &genesis_block) }, StoreCommand::Start { - rpc_url, - ntx_builder_url, - block_producer_url, + rpc_socket, + ntx_builder_socket, + block_producer_socket, block_prover_url, data_directory, enable_otel: _, @@ -131,9 +131,9 @@ impl StoreCommand { storage_options, } => { Self::start( - rpc_url, - ntx_builder_url, - block_producer_url, + rpc_socket, + ntx_builder_socket, + block_producer_socket, block_prover_url, data_directory, grpc_options, @@ -143,7 +143,7 @@ impl StoreCommand { .await }, StoreCommand::StartReplica { - url: rpc_url, + rpc_socket, upstream_store_url, data_directory, enable_otel: _, @@ -151,7 +151,7 @@ impl StoreCommand { storage_options, } => { Self::start_replica( - rpc_url, + rpc_socket, upstream_store_url, data_directory, grpc_options, @@ -173,35 +173,26 @@ impl StoreCommand { #[expect(clippy::too_many_arguments)] async fn start( - rpc_url: Url, - ntx_builder_url: Url, - block_producer_url: Url, + rpc_socket: SocketAddr, + ntx_builder_socket: SocketAddr, + block_producer_socket: SocketAddr, block_prover_url: Option, data_directory: PathBuf, grpc_options: GrpcOptionsInternal, max_concurrent_proofs: NonZeroUsize, storage_options: StorageOptions, ) -> anyhow::Result<()> { - let rpc_listener = rpc_url - .to_socket() - .context("Failed to extract socket address from store RPC URL")?; - let rpc_listener = tokio::net::TcpListener::bind(rpc_listener) + let rpc_listener = tokio::net::TcpListener::bind(rpc_socket) .await - .context("Failed to bind to store's RPC gRPC URL")?; + .context("Failed to bind to store's RPC gRPC socket")?; - let ntx_builder_addr = ntx_builder_url - .to_socket() - .context("Failed to extract socket address from store ntx-builder URL")?; - let ntx_builder_listener = tokio::net::TcpListener::bind(ntx_builder_addr) + let ntx_builder_listener = tokio::net::TcpListener::bind(ntx_builder_socket) .await - .context("Failed to bind to store's ntx-builder gRPC URL")?; + .context("Failed to bind to store's ntx-builder gRPC socket")?; - let block_producer_addr = block_producer_url - .to_socket() - .context("Failed to extract socket address from store block-producer URL")?; - let block_producer_listener = tokio::net::TcpListener::bind(block_producer_addr) + let block_producer_listener = tokio::net::TcpListener::bind(block_producer_socket) .await - .context("Failed to bind to store's block-producer gRPC URL")?; + .context("Failed to bind to store's block-producer gRPC socket")?; Store { rpc_listener, @@ -221,18 +212,15 @@ impl StoreCommand { } async fn start_replica( - rpc_url: Url, + rpc_socket: SocketAddr, upstream_store_url: Url, data_directory: PathBuf, grpc_options: GrpcOptionsInternal, storage_options: StorageOptions, ) -> anyhow::Result<()> { - let rpc_listener = rpc_url - .to_socket() - .context("Failed to extract socket address from store RPC URL")?; - let rpc_listener = tokio::net::TcpListener::bind(rpc_listener) + let rpc_listener = tokio::net::TcpListener::bind(rpc_socket) .await - .context("Failed to bind to store's RPC gRPC URL")?; + .context("Failed to bind to store's RPC gRPC socket")?; Store { rpc_listener, diff --git a/bin/node/src/commands/validator.rs b/bin/node/src/commands/validator.rs index 807f5fa12..64d2c6837 100644 --- a/bin/node/src/commands/validator.rs +++ b/bin/node/src/commands/validator.rs @@ -5,16 +5,14 @@ use anyhow::Context; use miden_node_store::genesis::config::{AccountFileWithName, GenesisConfig}; use miden_node_utils::clap::GrpcOptionsInternal; use miden_node_utils::fs::ensure_empty_directory; -use miden_node_utils::grpc::UrlExt; use miden_node_utils::signer::BlockSigner; use miden_node_validator::{Validator, ValidatorSigner}; use miden_protocol::crypto::dsa::ecdsa_k256_keccak::SecretKey; use miden_protocol::utils::serde::{Deserializable, Serializable}; -use url::Url; use crate::commands::{ENV_DATA_DIRECTORY, ENV_ENABLE_OTEL}; -const ENV_URL: &str = "MIDEN_NODE_VALIDATOR_URL"; +const ENV_SOCKET: &str = "MIDEN_NODE_VALIDATOR_SOCKET"; const ENV_GENESIS_CONFIG_FILE: &str = "MIDEN_NODE_VALIDATOR_GENESIS_CONFIG_FILE"; const ENV_KEY: &str = "MIDEN_NODE_VALIDATOR_KEY"; const ENV_KMS_KEY_ID: &str = "MIDEN_NODE_VALIDATOR_KMS_KEY_ID"; @@ -54,9 +52,9 @@ pub enum ValidatorCommand { /// Starts the validator component. Start { - /// Url at which to serve the gRPC API. - #[arg(env = ENV_URL)] - url: Url, + /// Socket address at which to serve the gRPC API. + #[arg(long = "socket", env = ENV_SOCKET, value_name = "SOCKET")] + socket: std::net::SocketAddr, /// Enables the exporting of traces for OpenTelemetry. /// @@ -120,16 +118,14 @@ impl ValidatorCommand { .await }, Self::Start { - url, + socket, grpc_options, validator_key, data_directory, kms_key_id, .. } => { - let address = url - .to_socket() - .context("failed to extract socket address from validator URL")?; + let address = socket; // Run validator with KMS key backend if key id provided. if let Some(kms_key_id) = kms_key_id { diff --git a/crates/ntx-builder/src/builder.rs b/crates/ntx-builder/src/builder.rs index 12bc442a8..7b823f7c1 100644 --- a/crates/ntx-builder/src/builder.rs +++ b/crates/ntx-builder/src/builder.rs @@ -104,16 +104,14 @@ impl NetworkTransactionBuilder { /// - An actor encounters a fatal error /// - The account loader task fails /// - The gRPC server fails - pub async fn run(self, listener: Option) -> anyhow::Result<()> { + pub async fn run(self, listener: TcpListener) -> anyhow::Result<()> { let mut join_set = JoinSet::new(); - // Start the gRPC server if a listener is provided. - if let Some(listener) = listener { - let server = NtxBuilderRpcServer::new(self.db.clone(), self.config.max_note_attempts); - join_set.spawn(async move { - server.serve(listener).await.context("ntx-builder gRPC server failed") - }); - } + // Start the gRPC server. + let server = NtxBuilderRpcServer::new(self.db.clone(), self.config.max_note_attempts); + join_set.spawn(async move { + server.serve(listener).await.context("ntx-builder gRPC server failed") + }); join_set.spawn(self.run_event_loop()); diff --git a/docker-compose.yml b/docker-compose.yml index cd5594507..804bf7d43 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -34,9 +34,9 @@ services: - 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 + - --rpc.socket=0.0.0.0:50001 + - --ntx-builder.socket=0.0.0.0:50002 + - --block-producer.socket=0.0.0.0:50003 - --data-directory=/data/store - --account_tree.rocksdb.max_cache_size=4294967296 - --account_tree.rocksdb.max_open_fds=512 @@ -60,7 +60,7 @@ services: - miden-node - validator - start - - http://0.0.0.0:50101 + - --socket=0.0.0.0:50101 - --data-directory=/data/validator ports: - "50101:50101" @@ -76,7 +76,7 @@ services: - miden-node - block-producer - start - - http://0.0.0.0:50201 + - --socket=0.0.0.0:50201 - --store.url=http://store:50003 - --validator.url=http://validator:50101 ports: @@ -93,7 +93,7 @@ services: - miden-node - rpc - start - - --url=http://0.0.0.0:57291 + - --socket=0.0.0.0:57291 - --store.url=http://store:50001 - --block-producer.url=http://block-producer:50201 - --validator.url=http://validator:50101 @@ -113,6 +113,7 @@ services: - miden-node - ntx-builder - start + - --socket=0.0.0.0:50301 - --store.url=http://store:50002 - --block-producer.url=http://block-producer:50201 - --validator.url=http://validator:50101 diff --git a/docs/external/src/operator/usage.md b/docs/external/src/operator/usage.md index 62d05b31a..e6f4e6860 100644 --- a/docs/external/src/operator/usage.md +++ b/docs/external/src/operator/usage.md @@ -160,29 +160,30 @@ 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 \ + --rpc.socket 0.0.0.0:50001 \ + --ntx-builder.socket 0.0.0.0:50002 \ + --block-producer.socket 0.0.0.0:50003 \ --data-directory /tmp/store # Start the validator -miden-node validator start http://0.0.0.0:50101 \ +miden-node validator start --socket 0.0.0.0:50101 \ --data-directory /tmp/validator # Start the block producer -miden-node block-producer start http://0.0.0.0:50201 \ +miden-node block-producer start --socket 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 \ + --socket 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 \ + --socket 0.0.0.0:50301 \ --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 \ @@ -226,7 +227,7 @@ Compaction parallelism is set automatically to the number of available CPU cores ```sh miden-node store start \ --data-directory data \ - --rpc.url http://0.0.0.0:57291 \ + --rpc.socket 0.0.0.0:57291 \ --account_tree.rocksdb.max_cache_size 4294967296 \ --account_tree.rocksdb.max_open_fds 512 \ --nullifier_tree.rocksdb.max_cache_size 4294967296 \ diff --git a/scripts/run-node.sh b/scripts/run-node.sh index a9621917a..fc8589644 100755 --- a/scripts/run-node.sh +++ b/scripts/run-node.sh @@ -19,19 +19,20 @@ NTX_BUILDER_DIR="/tmp/ntx-builder" ACCOUNTS_DIR="/tmp/accounts" # Primary store (block-producer mode): 3 APIs. -STORE_RPC_URL="http://0.0.0.0:50001" -STORE_NTX_BUILDER_URL="http://0.0.0.0:50002" -STORE_BLOCK_PRODUCER_URL="http://0.0.0.0:50003" +STORE_RPC_PORT=50001 +STORE_NTX_BUILDER_PORT=50002 +STORE_BLOCK_PRODUCER_PORT=50003 # Replica stores expose only the RPC API (no block-producer or ntx-builder endpoints). -STORE_REPLICA_1_RPC_URL="http://0.0.0.0:50011" -STORE_REPLICA_2_RPC_URL="http://0.0.0.0:50021" +STORE_REPLICA_1_RPC_PORT=50011 +STORE_REPLICA_2_RPC_PORT=50021 -VALIDATOR_URL="http://0.0.0.0:50101" -BLOCK_PRODUCER_URL="http://0.0.0.0:50201" -RPC_URL="http://0.0.0.0:57291" -RPC_REPLICA_1_URL="http://0.0.0.0:57292" -RPC_REPLICA_2_URL="http://0.0.0.0:57293" +VALIDATOR_PORT=50101 +BLOCK_PRODUCER_PORT=50201 +NTX_BUILDER_PORT=50301 +RPC_PORT=57291 +RPC_REPLICA_1_PORT=57292 +RPC_REPLICA_2_PORT=57293 PIDS=() @@ -47,7 +48,7 @@ trap cleanup EXIT INT TERM # --- Kill processes on required ports --- -PORTS=(50001 50002 50003 50011 50021 50101 50201 57291 57292 57293) +PORTS=(50001 50002 50003 50011 50021 50101 50201 50301 57291 57292 57293) echo "=== Killing processes on required ports ===" for port in "${PORTS[@]}"; do pids=$(lsof -ti :"$port" 2>/dev/null || true) @@ -106,9 +107,9 @@ echo "=== Starting components ===" echo "Starting store (block-producer mode)..." $BINARY store start \ - --rpc.url "$STORE_RPC_URL" \ - --ntx-builder.url "$STORE_NTX_BUILDER_URL" \ - --block-producer.url "$STORE_BLOCK_PRODUCER_URL" \ + --rpc.socket "0.0.0.0:$STORE_RPC_PORT" \ + --ntx-builder.socket "0.0.0.0:$STORE_NTX_BUILDER_PORT" \ + --block-producer.socket "0.0.0.0:$STORE_BLOCK_PRODUCER_PORT" \ --data-directory "$STORE_DIR" & PIDS+=($!) @@ -118,7 +119,7 @@ if [[ -n "$KMS_KEY_ID" ]]; then fi echo "Starting validator..." -$BINARY validator start "$VALIDATOR_URL" \ +$BINARY validator start --socket "0.0.0.0:$VALIDATOR_PORT" \ --data-directory "$VALIDATOR_DIR" \ "${KMS_START_ARGS[@]+"${KMS_START_ARGS[@]}"}" & PIDS+=($!) @@ -127,60 +128,61 @@ PIDS+=($!) sleep 2 # Replica 1 syncs from the primary store. -echo "Starting store replica 1 (upstream: primary store at $STORE_RPC_URL)..." +echo "Starting store replica 1 (upstream: primary store at 127.0.0.1:$STORE_RPC_PORT)..." $BINARY store start-replica \ - --rpc.url "$STORE_REPLICA_1_RPC_URL" \ - --upstream-store.url "$STORE_RPC_URL" \ + --rpc.socket "0.0.0.0:$STORE_REPLICA_1_RPC_PORT" \ + --upstream-store.url "http://127.0.0.1:$STORE_RPC_PORT" \ --data-directory "$STORE_REPLICA_1_DIR" & PIDS+=($!) # Replica 2 syncs from replica 1, proving replicas can act as upstreams. -echo "Starting store replica 2 (upstream: replica 1 at $STORE_REPLICA_1_RPC_URL)..." +echo "Starting store replica 2 (upstream: replica 1 at 127.0.0.1:$STORE_REPLICA_1_RPC_PORT)..." $BINARY store start-replica \ - --rpc.url "$STORE_REPLICA_2_RPC_URL" \ - --upstream-store.url "$STORE_REPLICA_1_RPC_URL" \ + --rpc.socket "0.0.0.0:$STORE_REPLICA_2_RPC_PORT" \ + --upstream-store.url "http://127.0.0.1:$STORE_REPLICA_1_RPC_PORT" \ --data-directory "$STORE_REPLICA_2_DIR" & PIDS+=($!) echo "Starting block producer..." -$BINARY block-producer start "$BLOCK_PRODUCER_URL" \ - --store.url "http://127.0.0.1:50003" \ - --validator.url "http://127.0.0.1:50101" & +$BINARY block-producer start --socket "0.0.0.0:$BLOCK_PRODUCER_PORT" \ + --store.url "http://127.0.0.1:$STORE_BLOCK_PRODUCER_PORT" \ + --validator.url "http://127.0.0.1:$VALIDATOR_PORT" & PIDS+=($!) echo "Starting RPC server (primary store)..." $BINARY rpc start \ - --url "$RPC_URL" \ - --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" & + --socket "0.0.0.0:$RPC_PORT" \ + --store.url "http://127.0.0.1:$STORE_RPC_PORT" \ + --block-producer.url "http://127.0.0.1:$BLOCK_PRODUCER_PORT" \ + --validator.url "http://127.0.0.1:$VALIDATOR_PORT" & PIDS+=($!) echo "Starting RPC server (replica 1)..." $BINARY rpc start \ - --url "$RPC_REPLICA_1_URL" \ - --store.url "http://127.0.0.1:50011" \ - --block-producer.url "http://127.0.0.1:50201" \ - --validator.url "http://127.0.0.1:50101" & + --socket "0.0.0.0:$RPC_REPLICA_1_PORT" \ + --store.url "http://127.0.0.1:$STORE_REPLICA_1_RPC_PORT" \ + --block-producer.url "http://127.0.0.1:$BLOCK_PRODUCER_PORT" \ + --validator.url "http://127.0.0.1:$VALIDATOR_PORT" & PIDS+=($!) echo "Starting RPC server (replica 2)..." $BINARY rpc start \ - --url "$RPC_REPLICA_2_URL" \ - --store.url "http://127.0.0.1:50021" \ - --block-producer.url "http://127.0.0.1:50201" \ - --validator.url "http://127.0.0.1:50101" & + --socket "0.0.0.0:$RPC_REPLICA_2_PORT" \ + --store.url "http://127.0.0.1:$STORE_REPLICA_2_RPC_PORT" \ + --block-producer.url "http://127.0.0.1:$BLOCK_PRODUCER_PORT" \ + --validator.url "http://127.0.0.1:$VALIDATOR_PORT" & PIDS+=($!) echo "Starting network transaction builder..." $BINARY 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" \ + --socket "0.0.0.0:$NTX_BUILDER_PORT" \ + --store.url "http://127.0.0.1:$STORE_NTX_BUILDER_PORT" \ + --block-producer.url "http://127.0.0.1:$BLOCK_PRODUCER_PORT" \ + --validator.url "http://127.0.0.1:$VALIDATOR_PORT" \ --data-directory "$NTX_BUILDER_DIR" & PIDS+=($!) echo "=== All components running. Ctrl+C to stop. ===" -echo "=== Block propagation chain: $STORE_RPC_URL -> $STORE_REPLICA_1_RPC_URL -> $STORE_REPLICA_2_RPC_URL ===" -echo "=== RPC endpoints: $RPC_URL, $RPC_REPLICA_1_URL, $RPC_REPLICA_2_URL ===" +echo "=== Block propagation chain: :$STORE_RPC_PORT -> :$STORE_REPLICA_1_RPC_PORT -> :$STORE_REPLICA_2_RPC_PORT ===" +echo "=== RPC endpoints: :$RPC_PORT, :$RPC_REPLICA_1_PORT, :$RPC_REPLICA_2_PORT ===" wait