Skip to content
Closed
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* [BREAKING] Merged `concurrent` feature with `std` (#974).
* [BREAKING] Changed `TransactionRequest` to use expected output recipients instead of output notes (#976).
* [BREAKING] Removed `TransactionExecutor` from `Client` and `NoteScreener` (#998).
* [BREAKING] Replace `FeltRng` trait object in `ClientBuilder` and `Client` with generic and remove `ClientRng` (#1015).

### Features

Expand Down
1 change: 0 additions & 1 deletion bin/miden-cli/src/commands/new_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use miden_lib::account::{auth::RpoFalcon512, wallets::BasicWallet};
use miden_objects::account::{
AccountComponent, AccountComponentTemplate, InitStorageData, StorageValueName,
};
use rand::RngCore;

use crate::{
CLIENT_BINARY_NAME, CliKeyStore, commands::account::maybe_set_default_account,
Expand Down
2 changes: 1 addition & 1 deletion bin/miden-cli/tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ async fn create_rust_client_with_store_path(store_path: &Path) -> (TestClient, C
let mut rng = rand::rng();
let coin_seed: [u64; 4] = rng.random();

let rng = Box::new(RpoRandomCoin::new(coin_seed.map(Felt::new)));
let rng = RpoRandomCoin::new(coin_seed.map(Felt::new));

let keystore = CliKeyStore::new(temp_dir()).unwrap();

Expand Down
36 changes: 17 additions & 19 deletions crates/rust-client/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use alloc::{
string::{String, ToString},
sync::Arc,
};
use std::boxed::Box;

use miden_objects::{
Felt, MAX_TX_EXECUTION_CYCLES, MIN_TX_EXECUTION_CYCLES,
Expand Down Expand Up @@ -46,13 +45,13 @@ enum AuthenticatorConfig {
/// This builder allows you to configure the various components required by the client, such as the
/// RPC endpoint, store, RNG, and keystore. It is generic over the keystore type. By default, it
/// uses `FilesystemKeyStore<rand::rngs::StdRng>`.
pub struct ClientBuilder {
pub struct ClientBuilder<R: FeltRng = RpoRandomCoin> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to do away with this by requiring the R to be supplied during the build fn. But wasn't sure people would prefer those ergonomics.

/// An optional custom RPC client. If provided, this takes precedence over `rpc_endpoint`.
rpc_api: Option<Arc<dyn NodeRpcClient + Send>>,
/// An optional store provided by the user.
store: Option<Arc<dyn Store>>,
/// An optional RNG provided by the user.
rng: Option<Box<dyn FeltRng>>,
/// RNG provided by the user.
rng: R,
/// The store path to use when no store is directly provided via `with_store()`.
#[cfg(feature = "sqlite")]
store_path: String,
Expand All @@ -70,10 +69,16 @@ pub struct ClientBuilder {

impl Default for ClientBuilder {
fn default() -> Self {
let rng = {
let mut seed_rng = rand::rng();
let coin_seed: [u64; 4] = seed_rng.random();
RpoRandomCoin::new(coin_seed.map(Felt::new))
};

Self {
rpc_api: None,
store: None,
rng: None,
rng,
#[cfg(feature = "sqlite")]
store_path: "store.sqlite3".to_string(),
keystore: None,
Expand All @@ -90,7 +95,9 @@ impl ClientBuilder {
pub fn new() -> Self {
Self::default()
}
}

impl<R: FeltRng> ClientBuilder<R> {
/// Enable or disable debug mode.
#[must_use]
pub fn in_debug_mode(mut self, debug: bool) -> Self {
Expand Down Expand Up @@ -128,10 +135,10 @@ impl ClientBuilder {
self
}

/// Optionally provide a custom RNG.
/// Provide a custom RNG.
#[must_use]
pub fn with_rng(mut self, rng: Box<dyn FeltRng>) -> Self {
self.rng = Some(rng);
pub fn with_rng(mut self, rng: R) -> Self {
self.rng = rng;
self
}

Expand Down Expand Up @@ -177,7 +184,7 @@ impl ClientBuilder {
/// - Returns an error if the store cannot be instantiated.
/// - Returns an error if the keystore is not specified or fails to initialize.
#[allow(clippy::unused_async, unused_mut)]
pub async fn build(mut self) -> Result<Client, ClientError> {
pub async fn build(mut self) -> Result<Client<R>, ClientError> {
// Determine the RPC client to use.
let rpc_api: Arc<dyn NodeRpcClient + Send> = if let Some(client) = self.rpc_api {
client
Expand Down Expand Up @@ -206,15 +213,6 @@ impl ClientBuilder {
));
};

// Use the provided RNG, or create a default one.
let rng = if let Some(user_rng) = self.rng {
user_rng
} else {
let mut seed_rng = rand::rng();
let coin_seed: [u64; 4] = seed_rng.random();
Box::new(RpoRandomCoin::new(coin_seed.map(Felt::new)))
};

// Initialize the authenticator.
let authenticator = match self.keystore {
Some(AuthenticatorConfig::Instance(authenticator)) => authenticator,
Expand All @@ -233,7 +231,7 @@ impl ClientBuilder {

Ok(Client::new(
rpc_api,
rng,
self.rng,
arc_store,
authenticator,
ExecutionOptions::new(
Expand Down
59 changes: 8 additions & 51 deletions crates/rust-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
//! let endpoint = Endpoint::new("https".into(), "localhost".into(), Some(57291));
//! let client: Client = Client::new(
//! Arc::new(TonicRpcClient::new(&endpoint, 10_000)),
//! Box::new(rng),
//! rng,
//! store,
//! Arc::new(keystore),
//! ExecutionOptions::new(
Expand All @@ -112,7 +112,6 @@

#[macro_use]
extern crate alloc;
use alloc::boxed::Box;

#[cfg(feature = "std")]
extern crate std;
Expand Down Expand Up @@ -206,9 +205,8 @@ pub mod testing {

use alloc::sync::Arc;

use miden_objects::crypto::rand::FeltRng;
use miden_objects::crypto::rand::{FeltRng, RpoRandomCoin};
use miden_tx::{LocalTransactionProver, auth::TransactionAuthenticator};
use rand::RngCore;
use rpc::NodeRpcClient;
use store::Store;

Expand All @@ -222,12 +220,12 @@ use store::Store;
/// as notes and transactions.
/// - 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 {
pub struct Client<R: FeltRng = RpoRandomCoin> {
/// The client's store, which provides a way to write and read entities to provide persistence.
store: Arc<dyn Store>,
/// An instance of [`FeltRng`] which provides randomness tools for generating new keys,
/// serial numbers, etc.
rng: ClientRng,
rng: R,
/// An instance of [`NodeRpcClient`] which provides a way for the client to connect to the
/// Miden node.
rpc_api: Arc<dyn NodeRpcClient + Send>,
Expand All @@ -247,7 +245,7 @@ pub struct Client {
}

/// Construction and access methods.
impl Client {
impl<R: FeltRng> Client<R> {
// CONSTRUCTOR
// --------------------------------------------------------------------------------------------

Expand Down Expand Up @@ -275,7 +273,7 @@ impl Client {
/// Returns an error if the client couldn't be instantiated.
pub fn new(
rpc_api: Arc<dyn NodeRpcClient + Send>,
rng: Box<dyn FeltRng>,
rng: R,
store: Arc<dyn Store>,
authenticator: Arc<dyn TransactionAuthenticator>,
exec_options: ExecutionOptions,
Expand All @@ -287,7 +285,7 @@ impl Client {

Self {
store,
rng: ClientRng::new(rng),
rng,
rpc_api,
tx_prover,
authenticator,
Expand All @@ -304,7 +302,7 @@ impl Client {

/// Returns a reference to the client's random number generator. This can be used to generate
/// randomness for various purposes such as serial numbers, keys, etc.
pub fn rng(&mut self) -> &mut ClientRng {
pub fn rng(&mut self) -> &mut R {
&mut self.rng
}

Expand All @@ -321,44 +319,3 @@ impl Client {
&mut self.store
}
}

// CLIENT RNG
// ================================================================================================

/// A wrapper around a [`FeltRng`] that implements the [`RngCore`] trait.
/// This allows the user to pass their own generic RNG so that it's used by the client.
pub struct ClientRng(Box<dyn FeltRng>);

impl ClientRng {
pub fn new(rng: Box<dyn FeltRng>) -> Self {
Self(rng)
}

pub fn inner_mut(&mut self) -> &mut Box<dyn FeltRng> {
&mut self.0
}
}

impl RngCore for ClientRng {
fn next_u32(&mut self) -> u32 {
self.0.next_u32()
}

fn next_u64(&mut self) -> u64 {
self.0.next_u64()
}

fn fill_bytes(&mut self, dest: &mut [u8]) {
self.0.fill_bytes(dest);
}
}

impl FeltRng for ClientRng {
fn draw_element(&mut self) -> Felt {
self.0.draw_element()
}

fn draw_word(&mut self) -> Word {
self.0.draw_word()
}
}
5 changes: 2 additions & 3 deletions crates/rust-client/src/test_utils/common.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::{
boxed::Box,
env::temp_dir,
fs::OpenOptions,
io::Write,
Expand All @@ -19,7 +18,7 @@ use miden_objects::{
note::{NoteId, NoteType},
transaction::{InputNote, OutputNote, TransactionId},
};
use rand::{Rng, RngCore, rngs::StdRng};
use rand::{Rng, rngs::StdRng};
use toml::Table;
use uuid::Uuid;

Expand Down Expand Up @@ -83,7 +82,7 @@ pub async fn create_test_client_builder() -> (ClientBuilder, TestClientKeyStore)

let builder = ClientBuilder::new()
.with_rpc(Arc::new(TonicRpcClient::new(&rpc_endpoint, rpc_timeout)))
.with_rng(Box::new(rng))
.with_rng(rng)
.with_store(store)
.with_filesystem_keystore(auth_path.to_str().unwrap())
.in_debug_mode(true)
Expand Down
6 changes: 3 additions & 3 deletions crates/rust-client/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use alloc::vec::Vec;
use std::{boxed::Box, collections::BTreeSet, env::temp_dir, println, sync::Arc};
use std::{collections::BTreeSet, env::temp_dir, println, sync::Arc};

// TESTS
// ================================================================================================
Expand Down Expand Up @@ -39,7 +39,7 @@ use miden_tx::{
TransactionExecutorError,
utils::{Deserializable, Serializable},
};
use rand::{Rng, RngCore, rngs::StdRng};
use rand::{Rng, rngs::StdRng};
use uuid::Uuid;

use crate::{
Expand Down Expand Up @@ -93,7 +93,7 @@ pub async fn create_test_client_builder() -> (ClientBuilder, MockRpcApi, Filesys

let builder = ClientBuilder::new()
.with_rpc(arc_rpc_api)
.with_rng(Box::new(rng))
.with_rng(rng)
.with_store(store)
.with_filesystem_keystore(keystore_path.to_str().unwrap())
.in_debug_mode(true)
Expand Down
18 changes: 10 additions & 8 deletions crates/rust-client/src/transaction/request/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use miden_objects::{
account::AccountId,
asset::{Asset, FungibleAsset},
block::BlockNumber,
crypto::merkle::{InnerNodeInfo, MerkleStore},
crypto::{
merkle::{InnerNodeInfo, MerkleStore},
rand::FeltRng,
},
note::{Note, NoteDetails, NoteId, NoteRecipient, NoteTag, NoteType, PartialNote},
transaction::{OutputNote, TransactionScript},
vm::AdviceMap,
Expand All @@ -17,7 +20,6 @@ use super::{
ForeignAccount, NoteArgs, TransactionRequest, TransactionRequestError,
TransactionScriptTemplate,
};
use crate::ClientRng;

// TRANSACTION REQUEST BUILDER
// ================================================================================================
Expand Down Expand Up @@ -250,12 +252,12 @@ impl TransactionRequestBuilder {
/// note.
///
/// This function cannot be used with a previously set custom script.
pub fn build_mint_fungible_asset(
pub fn build_mint_fungible_asset<R: FeltRng>(
self,
asset: FungibleAsset,
target_id: AccountId,
note_type: NoteType,
rng: &mut ClientRng,
rng: &mut R,
) -> Result<TransactionRequest, TransactionRequestError> {
let created_note = create_p2id_note(
asset.faucet_id(),
Expand All @@ -281,12 +283,12 @@ impl TransactionRequestBuilder {
/// note.
///
/// This function cannot be used with a previously set custom script.
pub fn build_pay_to_id(
pub fn build_pay_to_id<R: FeltRng>(
self,
payment_data: PaymentTransactionData,
recall_height: Option<BlockNumber>,
note_type: NoteType,
rng: &mut ClientRng,
rng: &mut R,
) -> Result<TransactionRequest, TransactionRequestError> {
let PaymentTransactionData {
assets,
Expand Down Expand Up @@ -336,11 +338,11 @@ impl TransactionRequestBuilder {
/// note.
///
/// This function cannot be used with a previously set custom script.
pub fn build_swap(
pub fn build_swap<R: FeltRng>(
self,
swap_data: &SwapTransactionData,
note_type: NoteType,
rng: &mut ClientRng,
rng: &mut R,
) -> Result<TransactionRequest, TransactionRequestError> {
// The created note is the one that we need as the output of the tx, the other one is the
// one that we expect to receive and consume eventually.
Expand Down
2 changes: 1 addition & 1 deletion crates/web-client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@demox-labs/miden-sdk",
"version": "0.10.0-next.4",
"version": "0.10.0-next.5",
"description": "Miden Wasm SDK",
"collaborators": [
"Miden",
Expand Down
2 changes: 1 addition & 1 deletion crates/web-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl WebClient {

self.inner = Some(Client::new(
web_rpc_client,
Box::new(rng),
rng,
web_store.clone(),
Arc::new(keystore.clone()),
ExecutionOptions::new(
Expand Down
1 change: 0 additions & 1 deletion crates/web-client/src/new_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use miden_client::{
};
use miden_lib::account::{auth::RpoFalcon512, faucets::BasicFungibleFaucet};
use miden_objects::asset::TokenSymbol;
use rand::RngCore;
use wasm_bindgen::prelude::*;

use super::models::{
Expand Down
1 change: 0 additions & 1 deletion tests/src/network_transaction_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use miden_objects::{
account::AccountComponent,
assembly::{Assembler, DefaultSourceManager, Library, LibraryPath, Module, ModuleKind},
};
use rand::RngCore;

// HELPERS
// ================================================================================================
Expand Down
Loading