Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v0.15.0 (TBD)

- [BREAKING] Changed `GetBlockByNumber` to accept a `BlockRequest` (with optional `include_proof` flag) and returns a response containing the block and an optional block proof ([#1864](https://github.com/0xMiden/node/pull/1864)).

## v0.14.1 (2025-04-02)

- Fixed batch building issue with unauthenticated notes consumed in the same batch as they were created ([#1875](https://github.com/0xMiden/node/issues/1875)).
Expand Down
36 changes: 18 additions & 18 deletions Cargo.lock

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

28 changes: 14 additions & 14 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ license = "MIT"
readme = "README.md"
repository = "https://github.com/0xMiden/node"
rust-version = "1.93"
version = "0.14.1"
version = "0.15.0"

# Optimize the cryptography for faster tests involving account creation.
[profile.test.package.miden-crypto]
Expand All @@ -43,22 +43,22 @@ debug = true

[workspace.dependencies]
# Workspace crates.
miden-large-smt-backend-rocksdb = { path = "crates/large-smt-backend-rocksdb", version = "0.14" }
miden-node-block-producer = { path = "crates/block-producer", version = "0.14" }
miden-node-db = { path = "crates/db", version = "0.14" }
miden-node-grpc-error-macro = { path = "crates/grpc-error-macro", version = "0.14" }
miden-node-ntx-builder = { path = "crates/ntx-builder", version = "0.14" }
miden-node-proto = { path = "crates/proto", version = "0.14" }
miden-node-proto-build = { path = "proto", version = "0.14" }
miden-node-rpc = { path = "crates/rpc", version = "0.14" }
miden-node-store = { path = "crates/store", version = "0.14" }
miden-large-smt-backend-rocksdb = { path = "crates/large-smt-backend-rocksdb", version = "0.15" }
miden-node-block-producer = { path = "crates/block-producer", version = "0.15" }
miden-node-db = { path = "crates/db", version = "0.15" }
miden-node-grpc-error-macro = { path = "crates/grpc-error-macro", version = "0.15" }
miden-node-ntx-builder = { path = "crates/ntx-builder", version = "0.15" }
miden-node-proto = { path = "crates/proto", version = "0.15" }
miden-node-proto-build = { path = "proto", version = "0.15" }
miden-node-rpc = { path = "crates/rpc", version = "0.15" }
miden-node-store = { path = "crates/store", version = "0.15" }
miden-node-test-macro = { path = "crates/test-macro" }
miden-node-utils = { path = "crates/utils", version = "0.14" }
miden-node-validator = { path = "crates/validator", version = "0.14" }
miden-remote-prover-client = { path = "crates/remote-prover-client", version = "0.14" }
miden-node-utils = { path = "crates/utils", version = "0.15" }
miden-node-validator = { path = "crates/validator", version = "0.15" }
miden-remote-prover-client = { path = "crates/remote-prover-client", version = "0.15" }
# Temporary workaround until <https://github.com/rust-rocksdb/rust-rocksdb/pull/1029>
# is part of `rocksdb-rust` release
miden-node-rocksdb-cxx-linkage-fix = { path = "crates/rocksdb-cxx-linkage-fix", version = "0.14" }
miden-node-rocksdb-cxx-linkage-fix = { path = "crates/rocksdb-cxx-linkage-fix", version = "0.15" }

# miden-protocol dependencies. These should be updated in sync.
miden-agglayer = { version = "0.14" }
Expand Down
6 changes: 3 additions & 3 deletions bin/node/src/commands/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use miden_node_store::{DEFAULT_MAX_CONCURRENT_PROOFS, Store};
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::ProvenBlock;
use miden_protocol::block::SignedBlock;
use miden_protocol::utils::serde::Deserializable;
use url::Url;

Expand Down Expand Up @@ -175,10 +175,10 @@ impl StoreCommand {
pub fn bootstrap_store(data_directory: &Path, genesis_block_path: &Path) -> anyhow::Result<()> {
// Read and deserialize the genesis block file.
let bytes = fs_err::read(genesis_block_path).context("failed to read genesis block")?;
let proven_block = ProvenBlock::read_from_bytes(&bytes)
let signed_block = SignedBlock::read_from_bytes(&bytes)
.context("failed to deserialize genesis block from file")?;
let genesis_block =
GenesisBlock::try_from(proven_block).context("genesis block validation failed")?;
GenesisBlock::try_from(signed_block).context("genesis block validation failed")?;

Store::bootstrap(genesis_block, data_directory)
}
7 changes: 3 additions & 4 deletions bin/stress-test/src/seeding/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ use miden_protocol::block::{
BlockNumber,
FeeParameters,
ProposedBlock,
ProvenBlock,
SignedBlock,
};
use miden_protocol::crypto::dsa::ecdsa_k256_keccak::SecretKey as EcdsaSecretKey;
Expand Down Expand Up @@ -111,12 +110,12 @@ pub async fn seed_store(
let accounts_filepath = data_directory.join(ACCOUNTS_FILENAME);
let data_directory =
miden_node_store::DataDirectory::load(data_directory).expect("data directory should exist");
let genesis_header = genesis_state.into_block().await.unwrap().into_inner();
let genesis_block = genesis_state.into_block().await.unwrap().into_inner();
let metrics = generate_blocks(
num_accounts,
public_accounts_percentage,
faucet,
genesis_header,
genesis_block,
&store_client,
data_directory,
accounts_filepath,
Expand All @@ -137,7 +136,7 @@ async fn generate_blocks(
num_accounts: usize,
public_accounts_percentage: u8,
mut faucet: Account,
genesis_block: ProvenBlock,
genesis_block: SignedBlock,
store_client: &StoreClient,
data_directory: DataDirectory,
accounts_filepath: PathBuf,
Expand Down
4 changes: 2 additions & 2 deletions bin/stress-test/src/store/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,8 @@ async fn sync_chain_mmr(
block_to: u32,
) -> SyncChainMmrRun {
let sync_request = proto::rpc::SyncChainMmrRequest {
block_range: Some(proto::rpc::BlockRange { block_from, block_to: Some(block_to) }),
finality: proto::rpc::Finality::Committed.into(),
block_from,
upper_bound: Some(proto::rpc::sync_chain_mmr_request::UpperBound::BlockNum(block_to)),
};

let start = Instant::now();
Expand Down
36 changes: 36 additions & 0 deletions crates/proto/src/domain/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,42 @@ impl From<&FeeParameters> for proto::blockchain::FeeParameters {
}
}

// SYNC TARGET
// ================================================================================================

/// The target block to sync up to in a chain MMR sync request.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SyncTarget {
/// Sync up to a specific block number (inclusive).
BlockNumber(BlockNumber),
/// Sync up to the latest committed block (chain tip).
CommittedChainTip,
/// Sync up to the latest proven block.
ProvenChainTip,
}

impl TryFrom<proto::rpc::sync_chain_mmr_request::UpperBound> for SyncTarget {
type Error = ConversionError;

fn try_from(
value: proto::rpc::sync_chain_mmr_request::UpperBound,
) -> Result<Self, Self::Error> {
use proto::rpc::sync_chain_mmr_request::UpperBound;

match value {
UpperBound::BlockNum(block_num) => Ok(Self::BlockNumber(block_num.into())),
UpperBound::ChainTip(tip) => match proto::rpc::ChainTip::try_from(tip) {
Ok(proto::rpc::ChainTip::Committed) => Ok(Self::CommittedChainTip),
Ok(proto::rpc::ChainTip::Proven) => Ok(Self::ProvenChainTip),
// These variants should never be encountered.
Ok(proto::rpc::ChainTip::Unspecified) | Err(_) => {
Err(ConversionError::message("unexpected chain tip"))
},
},
}
}
}

// BLOCK RANGE
// ================================================================================================

Expand Down
2 changes: 1 addition & 1 deletion crates/rpc/src/server/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ impl api_server::Api for RpcService {

async fn get_block_by_number(
&self,
request: Request<proto::blockchain::BlockNumber>,
request: Request<proto::blockchain::BlockRequest>,
) -> Result<Response<proto::blockchain::MaybeBlock>, Status> {
let request = request.into_inner();

Expand Down
6 changes: 4 additions & 2 deletions crates/rpc/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,8 +607,10 @@ async fn sync_chain_mmr_returns_delta() {
let (store_runtime, _data_directory, _genesis, _store_addr) = start_store(store_listener).await;

let request = proto::rpc::SyncChainMmrRequest {
block_range: Some(proto::rpc::BlockRange { block_from: 0, block_to: None }),
finality: proto::rpc::Finality::Committed.into(),
block_from: 0,
upper_bound: Some(proto::rpc::sync_chain_mmr_request::UpperBound::ChainTip(
proto::rpc::ChainTip::Committed.into(),
)),
};
let response = rpc_client.sync_chain_mmr(request).await.expect("sync_chain_mmr should succeed");
let response = response.into_inner();
Expand Down
17 changes: 17 additions & 0 deletions crates/store/src/blocks.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
//! File-based storage for raw block data and block proofs.
//!
//! Block data is stored under `{store_dir}/{epoch:04x}/block_{block_num:08x}.dat`, and proof data
//! for proven blocks is stored under `{store_dir}/{epoch:04x}/proof_{block_num:08x}.dat`.
//!
//! The epoch is derived from the 16 most significant bits of the block number (i.e.,
//! `block_num >> 16`), and both the epoch and block number are formatted as zero-padded
//! hexadecimal strings.

use std::io::ErrorKind;
use std::ops::Not;
use std::path::PathBuf;
Expand Down Expand Up @@ -115,6 +124,14 @@ impl BlockStore {
tokio::fs::write(proof_path, data).await
}

pub async fn load_proof(&self, block_num: BlockNumber) -> std::io::Result<Option<Vec<u8>>> {
match tokio::fs::read(self.proof_path(block_num)).await {
Ok(data) => Ok(Some(data)),
Err(err) if err.kind() == std::io::ErrorKind::NotFound => Ok(None),
Err(err) => Err(err),
}
}

// HELPER FUNCTIONS
// --------------------------------------------------------------------------------------------

Expand Down
5 changes: 2 additions & 3 deletions crates/store/src/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,8 @@ impl Db {
// Run migrations.
apply_migrations(&mut conn).context("failed to apply database migrations")?;

// Insert genesis block data. Deconstruct into signed block.
let (header, body, signature, _proof) = genesis.into_inner().into_parts();
let genesis_block = SignedBlock::new_unchecked(header, body, signature);
// Insert genesis block data.
let genesis_block = genesis.into_inner();
conn.transaction(move |conn| models::queries::apply_block(conn, &genesis_block, &[], None))
.context("failed to insert genesis block")?;
Ok(())
Expand Down
Loading
Loading