Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Introduce top-level module docs for Rust client crate #683

Merged
merged 20 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
13 changes: 13 additions & 0 deletions .github/workflows/test.yml
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ jobs:
- name: make - test
run: make test

doc-tests:
name: doc-tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/next' }}
- name: Install rust
run: rustup update --no-self-update
- name: Run doc-tests
run: make test-docs

integration-tests:
name: integration-tests
runs-on: ubuntu-latest
Expand Down
21 changes: 15 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ help: ## Show description of all commands

# --- Variables -----------------------------------------------------------------------------------

# Enable file generation in the `src` directory.
# This is used in the build script of the client to generate the node RPC-related code, from the
# protobuf files.
CODEGEN=CODEGEN=1

FEATURES_WEB_CLIENT=--features "testing"
FEATURES_CLIENT=--features "testing, concurrent" --no-default-features
FEATURES_CLI=--features "concurrent"
Expand Down Expand Up @@ -76,29 +81,33 @@ doc: ## Generate & check rust documentation. You'll need `jq` in order for this

.PHONY: test
test: ## Run tests
CODEGEN=1 cargo nextest run --workspace --exclude miden-client-web --release --lib $(FEATURES_CLIENT)
$(CODEGEN) cargo nextest run --workspace --exclude miden-client-web --release --lib $(FEATURES_CLIENT)

.PHONY: test-deps
test-deps: ## Install dependencies for tests
CODEGEN=1 cargo install cargo-nextest
$(CODEGEN) cargo install cargo-nextest

.PHONY: test-docs
test-docs: ## Run documentation tests
$(CODEGEN) cargo test --doc $(FEATURES_CLIENT)

# --- Integration testing -------------------------------------------------------------------------

.PHONY: integration-test
integration-test: ## Run integration tests
CODEGEN=1 cargo nextest run --workspace --exclude miden-client-web --release --test=integration $(FEATURES_CLI)
$(CODEGEN) cargo nextest run --workspace --exclude miden-client-web --release --test=integration $(FEATURES_CLI)

.PHONY: integration-test-web-client
integration-test-web-client: ## Run integration tests for the web client
CODEGEN=1 cd ./crates/web-client && npm run test:clean
$(CODEGEN) cd ./crates/web-client && npm run test:clean

.PHONY: integration-test-remote-prover-web-client
integration-test-remote-prover-web-client: ## Run integration tests for the web client with remote prover
CODEGEN=1 cd ./crates/web-client && npm run test:remote_prover
$(CODEGEN) cd ./crates/web-client && npm run test:remote_prover

.PHONY: integration-test-full
integration-test-full: ## Run the integration test binary with ignored tests included
CODEGEN=1 cargo nextest run --workspace --exclude miden-client-web --release --test=integration $(FEATURES_CLI)
$(CODEGEN) cargo nextest run --workspace --exclude miden-client-web --release --test=integration $(FEATURES_CLI)
cargo nextest run --workspace --exclude miden-client-web --release --test=integration $(FEATURES_CLI) --run-ignored ignored-only -- test_import_genesis_accounts_can_be_used_for_transactions

