Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
2901d70
Basic scaffolding for validator component
sergerad Oct 14, 2025
9881d3d
server scaffolding done
sergerad Oct 15, 2025
2a728c7
Add to bundled command
sergerad Oct 15, 2025
f3d8982
Feed data path through
sergerad Oct 15, 2025
ad3f11f
Add validate block endpoint
sergerad Oct 15, 2025
9ca815b
Deserialize block
sergerad Oct 15, 2025
de81a1b
Add diesel scaffolding
sergerad Oct 15, 2025
109c9c0
submit tx e2e
sergerad Oct 15, 2025
77a5bcc
status endpoint logic
sergerad Oct 16, 2025
0fb8893
title comments
sergerad Oct 16, 2025
5a50f84
migrations
sergerad Oct 16, 2025
a7f0739
fmt
sergerad Oct 16, 2025
430da6d
Fix modules
sergerad Oct 19, 2025
7155482
Update .env
sergerad Oct 19, 2025
894ef49
Update readme
sergerad Oct 20, 2025
39ee003
Update changelog
sergerad Oct 20, 2025
20f0491
RM unnecessary todo
sergerad Oct 20, 2025
932fe89
Fix logs
sergerad Oct 20, 2025
54b9b49
Rm copy trait
sergerad Oct 21, 2025
d5811ed
Doc comments
sergerad Oct 21, 2025
05bcfec
Add placeholder validate
sergerad Oct 22, 2025
fa95081
Add validate handler logic
sergerad Oct 22, 2025
00fd163
Use new base types with signed block
sergerad Oct 29, 2025
cbd64b6
Revert "Use new base types with signed block"
sergerad Oct 29, 2025
5c8ae1a
Rm signed block refs
sergerad Oct 29, 2025
f087ff3
Update validator readme
sergerad Oct 29, 2025
dc946b8
Merge branch 'next' of github.com:0xMiden/miden-node into sergerad-va…
sergerad Oct 29, 2025
596fa34
toml
sergerad Oct 29, 2025
32619a3
machete
sergerad Oct 29, 2025
01a3a59
fmt
sergerad Oct 29, 2025
609f056
Remove db
sergerad Oct 30, 2025
5ab7d97
RM pubs
sergerad Oct 30, 2025
f9ab5d9
machete
sergerad Oct 30, 2025
dccb18a
Fix readme
sergerad Oct 30, 2025
2a5d668
Fix changelog
sergerad Oct 30, 2025
0b32719
Fix readme status
sergerad Oct 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- Added pagination to `SyncNotes` endpoint ([#1257](https://github.com/0xMiden/miden-node/pull/1257)).
- Added application level error in gRPC endpoints ([#1266](https://github.com/0xMiden/miden-node/pull/1266)).
- [BREAKING] Response type nuances of `GetAccountProof` in the public store API (#[1277](https://github.com/0xMiden/miden-node/pull/1277)).
- Add `validator` crate with initial protobuf, gRPC server, and sub-command (#[1293](https://github.com/0xMiden/miden-node/pull/1293)).
- Add optional `TransactionInputs` field to `SubmitProvenTransaction` endpoint for transaction re-execution (#[1278](https://github.com/0xMiden/miden-node/pull/1278)).

## v0.11.2 (2025-09-10)
Expand Down
17 changes: 17 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ members = [
"crates/store",
"crates/test-macro",
"crates/utils",
"crates/validator",
"proto",
]

Expand Down Expand Up @@ -44,6 +45,7 @@ miden-node-rpc = { path = "crates/rpc", version = "0.12" }
miden-node-store = { path = "crates/store", version = "0.12" }
miden-node-test-macro = { path = "crates/test-macro" }
miden-node-utils = { path = "crates/utils", version = "0.12" }
miden-node-validator = { path = "crates/validator", version = "0.12" }
miden-remote-prover-client = { path = "crates/remote-prover-client", version = "0.12" }

# miden-base aka protocol dependencies. These should be updated in sync.
Expand Down
1 change: 1 addition & 0 deletions bin/node/.env
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# For more info use -h on the relevant commands:
# miden-node bundled 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=
Expand Down
1 change: 1 addition & 0 deletions bin/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ miden-node-ntx-builder = { workspace = true }
miden-node-rpc = { workspace = true }
miden-node-store = { workspace = true }
miden-node-utils = { workspace = true }
miden-node-validator = { workspace = true }
miden-objects = { workspace = true }
tokio = { features = ["macros", "net", "rt-multi-thread"], workspace = true }
url = { workspace = true }
Expand Down
19 changes: 19 additions & 0 deletions bin/node/src/commands/bundled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use miden_node_ntx_builder::NetworkTransactionBuilder;
use miden_node_rpc::Rpc;
use miden_node_store::Store;
use miden_node_utils::grpc::UrlExt;
use miden_node_validator::Validator;
use tokio::net::TcpListener;
use tokio::sync::Barrier;
use tokio::task::JoinSet;
Expand Down Expand Up @@ -141,6 +142,12 @@ impl BundledCommand {
.local_addr()
.context("Failed to retrieve the block-producer's gRPC address")?;

let validator_address = 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")?;

// Store addresses for each exposed API
let store_rpc_listener = TcpListener::bind("127.0.0.1:0")
.await
Expand Down Expand Up @@ -213,6 +220,17 @@ impl BundledCommand {
})
.id();

let validator_id = join_set
.spawn({
async move {
Validator { address: validator_address, grpc_timeout }
.serve()
.await
.context("failed while serving validator component")
}
})
.id();

// Start RPC component.
let rpc_id = join_set
.spawn(async move {
Expand All @@ -236,6 +254,7 @@ impl BundledCommand {
let mut component_ids = HashMap::from([
(store_id, "store"),
(block_producer_id, "block-producer"),
(validator_id, "validator"),
(rpc_id, "rpc"),
]);

Expand Down
2 changes: 2 additions & 0 deletions bin/node/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ pub mod block_producer;
pub mod bundled;
pub mod rpc;
pub mod store;
pub mod validator;

const ENV_BLOCK_PRODUCER_URL: &str = "MIDEN_NODE_BLOCK_PRODUCER_URL";
const ENV_VALIDATOR_URL: &str = "MIDEN_NODE_VALIDATOR_URL";
const ENV_BATCH_PROVER_URL: &str = "MIDEN_NODE_BATCH_PROVER_URL";
const ENV_BLOCK_PROVER_URL: &str = "MIDEN_NODE_BLOCK_PROVER_URL";
const ENV_NTX_PROVER_URL: &str = "MIDEN_NODE_NTX_PROVER_URL";
Expand Down
58 changes: 58 additions & 0 deletions bin/node/src/commands/validator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use std::time::Duration;

use anyhow::Context;
use miden_node_utils::grpc::UrlExt;
use miden_node_validator::Validator;
use url::Url;

use crate::commands::{
DEFAULT_TIMEOUT,
ENV_ENABLE_OTEL,
ENV_VALIDATOR_URL,
duration_to_human_readable_string,
};

#[derive(clap::Subcommand)]
pub enum ValidatorCommand {
/// Starts the validator component.
Start {
/// Url at which to serve the gRPC API.
#[arg(env = ENV_VALIDATOR_URL)]
url: Url,

/// 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 = true, env = ENV_ENABLE_OTEL, value_name = "BOOL")]
enable_otel: bool,

/// Maximum duration a gRPC request is allocated before being dropped by the server.
#[arg(
long = "grpc.timeout",
default_value = &duration_to_human_readable_string(DEFAULT_TIMEOUT),
value_parser = humantime::parse_duration,
value_name = "DURATION"
)]
grpc_timeout: Duration,
},
}

impl ValidatorCommand {
pub async fn handle(self) -> anyhow::Result<()> {
let Self::Start { url, grpc_timeout, .. } = self;

let address =
url.to_socket().context("Failed to extract socket address from validator URL")?;

Validator { address, grpc_timeout }
.serve()
.await
.context("failed while serving validator component")
}

pub fn is_open_telemetry_enabled(&self) -> bool {
let Self::Start { enable_otel, .. } = self;
*enable_otel
}
}
6 changes: 6 additions & 0 deletions bin/node/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ pub enum Command {
#[command(subcommand)]
BlockProducer(commands::block_producer::BlockProducerCommand),

// 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.
Expand All @@ -48,6 +52,7 @@ impl Command {
Command::Store(subcommand) => subcommand.is_open_telemetry_enabled(),
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(),
} {
OpenTelemetry::Enabled
Expand All @@ -61,6 +66,7 @@ impl Command {
Command::Rpc(rpc_command) => rpc_command.handle().await,
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,
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/block-producer/src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ pub struct BlockProducer {
impl BlockProducer {
/// Serves the block-producer RPC API, the batch-builder and the block-builder.
///
/// Note: Executes in place (i.e. not spawned) and will run indefinitely until
/// a fatal error is encountered.
/// Executes in place (i.e. not spawned) and will run indefinitely until a fatal error is
/// encountered.
#[allow(clippy::too_many_lines)]
pub async fn serve(self) -> anyhow::Result<()> {
info!(target: COMPONENT, endpoint=?self.block_producer_address, store=%self.store_url, "Initializing server");
Expand Down
2 changes: 2 additions & 0 deletions crates/proto/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use miden_node_proto_build::{
store_ntx_builder_api_descriptor,
store_rpc_api_descriptor,
store_shared_api_descriptor,
validator_api_descriptor,
};
use miette::{Context, IntoDiagnostic};
use tonic_build::FileDescriptorSet;
Expand Down Expand Up @@ -46,6 +47,7 @@ fn main() -> miette::Result<()> {
generate_bindings(store_shared_api_descriptor(), &dst_dir)?;
generate_bindings(block_producer_api_descriptor(), &dst_dir)?;
generate_bindings(remote_prover_api_descriptor(), &dst_dir)?;
generate_bindings(validator_api_descriptor(), &dst_dir)?;

generate_mod_rs(&dst_dir).into_diagnostic().wrap_err("generating mod.rs")?;

Expand Down
1 change: 1 addition & 0 deletions crates/proto/src/generated/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ pub mod rpc;
pub mod rpc_store;
pub mod shared;
pub mod transaction;
pub mod validator;
Loading