From 4cc39de4c5ea29fcb10901f6db0188f343b6637e Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Tue, 27 Aug 2024 14:11:21 -0700 Subject: [PATCH 1/3] chore: update MSRV in the main README --- README.md | 6 +++--- bin/node/Dockerfile | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cf14b3a89..4afd274f5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/0xPolygonMiden/miden-node/blob/main/LICENSE) [![test](https://github.com/0xPolygonMiden/miden-node/actions/workflows/test.yml/badge.svg)](https://github.com/0xPolygonMiden/miden-node/actions/workflows/test.yml) -[![RUST_VERSION](https://img.shields.io/badge/rustc-1.78+-lightgray.svg)](https://www.rust-lang.org/tools/install) +[![RUST_VERSION](https://img.shields.io/badge/rustc-1.80+-lightgray.svg)](https://www.rust-lang.org/tools/install) [![crates.io](https://img.shields.io/crates/v/miden-node)](https://crates.io/crates/miden-node) This repository holds the Miden node; that is, the software which processes transactions and creates blocks for the Miden rollup. @@ -56,9 +56,9 @@ sudo dpkg -i $package_name.deb > ``` > can be used so long as the checksum file and the package file are in the same folder. -### Intall using `cargo` +### Install using `cargo` -Install Rust version **1.78** or greater using the official Rust installation [instructions](https://www.rust-lang.org/tools/install). +Install Rust version **1.80** or greater using the official Rust installation [instructions](https://www.rust-lang.org/tools/install). Depending on the platform, you may need to install additional libraries. For example, on Ubuntu 22.04 the following command ensures that all required libraries are installed. diff --git a/bin/node/Dockerfile b/bin/node/Dockerfile index 9add73b81..577e5e61b 100644 --- a/bin/node/Dockerfile +++ b/bin/node/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.78-slim-bookworm AS builder +FROM rust:1.80-slim-bookworm AS builder RUN apt-get update && \ apt-get -y upgrade && \ From 042e73593606acb96b191decbbc15722ae2b2448 Mon Sep 17 00:00:00 2001 From: Mirko <48352201+Mirko-von-Leipzig@users.noreply.github.com> Date: Tue, 10 Sep 2024 10:51:50 +0200 Subject: [PATCH 2/3] feat: component startup is now coherent (#488) Splits node component startup into two steps: initialization and serving the api. Initialization includes binding the tcp listener on the endpoint. This enables the caller to know when the component is ready for communication prior to actually spawning the server. In particular, this solves the issue of spawning a server, and then sleeping an arbitrary amount to wait for the server to become available. Instead we now do `Component::init` after which the endpoint is valid. --- CHANGELOG.md | 6 ++ Cargo.lock | 3 + Cargo.toml | 2 + bin/node/Cargo.toml | 2 +- bin/node/src/commands/start.rs | 52 +++------ bin/node/src/main.rs | 29 +++-- crates/block-producer/Cargo.toml | 5 +- crates/block-producer/src/server/mod.rs | 135 ++++++++++++++---------- crates/rpc/Cargo.toml | 3 +- crates/rpc/src/server/mod.rs | 73 ++++++++----- crates/store/Cargo.toml | 3 +- crates/store/src/server/mod.rs | 75 ++++++++----- 12 files changed, 229 insertions(+), 159 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a23f1d516..6aca0c9ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.5.1 (TBD) + +### Enhancements + +- Node component server startup is now coherent instead of requiring an arbitrary sleep amount (#488). + ## 0.5.0 (2024-08-27) ### Enhancements diff --git a/Cargo.lock b/Cargo.lock index 318a25ddf..17f6a8f13 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1836,6 +1836,7 @@ dependencies = [ "serde", "thiserror", "tokio", + "tokio-stream", "toml", "tonic", "tracing", @@ -1876,6 +1877,7 @@ dependencies = [ "prost", "serde", "tokio", + "tokio-stream", "toml", "tonic", "tonic-web", @@ -1902,6 +1904,7 @@ dependencies = [ "serde", "thiserror", "tokio", + "tokio-stream", "toml", "tonic", "tracing", diff --git a/Cargo.toml b/Cargo.toml index c1b0ee5f7..a5adccbf4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,8 @@ miden-processor = { version = "0.10" } miden-stdlib = { version = "0.10", default-features = false } miden-tx = { version = "0.5" } thiserror = { version = "1.0" } +tokio = { version = "1.38" } +tokio-stream = { version = "0.1" } tonic = { version = "0.11" } tracing = { version = "0.1" } tracing-subscriber = { version = "0.3", features = ["fmt", "json", "env-filter"] } diff --git a/bin/node/Cargo.toml b/bin/node/Cargo.toml index 1ec7b1dea..902f54f5b 100644 --- a/bin/node/Cargo.toml +++ b/bin/node/Cargo.toml @@ -28,7 +28,7 @@ miden-node-utils = { workspace = true } miden-objects = { workspace = true } rand_chacha = "0.3" serde = { version = "1.0", features = ["derive"] } -tokio = { version = "1.38", features = ["rt-multi-thread", "net", "macros"] } +tokio = { workspace = true, features = ["rt-multi-thread", "net", "macros"] } toml = { version = "0.8" } tracing = { workspace = true } tracing-subscriber = { workspace = true } diff --git a/bin/node/src/commands/start.rs b/bin/node/src/commands/start.rs index f52e3777a..acbd356ac 100644 --- a/bin/node/src/commands/start.rs +++ b/bin/node/src/commands/start.rs @@ -1,9 +1,7 @@ -use std::time::Duration; - -use anyhow::{anyhow, Result}; -use miden_node_block_producer::{config::BlockProducerConfig, server as block_producer_server}; -use miden_node_rpc::{config::RpcConfig, server as rpc_server}; -use miden_node_store::{config::StoreConfig, server as store_server}; +use anyhow::{Context, Result}; +use miden_node_block_producer::server::BlockProducer; +use miden_node_rpc::server::Rpc; +use miden_node_store::server::Store; use tokio::task::JoinSet; use crate::config::NodeConfig; @@ -16,16 +14,18 @@ pub async fn start_node(config: NodeConfig) -> Result<()> { let mut join_set = JoinSet::new(); - // Start store - join_set.spawn(start_store(store)); + // Start store. The store endpoint is available after loading completes. + let store = Store::init(store).await.context("Loading store")?; + join_set.spawn(async move { store.serve().await.context("Serving store") }); - // Wait for store to start & start block-producer - tokio::time::sleep(Duration::from_secs(1)).await; - join_set.spawn(start_block_producer(block_producer)); + // Start block-producer. The block-producer's endpoint is available after loading completes. + let block_producer = + BlockProducer::init(block_producer).await.context("Loading block-producer")?; + join_set.spawn(async move { block_producer.serve().await.context("Serving block-producer") }); - // Wait for block-producer to start & start rpc - tokio::time::sleep(Duration::from_secs(1)).await; - join_set.spawn(start_rpc(rpc)); + // Start RPC component. + let rpc = Rpc::init(rpc).await.context("Loading RPC")?; + join_set.spawn(async move { rpc.serve().await.context("Serving RPC") }); // block on all tasks while let Some(res) = join_set.join_next().await { @@ -35,27 +35,3 @@ pub async fn start_node(config: NodeConfig) -> Result<()> { Ok(()) } - -pub async fn start_block_producer(config: BlockProducerConfig) -> Result<()> { - block_producer_server::serve(config) - .await - .map_err(|err| anyhow!("Failed to serve block-producer: {}", err))?; - - Ok(()) -} - -pub async fn start_rpc(config: RpcConfig) -> Result<()> { - rpc_server::serve(config) - .await - .map_err(|err| anyhow!("Failed to serve rpc: {}", err))?; - - Ok(()) -} - -pub async fn start_store(config: StoreConfig) -> Result<()> { - store_server::serve(config) - .await - .map_err(|err| anyhow!("Failed to serve store: {}", err))?; - - Ok(()) -} diff --git a/bin/node/src/main.rs b/bin/node/src/main.rs index 615931a44..1e04356c0 100644 --- a/bin/node/src/main.rs +++ b/bin/node/src/main.rs @@ -2,10 +2,10 @@ use std::path::PathBuf; use anyhow::{anyhow, Context}; use clap::{Parser, Subcommand}; -use commands::{ - init::init_config_files, - start::{start_block_producer, start_node, start_rpc, start_store}, -}; +use commands::{init::init_config_files, start::start_node}; +use miden_node_block_producer::server::BlockProducer; +use miden_node_rpc::server::Rpc; +use miden_node_store::server::Store; use miden_node_utils::config::load_config; mod commands; @@ -94,15 +94,30 @@ async fn main() -> anyhow::Result<()> { }, StartCommand::BlockProducer => { let config = load_config(config).context("Loading configuration file")?; - start_block_producer(config).await + BlockProducer::init(config) + .await + .context("Loading block-producer")? + .serve() + .await + .context("Serving block-producer") }, StartCommand::Rpc => { let config = load_config(config).context("Loading configuration file")?; - start_rpc(config).await + Rpc::init(config) + .await + .context("Loading RPC")? + .serve() + .await + .context("Serving RPC") }, StartCommand::Store => { let config = load_config(config).context("Loading configuration file")?; - start_store(config).await + Store::init(config) + .await + .context("Loading store")? + .serve() + .await + .context("Serving store") }, }, Command::MakeGenesis { output_path, force, inputs_path } => { diff --git a/crates/block-producer/Cargo.toml b/crates/block-producer/Cargo.toml index 85f69b037..711f4b32c 100644 --- a/crates/block-producer/Cargo.toml +++ b/crates/block-producer/Cargo.toml @@ -26,7 +26,8 @@ miden-stdlib = { workspace = true } miden-tx = { workspace = true } serde = { version = "1.0", features = ["derive"] } thiserror = { workspace = true } -tokio = { version = "1.38", features = ["rt-multi-thread", "net", "macros", "sync", "time"] } +tokio = { workspace = true, features = ["rt-multi-thread", "net", "macros", "sync", "time"] } +tokio-stream = { workspace = true, features = ["net"] } toml = { version = "0.8" } tonic = { workspace = true } tracing = { workspace = true } @@ -41,5 +42,5 @@ miden-objects = { workspace = true, features = ["testing"] } miden-tx = { workspace = true, features = ["testing"] } once_cell = { version = "1.18" } rand_chacha = { version = "0.3", default-features = false } -tokio = { version = "1.38", features = ["test-util"] } +tokio = { workspace = true, features = ["test-util"] } winterfell = { version = "0.9" } diff --git a/crates/block-producer/src/server/mod.rs b/crates/block-producer/src/server/mod.rs index 0e31b9d63..46a19f925 100644 --- a/crates/block-producer/src/server/mod.rs +++ b/crates/block-producer/src/server/mod.rs @@ -2,7 +2,8 @@ use std::{net::ToSocketAddrs, sync::Arc}; use miden_node_proto::generated::{block_producer::api_server, store::api_client as store_client}; use miden_node_utils::errors::ApiError; -use tonic::transport::Server; +use tokio::net::TcpListener; +use tokio_stream::wrappers::TcpListenerStream; use tracing::info; use crate::{ @@ -18,59 +19,87 @@ use crate::{ pub mod api; -// BLOCK PRODUCER INITIALIZER -// ================================================================================================ +type Api = api::BlockProducerApi< + DefaultBatchBuilder< + DefaultStore, + DefaultBlockBuilder>, + >, + DefaultStateView, +>; -pub async fn serve(config: BlockProducerConfig) -> Result<(), ApiError> { - info!(target: COMPONENT, %config, "Initializing server"); +/// Represents an initialized block-producer component where the RPC connection is open, +/// but not yet actively responding to requests. Separating the connection binding +/// from the server spawning allows the caller to connect other components to the +/// store without resorting to sleeps or other mechanisms to spawn dependent components. +pub struct BlockProducer { + api_service: api_server::ApiServer, + listener: TcpListener, +} + +impl BlockProducer { + /// Performs all expensive initialization tasks, and notably begins listening on the rpc + /// endpoint without serving the API yet. Incoming requests will be queued until + /// [`serve`](Self::serve) is called. + pub async fn init(config: BlockProducerConfig) -> Result { + info!(target: COMPONENT, %config, "Initializing server"); + + let store = Arc::new(DefaultStore::new( + store_client::ApiClient::connect(config.store_url.to_string()) + .await + .map_err(|err| ApiError::DatabaseConnectionFailed(err.to_string()))?, + )); + let state_view = + Arc::new(DefaultStateView::new(Arc::clone(&store), config.verify_tx_proofs)); + + let block_builder = DefaultBlockBuilder::new(Arc::clone(&store), Arc::clone(&state_view)); + let batch_builder_options = DefaultBatchBuilderOptions { + block_frequency: SERVER_BLOCK_FREQUENCY, + max_batches_per_block: SERVER_MAX_BATCHES_PER_BLOCK, + }; + let batch_builder = Arc::new(DefaultBatchBuilder::new( + Arc::clone(&store), + Arc::new(block_builder), + batch_builder_options, + )); + + let transaction_queue_options = TransactionQueueOptions { + build_batch_frequency: SERVER_BUILD_BATCH_FREQUENCY, + batch_size: SERVER_BATCH_SIZE, + }; + let queue = Arc::new(TransactionQueue::new( + state_view, + Arc::clone(&batch_builder), + transaction_queue_options, + )); + + let api_service = + api_server::ApiServer::new(api::BlockProducerApi::new(Arc::clone(&queue))); + + tokio::spawn(async move { queue.run().await }); + tokio::spawn(async move { batch_builder.run().await }); + + let addr = config + .endpoint + .to_socket_addrs() + .map_err(ApiError::EndpointToSocketFailed)? + .next() + .ok_or_else(|| ApiError::AddressResolutionFailed(config.endpoint.to_string()))?; + + let listener = TcpListener::bind(addr).await?; + + info!(target: COMPONENT, "Server initialized"); + + Ok(Self { api_service, listener }) + } - let store = Arc::new(DefaultStore::new( - store_client::ApiClient::connect(config.store_url.to_string()) + /// Serves the block-producers's RPC API. + /// + /// Note: this blocks until the server dies. + pub async fn serve(self) -> Result<(), ApiError> { + tonic::transport::Server::builder() + .add_service(self.api_service) + .serve_with_incoming(TcpListenerStream::new(self.listener)) .await - .map_err(|err| ApiError::DatabaseConnectionFailed(err.to_string()))?, - )); - let state_view = Arc::new(DefaultStateView::new(Arc::clone(&store), config.verify_tx_proofs)); - - let block_builder = DefaultBlockBuilder::new(Arc::clone(&store), Arc::clone(&state_view)); - let batch_builder_options = DefaultBatchBuilderOptions { - block_frequency: SERVER_BLOCK_FREQUENCY, - max_batches_per_block: SERVER_MAX_BATCHES_PER_BLOCK, - }; - let batch_builder = Arc::new(DefaultBatchBuilder::new( - Arc::clone(&store), - Arc::new(block_builder), - batch_builder_options, - )); - - let transaction_queue_options = TransactionQueueOptions { - build_batch_frequency: SERVER_BUILD_BATCH_FREQUENCY, - batch_size: SERVER_BATCH_SIZE, - }; - let queue = Arc::new(TransactionQueue::new( - state_view, - Arc::clone(&batch_builder), - transaction_queue_options, - )); - - let block_producer = api_server::ApiServer::new(api::BlockProducerApi::new(Arc::clone(&queue))); - - tokio::spawn(async move { queue.run().await }); - tokio::spawn(async move { batch_builder.run().await }); - - info!(target: COMPONENT, "Server initialized"); - - let addr = config - .endpoint - .to_socket_addrs() - .map_err(ApiError::EndpointToSocketFailed)? - .next() - .ok_or_else(|| ApiError::AddressResolutionFailed(config.endpoint.to_string()))?; - - Server::builder() - .add_service(block_producer) - .serve(addr) - .await - .map_err(ApiError::ApiServeFailed)?; - - Ok(()) + .map_err(ApiError::ApiServeFailed) + } } diff --git a/crates/rpc/Cargo.toml b/crates/rpc/Cargo.toml index a4d779625..c6db3ed25 100644 --- a/crates/rpc/Cargo.toml +++ b/crates/rpc/Cargo.toml @@ -23,7 +23,8 @@ miden-objects = { workspace = true } miden-tx = { workspace = true } prost = { version = "0.12" } serde = { version = "1.0", features = ["derive"] } -tokio = { version = "1.38", features = ["rt-multi-thread", "net", "macros"] } +tokio = { workspace = true, features = ["rt-multi-thread", "net", "macros"] } +tokio-stream = { workspace = true, features = ["net"] } toml = { version = "0.8" } tonic = { workspace = true } tonic-web = { version = "0.11" } diff --git a/crates/rpc/src/server/mod.rs b/crates/rpc/src/server/mod.rs index 222b55537..9745f7378 100644 --- a/crates/rpc/src/server/mod.rs +++ b/crates/rpc/src/server/mod.rs @@ -1,40 +1,57 @@ use std::net::ToSocketAddrs; +use api::RpcApi; use miden_node_proto::generated::rpc::api_server; use miden_node_utils::errors::ApiError; -use tonic::transport::Server; +use tokio::net::TcpListener; +use tokio_stream::wrappers::TcpListenerStream; use tracing::info; use crate::{config::RpcConfig, COMPONENT}; mod api; -// RPC INITIALIZER -// ================================================================================================ - -pub async fn serve(config: RpcConfig) -> Result<(), ApiError> { - info!(target: COMPONENT, %config, "Initializing server"); - - let api = api::RpcApi::from_config(&config) - .await - .map_err(|err| ApiError::ApiInitialisationFailed(err.to_string()))?; - let rpc = api_server::ApiServer::new(api); - - info!(target: COMPONENT, "Server initialized"); - - let addr = config - .endpoint - .to_socket_addrs() - .map_err(ApiError::EndpointToSocketFailed)? - .next() - .ok_or_else(|| ApiError::AddressResolutionFailed(config.endpoint.to_string()))?; - - Server::builder() - .accept_http1(true) - .add_service(tonic_web::enable(rpc)) - .serve(addr) - .await - .map_err(ApiError::ApiServeFailed)?; +/// Represents an initialized rpc component where the RPC connection is open, +/// but not yet actively responding to requests. Separating the connection binding +/// from the server spawning allows the caller to connect other components to the +/// store without resorting to sleeps or other mechanisms to spawn dependent components. +pub struct Rpc { + api_service: api_server::ApiServer, + listener: TcpListener, +} - Ok(()) +impl Rpc { + pub async fn init(config: RpcConfig) -> Result { + info!(target: COMPONENT, %config, "Initializing server"); + + let api = api::RpcApi::from_config(&config) + .await + .map_err(|err| ApiError::ApiInitialisationFailed(err.to_string()))?; + let api_service = api_server::ApiServer::new(api); + + let addr = config + .endpoint + .to_socket_addrs() + .map_err(ApiError::EndpointToSocketFailed)? + .next() + .ok_or_else(|| ApiError::AddressResolutionFailed(config.endpoint.to_string()))?; + + let listener = TcpListener::bind(addr).await?; + + info!(target: COMPONENT, "Server initialized"); + + Ok(Self { api_service, listener }) + } + + /// Serves the RPC API. + /// + /// Note: this blocks until the server dies. + pub async fn serve(self) -> Result<(), ApiError> { + tonic::transport::Server::builder() + .accept_http1(true) + .add_service(tonic_web::enable(self.api_service)) + .serve_with_incoming(TcpListenerStream::new(self.listener)) + .await + .map_err(ApiError::ApiServeFailed) + } } diff --git a/crates/store/Cargo.toml b/crates/store/Cargo.toml index e22d89f60..22c2f748e 100644 --- a/crates/store/Cargo.toml +++ b/crates/store/Cargo.toml @@ -26,7 +26,8 @@ rusqlite = { version = "0.31", features = ["array", "buildtime_bindgen", "bundle rusqlite_migration = { version = "1.0" } serde = { version = "1.0", features = ["derive"] } thiserror = { workspace = true } -tokio = { version = "1.38", features = ["fs", "net", "macros", "rt-multi-thread"] } +tokio = { workspace = true, features = ["fs", "net", "macros", "rt-multi-thread"] } +tokio-stream = { workspace = true, features = ["net"] } toml = { version = "0.8" } tonic = { workspace = true } tracing = { workspace = true } diff --git a/crates/store/src/server/mod.rs b/crates/store/src/server/mod.rs index 30b1e0cd2..0c912193b 100644 --- a/crates/store/src/server/mod.rs +++ b/crates/store/src/server/mod.rs @@ -2,47 +2,66 @@ use std::{net::ToSocketAddrs, sync::Arc}; use miden_node_proto::generated::store::api_server; use miden_node_utils::errors::ApiError; -use tonic::transport::Server; +use tokio::net::TcpListener; +use tokio_stream::wrappers::TcpListenerStream; use tracing::info; use crate::{blocks::BlockStore, config::StoreConfig, db::Db, state::State, COMPONENT}; mod api; -// STORE INITIALIZER -// ================================================================================================ - -pub async fn serve(config: StoreConfig) -> Result<(), ApiError> { - info!(target: COMPONENT, %config, "Initializing server"); +/// Represents an initialized store component where the RPC connection is open, +/// but not yet actively responding to requests. Separating the connection binding +/// from the server spawning allows the caller to connect other components to the +/// store without resorting to sleeps or other mechanisms to spawn dependent components. +pub struct Store { + api_service: api_server::ApiServer, + listener: TcpListener, +} - let block_store = Arc::new(BlockStore::new(config.blockstore_dir.clone()).await?); +impl Store { + /// Loads the required database data and initializes the TCP listener without + /// serving the API yet. Incoming requests will be queued until [`serve`](Self::serve) is + /// called. + pub async fn init(config: StoreConfig) -> Result { + info!(target: COMPONENT, %config, "Loading database"); - let db = Db::setup(config.clone(), Arc::clone(&block_store)) - .await - .map_err(|err| ApiError::ApiInitialisationFailed(err.to_string()))?; + let block_store = Arc::new(BlockStore::new(config.blockstore_dir.clone()).await?); - let state = Arc::new( - State::load(db, block_store) + let db = Db::setup(config.clone(), Arc::clone(&block_store)) .await - .map_err(|err| ApiError::DatabaseConnectionFailed(err.to_string()))?, - ); + .map_err(|err| ApiError::ApiInitialisationFailed(err.to_string()))?; + + let state = Arc::new( + State::load(db, block_store) + .await + .map_err(|err| ApiError::DatabaseConnectionFailed(err.to_string()))?, + ); - let store = api_server::ApiServer::new(api::StoreApi { state }); + let api_service = api_server::ApiServer::new(api::StoreApi { state }); - info!(target: COMPONENT, "Server initialized"); + let addr = config + .endpoint + .to_socket_addrs() + .map_err(ApiError::EndpointToSocketFailed)? + .next() + .ok_or_else(|| ApiError::AddressResolutionFailed(config.endpoint.to_string()))?; - let addr = config - .endpoint - .to_socket_addrs() - .map_err(ApiError::EndpointToSocketFailed)? - .next() - .ok_or_else(|| ApiError::AddressResolutionFailed(config.endpoint.to_string()))?; + let listener = TcpListener::bind(addr).await?; - Server::builder() - .add_service(store) - .serve(addr) - .await - .map_err(ApiError::ApiServeFailed)?; + info!(target: COMPONENT, "Database loaded"); - Ok(()) + Ok(Self { api_service, listener }) + } + + /// Serves the store's RPC API. + /// + /// Note: this blocks until the server dies. + pub async fn serve(self) -> Result<(), ApiError> { + tonic::transport::Server::builder() + .add_service(self.api_service) + .serve_with_incoming(TcpListenerStream::new(self.listener)) + .await + .map_err(ApiError::ApiServeFailed) + } } From 2cdabadf5e22051d0f40657039edc4f959ff5766 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Thu, 12 Sep 2024 22:35:40 -0700 Subject: [PATCH 3/3] chore: update crate versions to v0.5.1 --- CHANGELOG.md | 2 +- Cargo.lock | 16 ++++++++-------- Cargo.toml | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6aca0c9ce..4d2363ab9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 0.5.1 (TBD) +## 0.5.1 (2024-09-12) ### Enhancements diff --git a/Cargo.lock b/Cargo.lock index 17f6a8f13..58d4a5b62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1708,7 +1708,7 @@ dependencies = [ [[package]] name = "miden-faucet" -version = "0.5.0" +version = "0.5.1" dependencies = [ "actix-cors", "actix-web", @@ -1796,7 +1796,7 @@ dependencies = [ [[package]] name = "miden-node" -version = "0.5.0" +version = "0.5.1" dependencies = [ "anyhow", "clap", @@ -1817,7 +1817,7 @@ dependencies = [ [[package]] name = "miden-node-block-producer" -version = "0.5.0" +version = "0.5.1" dependencies = [ "async-trait", "figment", @@ -1846,7 +1846,7 @@ dependencies = [ [[package]] name = "miden-node-proto" -version = "0.5.0" +version = "0.5.1" dependencies = [ "hex", "miden-node-utils", @@ -1863,7 +1863,7 @@ dependencies = [ [[package]] name = "miden-node-rpc" -version = "0.5.0" +version = "0.5.1" dependencies = [ "directories", "figment", @@ -1887,7 +1887,7 @@ dependencies = [ [[package]] name = "miden-node-store" -version = "0.5.0" +version = "0.5.1" dependencies = [ "deadpool-sqlite", "directories", @@ -1921,7 +1921,7 @@ dependencies = [ [[package]] name = "miden-node-utils" -version = "0.5.0" +version = "0.5.1" dependencies = [ "anyhow", "figment", @@ -1976,7 +1976,7 @@ dependencies = [ [[package]] name = "miden-rpc-proto" -version = "0.5.0" +version = "0.5.1" [[package]] name = "miden-stdlib" diff --git a/Cargo.toml b/Cargo.toml index a5adccbf4..3b991e046 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ resolver = "2" [workspace.package] edition = "2021" rust-version = "1.80" -version = "0.5.0" +version = "0.5.1" license = "MIT" authors = ["Miden contributors"] homepage = "https://polygon.technology/polygon-miden"