.PHONY: kill-node
Expand Down
4 changes: 2 additions & 2 deletions bin/miden-cli/src/commands/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ the CLI and client configurations, and will be placed by default in the current
directory."
)]
pub struct InitCmd {
/// Network configuration to use. Options are devnet, testnet, localhost or a custom RPC
/// Network configuration to use. Options are `devnet`, `testnet`, `localhost` or a custom RPC
/// endpoint. Defaults to the testnet network.
#[clap(long, short, default_value = "testnet")]
network: Option<Network>,

/// Store file path.
/// Path to the store file.
#[clap(long)]
store_path: Option<String>,

Expand Down
18 changes: 10 additions & 8 deletions crates/rust-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ miden-client = { version = "0.6" }

## Crate Features

- `concurrent`: used to enable concurrency during execution and proof generation. Disabled by default.
- `idxdb`: includes `WebStore`, an IdexedDB implementation of the `Store` trait. Disabled by default.
- `sqlite`: includes `SqliteStore`, a SQLite implementation of the `Store` trait. Disabled by default.
- `tonic`: includes `TonicRpcClient`, a Tonic client to communicate with Miden node. Disabled by default.
- `web-tonic`: includes `WebTonicRpcClient`, an Tonic client to communicate with the Miden node in the browser. Disabled by default.
- `testing`: useful feature that lowers PoW difficulty when enabled, meant to be used during development and not on production. Disabled by default.

To compile with `no_std`, disable default features via `--no-default-features` flag.
| Features | Description |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `concurrent` | Used to enable concurrency during execution and proof generation. **Disabled by default.** |
| `idxdb` | Includes `WebStore`, an IndexedDB implementation of the `Store` trait. **Disabled by default.** |
| `sqlite` | Includes `SqliteStore`, a SQLite implementation of the `Store` trait. This relies on the standard library. **Disabled by default.** |
| `tonic` | Includes `TonicRpcClient`, a Tonic client to communicate with Miden node. This relies on the standard library. **Disabled by default.** |
| `web-tonic` | Includes `WebTonicRpcClient`, a Tonic client to communicate with the Miden node in the browser. **Disabled by default.** |
| `testing` | Enables functions meant to be used in testing environments. **Disabled by default.** |

Features `sqlite` and `idxdb` are mutually exclusive.

### Store and RpcClient implementations

Expand Down
91 changes: 52 additions & 39 deletions crates/rust-client/src/account.rs
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,8 +1,44 @@
//! The `accounts` module provides types and client APIs for managing accounts within the Miden
//! rollup network .
//! The `account` module provides types and client APIs for managing accounts within the Miden
//! network.
//!
//! Once accounts start being tracked by the client, their state will be
//! updated accordingly on every transaction, and validated against the rollup on every sync.
//! Once accounts start being tracked by the client, their state will be updated accordingly on
//! every transaction, and validated against the rollup on every sync.
//!
//! An account can store assets and define rules for manipulating them.
//!
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
//! # Example
//!
//! To add a new account to the client's store, you might use the [`Client::add_account`] method as
//! follows:
//!
//! ```rust
//! # use miden_client::account::{Account, AccountBuilder, AccountType, BasicWalletComponent};
//! # use miden_objects::account::{AuthSecretKey, AccountStorageMode};
//! # use miden_client::crypto::{FeltRng, SecretKey};
//! # async fn add_new_account_example(
//! # client: &mut miden_client::Client<impl FeltRng>
//! # ) -> Result<(), miden_client::ClientError> {
//! # let random_seed = Default::default();
//! let key_pair = SecretKey::with_rng(client.rng());
//!
//! let (account, seed) = AccountBuilder::new(random_seed)
//! .account_type(AccountType::RegularAccountImmutableCode)
//! .storage_mode(AccountStorageMode::Private)
//! .with_component(BasicWalletComponent)
//! .build()?;
//!
//! // Add the account to the client. The account seed and authentication key are required
//! // for new accounts.
//! client.add_account(&account,
//! Some(seed),
//! &AuthSecretKey::RpoFalcon512(key_pair),
//! false
//! ).await?;
//! # Ok(())
//! # }
//! ```
//!
//! For more details on accounts, refer to the [Account] documentation.

use alloc::vec::Vec;

Expand All @@ -15,14 +51,25 @@ pub use miden_objects::account::{
Account, AccountBuilder, AccountCode, AccountData, AccountHeader, AccountId, AccountStorage,
AccountStorageMode, AccountType, StorageSlot, StorageSlotType,
};
use miden_objects::{account::AuthSecretKey, crypto::rand::FeltRng, Digest, Word};
use miden_objects::{account::AuthSecretKey, crypto::rand::FeltRng, Word};

use super::Client;
use crate::{
store::{AccountRecord, AccountStatus},
ClientError,
};

/// This account section of the client contains functionality for:
///
/// - **Account creation:** Use the [`AccountBuilder`] to construct new accounts, specifying account
/// type, storage mode (public/private), and attaching necessary components (e.g., basic wallet or
/// fungible faucet). After creation, they can be added to the client.
///
/// - **Account tracking:** Accounts added via the client are persisted to the local store, where
/// their state (including nonce, balance, and metadata) is updated upon every synchronization
/// with the network.
///
/// - **Data retrieval:** The module also provides methods to fetch account-related data.
impl<R: FeltRng> Client<R> {
// ACCOUNT CREATION
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
// --------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -177,40 +224,6 @@ impl<R: FeltRng> Client<R> {
}
}

