Skip to content
Open
Show file tree
Hide file tree
Changes from 7 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
42 changes: 20 additions & 22 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 @@ -84,6 +89,15 @@ impl Default for ClientBuilder {
}
}

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

impl ClientBuilder {
/// Create a new `ClientBuilder` with default settings.
#[must_use]
Expand Down Expand Up @@ -128,13 +142,6 @@ impl ClientBuilder {
self
}

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

/// Optionally provide a custom authenticator instance.
#[must_use]
pub fn with_authenticator(mut self, authenticator: Arc<dyn TransactionAuthenticator>) -> Self {
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
Loading