From 349c43be3975091d448833ea524b7838af6b66bb Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Fri, 25 Oct 2024 11:42:54 +0500 Subject: [PATCH] refactor: update genesis generation, read faucet account from `faucet.mac`, request faucet state on initialization --- .github/workflows/deploy_package.yml | 2 +- Cargo.lock | 1 + bin/faucet/src/client.rs | 173 ++++++++---------------- bin/faucet/src/config.rs | 23 +--- bin/faucet/src/handlers.rs | 82 +++-------- bin/faucet/src/main.rs | 13 +- bin/faucet/src/store.rs | 16 +-- bin/node/Cargo.toml | 1 + bin/node/src/commands/genesis/inputs.rs | 6 - bin/node/src/commands/genesis/mod.rs | 74 +++++----- bin/node/src/main.rs | 7 +- config/genesis.toml | 2 - config/miden-faucet.toml | 7 +- 13 files changed, 143 insertions(+), 264 deletions(-) diff --git a/.github/workflows/deploy_package.yml b/.github/workflows/deploy_package.yml index 53530896b..d2de0c2ba 100644 --- a/.github/workflows/deploy_package.yml +++ b/.github/workflows/deploy_package.yml @@ -117,7 +117,7 @@ jobs: sudo chown -R miden /opt/miden; \ sudo /usr/bin/miden-node init -c /etc/miden/miden-node.toml -g /opt/miden/miden-node/genesis.toml; \ sudo /usr/bin/miden-node make-genesis -i /opt/miden/miden-node/genesis.toml -o /opt/miden/miden-node/genesis.dat --force; \ - sudo /usr/bin/miden-faucet init -c /opt/miden/miden-faucet/miden-faucet.toml + sudo /usr/bin/miden-faucet init -c /opt/miden/miden-faucet/miden-faucet.toml -f /opt/miden/miden-node/accounts/faucet.mac - name: Start miden node service uses: ./.github/actions/ssm_execute diff --git a/Cargo.lock b/Cargo.lock index 5a290bb69..3dfab751b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1566,6 +1566,7 @@ dependencies = [ "miden-node-store", "miden-node-utils", "miden-objects", + "rand", "rand_chacha", "serde", "tokio", diff --git a/bin/faucet/src/client.rs b/bin/faucet/src/client.rs index 36367b3a0..4682bba91 100644 --- a/bin/faucet/src/client.rs +++ b/bin/faucet/src/client.rs @@ -1,15 +1,7 @@ -use std::{ - path::Path, - rc::Rc, - sync::{Arc, RwLock}, - time::Duration, -}; +use std::{rc::Rc, time::Duration}; -use anyhow::{anyhow, Context}; -use miden_lib::{ - accounts::faucets::create_basic_fungible_faucet, notes::create_p2id_note, - transaction::TransactionKernel, AuthScheme, -}; +use anyhow::Context; +use miden_lib::{notes::create_p2id_note, transaction::TransactionKernel}; use miden_node_proto::generated::{ requests::{ GetAccountDetailsRequest, GetBlockHeaderByNumberRequest, SubmitProvenTransactionRequest, @@ -17,10 +9,9 @@ use miden_node_proto::generated::{ rpc::api_client::ApiClient, }; use miden_objects::{ - accounts::{Account, AccountId, AccountStorageMode, AuthSecretKey}, - assets::{FungibleAsset, TokenSymbol}, + accounts::{Account, AccountData, AccountId, AuthSecretKey}, + assets::FungibleAsset, crypto::{ - dsa::rpo_falcon512::SecretKey, merkle::{MmrPeaks, PartialMmr}, rand::RpoRandomCoin, }, @@ -28,20 +19,21 @@ use miden_objects::{ transaction::{ChainMmr, ExecutedTransaction, TransactionArgs, TransactionScript}, utils::Deserializable, vm::AdviceMap, - BlockHeader, Felt, Word, + BlockHeader, Felt, }; use miden_tx::{ auth::BasicAuthenticator, utils::Serializable, LocalTransactionProver, ProvingOptions, TransactionExecutor, TransactionProver, }; -use rand::{rngs::StdRng, thread_rng, Rng}; -use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; +use rand::{random, rngs::StdRng}; use tonic::transport::Channel; +use tracing::info; use crate::{ config::FaucetConfig, errors::{ClientError, ImplError}, store::FaucetDataStore, + COMPONENT, }; pub const DISTRIBUTE_FUNGIBLE_ASSET_SCRIPT: &str = @@ -65,25 +57,36 @@ unsafe impl Send for FaucetClient {} impl FaucetClient { /// Creates a new faucet client. pub async fn new(config: &FaucetConfig) -> Result { - let (rpc_api, root_block_header, root_chain_mmr) = initialize_faucet_client(config).await?; - let init_seed: [u8; 32] = [0; 32]; - let (auth_scheme, authenticator) = init_authenticator(init_seed, &config.secret_key_path) - .context("Failed to initialize authentication scheme")?; - - let (faucet_account, account_seed) = build_account(config, init_seed, auth_scheme)?; - let id = faucet_account.id(); - - let data_store = FaucetDataStore::new( - Arc::new(RwLock::new(faucet_account)), - account_seed, - root_block_header, - root_chain_mmr, + let (mut rpc_api, root_block_header, root_chain_mmr) = + initialize_faucet_client(config).await?; + + let faucet_account_data = AccountData::read(&config.faucet_account_path) + .context("Failed to load faucet account from file")?; + + let id = faucet_account_data.account.id(); + + let public_key = match &faucet_account_data.auth_secret_key { + AuthSecretKey::RpoFalcon512(secret) => secret.public_key(), + }; + + let authenticator = BasicAuthenticator::::new(&[( + public_key.into(), + faucet_account_data.auth_secret_key, + )]); + + info!(target: COMPONENT, "Requesting account state from the node..."); + let faucet_account = request_account_state(&mut rpc_api, id).await?; + info!( + target: COMPONENT, + got_new_hash = %faucet_account.hash(), + "Received faucet account state from the node", ); + let data_store = FaucetDataStore::new(faucet_account, root_block_header, root_chain_mmr); + let executor = TransactionExecutor::new(data_store.clone(), Some(Rc::new(authenticator))); - let mut rng = thread_rng(); - let coin_seed: [u64; 4] = rng.gen(); + let coin_seed: [u64; 4] = random(); let rng = RpoRandomCoin::new(coin_seed.map(Felt::new)); Ok(Self { data_store, rpc_api, executor, id, rng }) @@ -155,29 +158,6 @@ impl FaucetClient { Ok(response.into_inner().block_height) } - /// Requests faucet account state from the node. - /// - /// The account is expected to be public, otherwise, the error is returned. - pub async fn request_account_state(&mut self) -> Result<(Account, u32), ClientError> { - let account_info = self - .rpc_api - .get_account_details(GetAccountDetailsRequest { account_id: Some(self.id.into()) }) - .await - .context("Failed to get faucet account state")? - .into_inner() - .details - .context("Account info field is empty")?; - - let faucet_account_state_bytes = - account_info.details.context("Account details field is empty")?; - let faucet_account = Account::read_from_bytes(&faucet_account_state_bytes) - .map_err(ImplError) - .context("Failed to deserialize faucet account")?; - let block_num = account_info.summary.context("Account summary field is empty")?.block_num; - - Ok((faucet_account, block_num)) - } - /// Returns a reference to the data store. pub fn data_store(&self) -> &FaucetDataStore { &self.data_store @@ -192,65 +172,6 @@ impl FaucetClient { // HELPER FUNCTIONS // ================================================================================================ -/// Initializes the keypair used to sign transactions. -/// -/// If the secret key file exists, it is read from the file. Otherwise, a new key is generated and -/// written to the file. -fn init_authenticator( - init_seed: [u8; 32], - secret_key_path: impl AsRef, -) -> Result<(AuthScheme, BasicAuthenticator), ClientError> { - // Load secret key from file or generate new one - let secret = if secret_key_path.as_ref().exists() { - SecretKey::read_from_bytes( - &std::fs::read(secret_key_path).context("Failed to read secret key from file")?, - ) - .map_err(ImplError) - .context("Failed to deserialize secret key")? - } else { - let mut rng = ChaCha20Rng::from_seed(init_seed); - let secret = SecretKey::with_rng(&mut rng); - std::fs::write(secret_key_path, secret.to_bytes()) - .context("Failed to write secret key to file")?; - - secret - }; - - let auth_scheme = AuthScheme::RpoFalcon512 { pub_key: secret.public_key() }; - - let authenticator = BasicAuthenticator::::new(&[( - secret.public_key().into(), - AuthSecretKey::RpoFalcon512(secret), - )]); - - Ok((auth_scheme, authenticator)) -} - -/// Builds a new faucet account with the provided configuration. -/// -/// Returns the created account, its seed, and the secret key used to sign transactions. -fn build_account( - config: &FaucetConfig, - init_seed: [u8; 32], - auth_scheme: AuthScheme, -) -> Result<(Account, Word), ClientError> { - let token_symbol = TokenSymbol::new(config.token_symbol.as_str()) - .context("Failed to parse token symbol from configuration file")?; - - let (faucet_account, account_seed) = create_basic_fungible_faucet( - init_seed, - token_symbol, - config.decimals, - Felt::try_from(config.max_supply) - .map_err(|err| anyhow!("Error converting max supply to Felt: {err}"))?, - AccountStorageMode::Public, - auth_scheme, - ) - .context("Failed to create basic fungible faucet account")?; - - Ok((faucet_account, account_seed)) -} - /// Initializes the faucet client by connecting to the node and fetching the root block header. pub async fn initialize_faucet_client( config: &FaucetConfig, @@ -288,6 +209,30 @@ pub async fn initialize_faucet_client( Ok((rpc_api, root_block_header, root_chain_mmr)) } +/// Requests account state from the node. +/// +/// The account is expected to be public, otherwise, the error is returned. +async fn request_account_state( + rpc_api: &mut ApiClient, + account_id: AccountId, +) -> Result { + let account_info = rpc_api + .get_account_details(GetAccountDetailsRequest { account_id: Some(account_id.into()) }) + .await + .context("Failed to get faucet account state")? + .into_inner() + .details + .context("Account info field is empty")?; + + let faucet_account_state_bytes = + account_info.details.context("Account details field is empty")?; + + Account::read_from_bytes(&faucet_account_state_bytes) + .map_err(ImplError) + .context("Failed to deserialize faucet account") + .map_err(Into::into) +} + /// Builds transaction arguments for the mint transaction. fn build_transaction_arguments( output_note: &Note, diff --git a/bin/faucet/src/config.rs b/bin/faucet/src/config.rs index 631f1df90..1fb8947a0 100644 --- a/bin/faucet/src/config.rs +++ b/bin/faucet/src/config.rs @@ -9,8 +9,8 @@ use serde::{Deserialize, Serialize}; // Faucet config // ================================================================================================ -/// Default path to the secret key file -const DEFAULT_SECRET_KEY_PATH: &str = "faucet-secret.key"; +/// Default path to the faucet account file +pub const DEFAULT_FAUCET_ACCOUNT_PATH: &str = "accounts/faucet.mac"; #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Serialize, Deserialize)] #[serde(deny_unknown_fields)] @@ -23,21 +23,15 @@ pub struct FaucetConfig { pub timeout_ms: u64, /// Possible options on the amount of asset that should be dispersed on each faucet request pub asset_amount_options: Vec, - /// Token symbol of the generated fungible asset - pub token_symbol: String, - /// Number of decimals of the generated fungible asset - pub decimals: u8, - /// Maximum supply of the generated fungible asset - pub max_supply: u64, - /// Path to the key store file - pub secret_key_path: PathBuf, + /// Path to the faucet account file + pub faucet_account_path: PathBuf, } impl Display for FaucetConfig { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_fmt(format_args!( - "{{ endpoint: \"{}\", asset_amount_options: {:?}, token_symbol: {}, decimals: {}, max_supply: {} }}", - self.endpoint, self.asset_amount_options, self.token_symbol, self.decimals, self.max_supply + "{{ endpoint: \"{}\", node_url: \"{}\", timeout_ms: \"{}\", asset_amount_options: {:?}, faucet_account_path: \"{}\" }}", + self.endpoint, self.node_url, self.timeout_ms, self.asset_amount_options, self.faucet_account_path.display() )) } } @@ -49,10 +43,7 @@ impl Default for FaucetConfig { node_url: Endpoint::localhost(DEFAULT_NODE_RPC_PORT).to_string(), timeout_ms: 10000, asset_amount_options: vec![100, 500, 1000], - token_symbol: "POL".to_string(), - decimals: 8, - max_supply: 1000000, - secret_key_path: DEFAULT_SECRET_KEY_PATH.into(), + faucet_account_path: DEFAULT_FAUCET_ACCOUNT_PATH.into(), } } } diff --git a/bin/faucet/src/handlers.rs b/bin/faucet/src/handlers.rs index 5b4ddd97b..764f997d6 100644 --- a/bin/faucet/src/handlers.rs +++ b/bin/faucet/src/handlers.rs @@ -14,7 +14,7 @@ use miden_objects::{ }; use serde::{Deserialize, Serialize}; use tonic::body; -use tracing::{error, info}; +use tracing::info; use crate::{errors::HandlerError, state::FaucetState, COMPONENT}; @@ -65,67 +65,25 @@ pub async fn get_tokens( let target_account_id = AccountId::from_hex(req.account_id.as_str()) .map_err(|err| HandlerError::BadRequest(err.to_string()))?; - let (created_note, block_height) = loop { - let mut faucet_account = client.data_store().faucet_account(); - - // Execute transaction - info!(target: COMPONENT, "Executing mint transaction for account."); - let (executed_tx, created_note) = client.execute_mint_transaction( - target_account_id, - req.is_private_note, - req.asset_amount, - )?; - - let prev_hash = faucet_account.hash(); - - faucet_account - .apply_delta(executed_tx.account_delta()) - .context("Failed to apply faucet account delta")?; - - let new_hash = faucet_account.hash(); - - // Run transaction prover & send transaction to node - info!(target: COMPONENT, "Proving and submitting transaction."); - match client.prove_and_submit_transaction(executed_tx.clone()).await { - Ok(block_height) => { - break (created_note, block_height); - }, - Err(err) => { - error!( - target: COMPONENT, - %err, - "Failed to prove and submit transaction", - ); - - // TODO: Improve error statuses returned from the `SubmitProvenTransaction` endpoint - // of block producer. Check received error status here. - - info!(target: COMPONENT, "Requesting account state from the node..."); - let (got_faucet_account, block_num) = client.request_account_state().await?; - let got_new_hash = got_faucet_account.hash(); - info!( - target: COMPONENT, - %prev_hash, - %new_hash, - %got_new_hash, - "Received new account state from the node", - ); - // If the hash hasn't changed, then the account's state we had is correct, - // and we should not try to execute the transaction again. We can just return error - // to the caller. - if new_hash == prev_hash { - return Err(err.into()); - } - // If the new hash from the node is the same, as we expected to have, then - // transaction was successfully executed despite the error. Don't need to retry. - if new_hash == got_new_hash { - break (created_note, block_num); - } - - client.data_store().update_faucet_state(got_faucet_account).await?; - }, - } - }; + // Execute transaction + info!(target: COMPONENT, "Executing mint transaction for account."); + let (executed_tx, created_note) = client.execute_mint_transaction( + target_account_id, + req.is_private_note, + req.asset_amount, + )?; + + let mut faucet_account = client.data_store().faucet_account(); + faucet_account + .apply_delta(executed_tx.account_delta()) + .context("Failed to apply faucet account delta")?; + + // Run transaction prover & send transaction to node + info!(target: COMPONENT, "Proving and submitting transaction."); + let block_height = client.prove_and_submit_transaction(executed_tx).await?; + + // Update data store with the new faucet state + client.data_store().update_faucet_state(faucet_account).await?; let note_id: NoteId = created_note.id(); let note_details = diff --git a/bin/faucet/src/main.rs b/bin/faucet/src/main.rs index 2188d4c55..72e8f3ded 100644 --- a/bin/faucet/src/main.rs +++ b/bin/faucet/src/main.rs @@ -22,7 +22,7 @@ use tower_http::{cors::CorsLayer, set_header::SetResponseHeaderLayer, trace::Tra use tracing::info; use crate::{ - config::FaucetConfig, + config::{FaucetConfig, DEFAULT_FAUCET_ACCOUNT_PATH}, handlers::{get_index, get_metadata, get_static_file, get_tokens}, }; // CONSTANTS @@ -53,6 +53,8 @@ pub enum Command { Init { #[arg(short, long, default_value = FAUCET_CONFIG_FILE_PATH)] config_path: String, + #[arg(short, long, default_value = DEFAULT_FAUCET_ACCOUNT_PATH)] + faucet_account_path: String, }, } @@ -102,12 +104,17 @@ async fn main() -> anyhow::Result<()> { axum::serve(listener, app).await.unwrap(); }, - Command::Init { config_path } => { + Command::Init { config_path, faucet_account_path } => { let current_dir = std::env::current_dir().context("failed to open current directory")?; let config_file_path = current_dir.join(config_path); - let config = FaucetConfig::default(); + + let config = FaucetConfig { + faucet_account_path: faucet_account_path.into(), + ..FaucetConfig::default() + }; + let config_as_toml_string = toml::to_string(&config).context("Failed to serialize default config")?; diff --git a/bin/faucet/src/store.rs b/bin/faucet/src/store.rs index 8b1b15ec0..9dbf22bf1 100644 --- a/bin/faucet/src/store.rs +++ b/bin/faucet/src/store.rs @@ -4,7 +4,7 @@ use miden_objects::{ accounts::{Account, AccountId}, notes::NoteId, transaction::{ChainMmr, InputNotes, TransactionInputs}, - BlockHeader, Word, + BlockHeader, }; use miden_tx::{DataStore, DataStoreError}; @@ -13,8 +13,6 @@ use crate::errors::HandlerError; #[derive(Clone)] pub struct FaucetDataStore { faucet_account: Arc>, - /// Seed used for faucet account creation. - seed: Word, block_header: BlockHeader, chain_mmr: ChainMmr, } @@ -24,14 +22,12 @@ pub struct FaucetDataStore { impl FaucetDataStore { pub fn new( - faucet_account: Arc>, - seed: Word, + faucet_account: Account, root_block_header: BlockHeader, root_chain_mmr: ChainMmr, ) -> Self { Self { - faucet_account, - seed, + faucet_account: Arc::new(RwLock::new(faucet_account)), block_header: root_block_header, chain_mmr: root_chain_mmr, } @@ -62,14 +58,12 @@ impl DataStore for FaucetDataStore { return Err(DataStoreError::AccountNotFound(account_id)); } - let empty_input_notes = InputNotes::new(vec![]).expect("Empty notes must succeed"); - TransactionInputs::new( account.clone(), - account.is_new().then_some(self.seed), + None, self.block_header, self.chain_mmr.clone(), - empty_input_notes, + InputNotes::default(), ) .map_err(DataStoreError::InvalidTransactionInput) } diff --git a/bin/node/Cargo.toml b/bin/node/Cargo.toml index d544f285f..f1f2bec92 100644 --- a/bin/node/Cargo.toml +++ b/bin/node/Cargo.toml @@ -26,6 +26,7 @@ miden-node-rpc = { workspace = true } miden-node-store = { workspace = true } miden-node-utils = { workspace = true } miden-objects = { workspace = true } +rand = "0.8" rand_chacha = "0.3" serde = { version = "1.0", features = ["derive"] } tokio = { workspace = true, features = ["rt-multi-thread", "net", "macros"] } diff --git a/bin/node/src/commands/genesis/inputs.rs b/bin/node/src/commands/genesis/inputs.rs index a400fc69f..2f93d1d60 100644 --- a/bin/node/src/commands/genesis/inputs.rs +++ b/bin/node/src/commands/genesis/inputs.rs @@ -23,9 +23,7 @@ pub enum AccountInput { #[derive(Debug, Clone, Deserialize, Serialize)] pub struct BasicFungibleFaucetInputs { - pub init_seed: String, pub auth_scheme: AuthSchemeInput, - pub auth_seed: String, pub token_symbol: String, pub decimals: u8, pub max_supply: u64, @@ -46,11 +44,7 @@ impl Default for GenesisInput { .expect("Current timestamp should be greater than unix epoch") .as_secs() as u32, accounts: Some(vec![AccountInput::BasicFungibleFaucet(BasicFungibleFaucetInputs { - init_seed: "0xc123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - .to_string(), auth_scheme: AuthSchemeInput::RpoFalcon512, - auth_seed: "0xd123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - .to_string(), token_symbol: "POL".to_string(), decimals: 12, max_supply: 1000000, diff --git a/bin/node/src/commands/genesis/mod.rs b/bin/node/src/commands/genesis/mod.rs index 3772b1201..a5ed29224 100644 --- a/bin/node/src/commands/genesis/mod.rs +++ b/bin/node/src/commands/genesis/mod.rs @@ -9,15 +9,15 @@ use miden_lib::{accounts::faucets::create_basic_fungible_faucet, AuthScheme}; use miden_node_store::genesis::GenesisState; use miden_node_utils::config::load_config; use miden_objects::{ - accounts::{Account, AccountData, AccountStorageMode, AuthSecretKey}, + accounts::{Account, AccountData, AuthSecretKey}, assets::TokenSymbol, - crypto::{ - dsa::rpo_falcon512::SecretKey, - rand::RpoRandomCoin, - utils::{hex_to_bytes, Serializable}, - }, + crypto::{dsa::rpo_falcon512::SecretKey, rand::RpoRandomCoin, utils::Serializable}, Digest, Felt, ONE, }; +use rand_chacha::{ + rand_core::{RngCore, SeedableRng}, + ChaCha20Rng, +}; use tracing::info; mod inputs; @@ -80,13 +80,9 @@ pub fn make_genesis(inputs_path: &PathBuf, output_path: &PathBuf, force: &bool) })?; info!("Genesis input file: {} has successfully been loaded.", inputs_path.display()); + let accounts_path = parent_path.join(DEFAULT_ACCOUNTS_DIR); let accounts = - create_accounts(&genesis_input.accounts.unwrap_or_default(), parent_path, force)?; - info!( - "Accounts have successfully been created at: {}/{}", - parent_path.display(), - DEFAULT_ACCOUNTS_DIR - ); + create_accounts(&genesis_input.accounts.unwrap_or_default(), &accounts_path, force)?; let genesis_state = GenesisState::new(accounts, genesis_input.version, genesis_input.timestamp); fs::write(output_path, genesis_state.to_bytes()).unwrap_or_else(|_| { @@ -102,13 +98,10 @@ pub fn make_genesis(inputs_path: &PathBuf, output_path: &PathBuf, force: &bool) /// This function also writes the account data files into the default accounts directory. fn create_accounts( accounts: &[AccountInput], - parent_path: &Path, + accounts_path: impl AsRef, force: &bool, ) -> Result> { - let mut accounts_path = PathBuf::from(&parent_path); - accounts_path.push(DEFAULT_ACCOUNTS_DIR); - - if accounts_path.try_exists()? { + if accounts_path.as_ref().try_exists()? { if !force { bail!( "Failed to create accounts directory because it already exists. \ @@ -121,19 +114,21 @@ fn create_accounts( fs::create_dir_all(&accounts_path).context("Failed to create accounts directory")?; let mut final_accounts = Vec::new(); + let mut faucet_count = 0; + let mut rng = ChaCha20Rng::from_seed(rand::random()); for account in accounts { // build offchain account data from account inputs - let mut account_data = match account { + let (mut account_data, name) = match account { AccountInput::BasicFungibleFaucet(inputs) => { info!("Creating fungible faucet account..."); - let init_seed = hex_to_bytes(&inputs.init_seed)?; - - let (auth_scheme, auth_secret_key) = - parse_auth_inputs(inputs.auth_scheme, &inputs.auth_seed)?; - - let storage_mode: AccountStorageMode = inputs.storage_mode.as_str().try_into()?; + let mut auth_seed = [0; 32]; + rng.fill_bytes(&mut auth_seed); + let (auth_scheme, auth_secret_key) = gen_auth_keys(inputs.auth_scheme, auth_seed)?; + let mut init_seed = [0; 32]; + rng.fill_bytes(&mut init_seed); + let storage_mode = inputs.storage_mode.as_str().try_into()?; let (account, account_seed) = create_basic_fungible_faucet( init_seed, TokenSymbol::try_from(inputs.token_symbol.as_str())?, @@ -144,23 +139,29 @@ fn create_accounts( auth_scheme, )?; - AccountData::new(account, Some(account_seed), auth_secret_key) + let name = if faucet_count == 0 { + "faucet".to_string() + } else { + format!("faucet{faucet_count}") + }; + faucet_count += 1; + + (AccountData::new(account, Some(account_seed), auth_secret_key), name) }, }; // write account data to file - let path = format!("{}/account{}.mac", accounts_path.display(), final_accounts.len()); - let path = Path::new(&path); + let path = accounts_path.as_ref().join(format!("{name}.mac")); - if let Ok(path_exists) = path.try_exists() { - if path_exists && !force { - bail!("Failed to generate account file {} because it already exists. Use the --force flag to overwrite.", path.display()); - } + if !force && matches!(path.try_exists(), Ok(true)) { + bail!("Failed to generate account file {} because it already exists. Use the --force flag to overwrite.", path.display()); } account_data.account.set_nonce(ONE)?; - account_data.write(path)?; + account_data.write(&path)?; + + info!("Account \"{name}\" has successfully been saved to: {}", path.display()); final_accounts.push(account_data.account); } @@ -168,13 +169,12 @@ fn create_accounts( Ok(final_accounts) } -fn parse_auth_inputs( +fn gen_auth_keys( auth_scheme_input: AuthSchemeInput, - auth_seed: &str, + auth_seed: [u8; 32], ) -> Result<(AuthScheme, AuthSecretKey)> { match auth_scheme_input { AuthSchemeInput::RpoFalcon512 => { - let auth_seed: [u8; 32] = hex_to_bytes(auth_seed)?; let rng_seed = Digest::try_from(&auth_seed)?.into(); let mut rng = RpoRandomCoin::new(rng_seed); let secret = SecretKey::with_rng(&mut rng); @@ -215,9 +215,7 @@ mod tests { [[accounts]] type = "BasicFungibleFaucet" - init_seed = "0xc123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" auth_scheme = "RpoFalcon512" - auth_seed = "0xd123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" token_symbol = "POL" decimals = 12 max_supply = 1000000 @@ -230,7 +228,7 @@ mod tests { // run make_genesis to generate genesis.dat and accounts folder and files make_genesis(&genesis_inputs_file_path, &genesis_dat_file_path, &true).unwrap(); - let a0_file_path = PathBuf::from("accounts/account0.mac"); + let a0_file_path = PathBuf::from("accounts/faucet.mac"); // assert that the genesis.dat and account files exist assert!(genesis_dat_file_path.exists()); diff --git a/bin/node/src/main.rs b/bin/node/src/main.rs index 1ce93c60b..1839d7484 100644 --- a/bin/node/src/main.rs +++ b/bin/node/src/main.rs @@ -127,11 +127,8 @@ async fn main() -> anyhow::Result<()> { let current_dir = std::env::current_dir() .map_err(|err| anyhow!("failed to open current directory: {err}"))?; - let mut config = current_dir.clone(); - let mut genesis = current_dir.clone(); - - config.push(config_path); - genesis.push(genesis_path); + let config = current_dir.join(config_path); + let genesis = current_dir.join(genesis_path); init_config_files(config, genesis) }, diff --git a/config/genesis.toml b/config/genesis.toml index 6a77d9a77..8c74a4dd3 100644 --- a/config/genesis.toml +++ b/config/genesis.toml @@ -5,9 +5,7 @@ timestamp = 1672531200 [[accounts]] type = "BasicFungibleFaucet" storage_mode = "public" -init_seed = "0xc123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" auth_scheme = "RpoFalcon512" -auth_seed = "0xd123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" token_symbol = "POL" decimals = 12 max_supply = 1000000 diff --git a/config/miden-faucet.toml b/config/miden-faucet.toml index 688e2ac48..8124e33db 100644 --- a/config/miden-faucet.toml +++ b/config/miden-faucet.toml @@ -1,10 +1,5 @@ endpoint = { host = "localhost", port = 8080 } node_url = "http://localhost:57291" timeout_ms = 10000 -secret_key_path = "faucet-secret.key" - -# Data used to construct the faucet account of the faucet asset_amount_options = [100, 500, 1000] -token_symbol = "POL" -decimals = 8 -max_supply = 1000000 +faucet_account_path = "accounts/faucet.mac"