// ACCOUNT UPDATES
// ================================================================================================

/// Contains account changes to apply to the store.
pub struct AccountUpdates {
/// Updated public accounts.
updated_public_accounts: Vec<Account>,
/// Node account hashes that don't match the current tracked state for private accounts.
mismatched_private_accounts: Vec<(AccountId, Digest)>,
}

impl AccountUpdates {
/// Creates a new instance of `AccountUpdates`.
pub fn new(
updated_public_accounts: Vec<Account>,
mismatched_private_accounts: Vec<(AccountId, Digest)>,
) -> Self {
Self {
updated_public_accounts,
mismatched_private_accounts,
}
}

/// Returns the updated public accounts.
pub fn updated_public_accounts(&self) -> &[Account] {
&self.updated_public_accounts
}

/// Returns the mismatched private accounts.
pub fn mismatched_private_accounts(&self) -> &[(AccountId, Digest)] {
&self.mismatched_private_accounts
}
}

// TESTS
// ================================================================================================

Expand Down
102 changes: 100 additions & 2 deletions crates/rust-client/src/lib.rs
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,3 +1,102 @@
//! A no_std-compatible client library for interacting with the Miden rollup network.
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
//!
//! This crate provides a lightweight client that handles connections to the Miden node, manages
//! accounts and their state, and facilitates executing, proving, and submitting transactions.
//!
//! For a protocol-level overview and guides for getting started, please visit the official
//! [Polygon Miden docs](https://docs.polygon.technology/miden/).
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
//!
//! ## Overview
//!
//! The library is organized into several key modules:
//!
//! - **Accounts:** Provides types, builders, and client APIs for managing accounts. Once accounts
//! are tracked by the client, their state is updated with every transaction and validated during
//! each sync.
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
//!
//! - **Notes:** Contains types and utilities for working with notes in the Miden client.
//!
//! - **RPC:** Facilitates communication with Miden node, exposing RPC methods for syncing state,
//! fetching block headers, and submitting transactions.
//!
//! - **Store:** Defines and implements the persistence layer for accounts, transactions, notes, and
//! other entities.
//!
//! - **Sync:** Provides functionality to synchronize the local state with the current state on the
//! Miden network.
//!
//! - **Transactions:** Offers capabilities to build, execute, prove, and submit transactions.
//!
//! Additionally, the crate re-exports several utility modules:
//!
//! - **Assets:** Types and utilities for working with assets.
//! - **Auth:** Authentication-related types and functionalities.
//! - **Blocks:** Types for handling block headers.
//! - **Crypto:** Cryptographic types and utilities, including random number generators.
//! - **Utils:** Miscellaneous utilities for serialization and common operations.
//!
//! The library is designed to work in both `no_std` and `std` environments and is
//! configurable via Cargo features.
//!
//! ## Usage
//!
//! To use the Miden client library in your project, add it as a dependency in your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! miden-client = "0.7.0"
//! ```
//!
//! ## Example
//!
//! Below is a brief example illustrating how to instantiate the client:
//!
//! ```rust
//! use std::sync::Arc;
//!
//! use miden_client::{
//! crypto::RpoRandomCoin,
//! rpc::{Endpoint, TonicRpcClient},
//! store::{sqlite_store::SqliteStore, Store, StoreAuthenticator},
//! Client, Felt,
//! };
//! use miden_objects::crypto::rand::FeltRng;
//! use rand::Rng;
//!
//! # pub async fn create_test_client() -> Result<(), Box<dyn std::error::Error>> {
//! let client: Client<RpoRandomCoin> = {
//! // Create the SQLite store from the client configuration.
//! let sqlite_store = SqliteStore::new("path/to/store".try_into()?).await?;
//! let store = Arc::new(sqlite_store);
//!
//! // Generate a random seed for the RpoRandomCoin.
//! let mut rng = rand::thread_rng();
//! let coin_seed: [u64; 4] = rng.gen();
//!
//! // Initialize the random coin using the generated seed.
//! let rng = RpoRandomCoin::new(coin_seed.map(Felt::new));
//!
//! // Create a store authenticator with the store and random coin.
//! let authenticator = StoreAuthenticator::new_with_rng(store.clone(), rng);
//!
//! // Instantiate the client using a Tonic RPC client
//! let endpoint = Endpoint::new("https".into(), "localhost".into(), Some(57291));
//! Client::new(
//! Box::new(TonicRpcClient::new(endpoint, 10_000)),
//! rng,
//! store,
//! Arc::new(authenticator),
//! false, // Set to true for debug mode, if needed.
//! )
//! };
//!
//! # Ok(())
//! # }
//! ```
//!
//! For additional usage details, configuration options, and examples, consult the documentation for
//! each module.

#![no_std]

#[macro_use]
Expand Down Expand Up @@ -104,8 +203,7 @@ use tracing::info;
/// Miden client is responsible for managing a set of accounts. Specifically, the client:
/// - Keeps track of the current and historical states of a set of accounts and related objects such
/// as notes and transactions.
/// - Connects to one or more Miden nodes to periodically sync with the current state of the
/// network.
/// - Connects to a Miden node to periodically sync with the current state of the network.
/// - Executes, proves, and submits transactions to the network as directed by the user.
pub struct Client<R: FeltRng> {
/// The client's store, which provides a way to write and read entities to provide persistence.
Expand Down
14 changes: 13 additions & 1 deletion crates/rust-client/src/note/import.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
//! Provides note importing methods.
//!
//! This module allows users to import notes into the client's store.
//! Depending on the variant of [NoteFile] provided, the client will either fetch note details
//! from the network or create a new note record from supplied data. If a note already exists in
//! the store, it is updated with the new information. Additionally, the appropriate note tag
//! is tracked based on the imported note's metadata.
//!
//! For more specific information on how the process is performed, refer to the docs for
//! [Client::import_note()].
use alloc::string::ToString;

use miden_objects::{
Expand Down Expand Up @@ -29,6 +39,8 @@ impl<R: FeltRng> Client<R> {
/// - If the note file is a [NoteFile::NoteWithProof], the note is stored with the provided
/// inclusion proof and metadata. The block header data is only fetched from the node if the
/// note is committed in the past relative to the client.
///
/// An error is returned if an attempt is made to overwrite a note that is currently processing.
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
pub async fn import_note(&mut self, note_file: NoteFile) -> Result<NoteId, ClientError> {
let id = match &note_file {
NoteFile::NoteId(id) => *id,
Expand Down Expand Up @@ -77,7 +89,7 @@ impl<R: FeltRng> Client<R> {
/// passed via `previous_note` so it can be updated. The note information is fetched from the
/// node and stored in the client's store.
///
/// Errors:
/// # Errors:
/// - If the note doesn't exist on the node.
/// - If the note exists but is private.
async fn import_note_record_by_id(
Expand Down
Loading
Loading