diff --git a/Cargo.lock b/Cargo.lock index 281161061a7..5a0db5ce620 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1007,6 +1007,7 @@ dependencies = [ "tower-http", "tracing", "tracing-subscriber", + "url", ] [[package]] diff --git a/devimint/Cargo.toml b/devimint/Cargo.toml index 5ca5eddb24e..5639c115e11 100644 --- a/devimint/Cargo.toml +++ b/devimint/Cargo.toml @@ -37,3 +37,4 @@ tower-http = { version = "0.3.5", features = ["cors", "auth"] } tracing = "0.1.37" tracing-subscriber = "0.3.16" serde = "1.0.159" +url = "2.3.1" diff --git a/devimint/src/bin/faucet.rs b/devimint/src/bin/faucet.rs index e89b894541a..650f97ad8d1 100644 --- a/devimint/src/bin/faucet.rs +++ b/devimint/src/bin/faucet.rs @@ -1,5 +1,7 @@ +use std::path::PathBuf; use std::sync::Arc; +use anyhow::Context; use axum::extract::State; use axum::http::StatusCode; use axum::routing::{get, post}; @@ -20,7 +22,7 @@ struct Cmd { #[clap(long, env = "FM_CLN_SOCKET")] cln_socket: String, #[clap(long, env = "FM_CONNECT_STRING")] - connect_string: String, + connect_string: Option, } #[derive(Clone)] @@ -35,7 +37,11 @@ impl Faucet { let url = cmd.bitcoind_rpc.parse()?; let (host, auth) = fedimint_bitcoind::bitcoincore::from_url_to_url_auth(&url)?; let bitcoin = Arc::new(bitcoincore_rpc::Client::new(&host, auth)?); - let ln_rpc = Arc::new(Mutex::new(ClnRpc::new(&cmd.cln_socket).await?)); + let ln_rpc = Arc::new(Mutex::new( + ClnRpc::new(&cmd.cln_socket) + .await + .with_context(|| format!("couldn't open CLN socket {}", &cmd.cln_socket))?, + )); Ok(Faucet { bitcoin, ln_rpc }) } @@ -97,7 +103,13 @@ async fn main() -> anyhow::Result<()> { let router = Router::new() .route( "/connect-string", - get(|| async move { cmd.connect_string.clone() }), + get(|| async move { + cmd.connect_string.unwrap_or_else(|| { + // return error if not set + let data_dir = std::env::var("FM_DATA_DIR").unwrap(); + std::fs::read_to_string(PathBuf::from(data_dir).join("client-connect")).unwrap() + }) + }), ) .route( "/pay", diff --git a/devimint/src/federation.rs b/devimint/src/federation.rs index e5a3dbb3549..434b41735ce 100644 --- a/devimint/src/federation.rs +++ b/devimint/src/federation.rs @@ -1,26 +1,28 @@ -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashSet}; use anyhow::{anyhow, Context}; use bitcoincore_rpc::bitcoin::Network; -use fedimint_aead::random_salt; +use fedimint_core::admin_client::{ConfigGenConnectionsRequest, ConfigGenParamsRequest}; +use fedimint_core::api::ServerStatus; use fedimint_core::bitcoinrpc::BitcoinRpcConfig; +use fedimint_core::config::ServerModuleGenParamsRegistry; use fedimint_core::core::LEGACY_HARDCODED_INSTANCE_ID_WALLET; use fedimint_core::db::mem_impl::MemDatabase; -use fedimint_core::util::write_new; +use fedimint_core::module::ApiAuth; use fedimint_core::{Amount, PeerId}; -use fedimint_server::config::io::{write_server_config, PLAINTEXT_PASSWORD, SALT_FILE}; -use fedimint_server::config::ServerConfig; +use fedimint_server::config::ConfigGenParams; use fedimint_testing::federation::local_config_gen_params; use fedimint_wallet_client::config::WalletClientConfig; use fedimintd::attach_default_module_gen_params; use fedimintd::fedimintd::Fedimintd as FedimintBuilder; -use tokio::fs; +use futures::future::join_all; +use rand::Rng; +use url::Url; use super::*; // TODO: remove this pub struct Federation { // client is only for internal use, use cli commands instead - client: Arc, members: BTreeMap, vars: BTreeMap, bitcoind: Bitcoind, @@ -30,16 +32,59 @@ impl Federation { pub async fn new( process_mgr: &ProcessManager, bitcoind: Bitcoind, - vars: BTreeMap, + servers: usize, + // vars: BTreeMap, ) -> Result { let mut members = BTreeMap::new(); - for (peer, var) in &vars { + let mut vars = BTreeMap::new(); + + // FIXME: this is a hack to pass fed.server_gen_params in + // local_config_gen_params call below + let fed = FedimintBuilder::new()?.with_default_modules(); + let peers: Vec<_> = (0..servers).map(|id| PeerId::from(id as u16)).collect(); + let params: HashMap = + local_config_gen_params(&peers, BASE_PORT, fed.server_gen_params.clone())?; + + let mut admin_clients: BTreeMap = BTreeMap::new(); + for (peer, peer_params) in ¶ms { + // FIXME: we should do this inside + let var = vars::Fedimintd::init(&process_mgr.globals, peer_params.to_owned()).await?; members.insert( - *peer, - Fedimintd::new(process_mgr, bitcoind.clone(), *peer, var).await?, + peer.to_usize(), + Fedimintd::new(process_mgr, bitcoind.clone(), peer.to_usize(), &var).await?, ); + let admin_client = WsAdminClient::new(Url::parse(&var.FM_API_URL)?); + admin_clients.insert(*peer, admin_client); + vars.insert(peer.to_usize(), var); } + run_dkg(admin_clients, params).await?; + + let out_dir = &vars[&0].FM_DATA_DIR; + let cfg_dir = &process_mgr.globals.FM_DATA_DIR; + let out_dir = utf8(out_dir); + let cfg_dir = utf8(cfg_dir); + // copy configs to config directory + tokio::fs::rename( + format!("{out_dir}/client-connect"), + format!("{cfg_dir}/client-connect"), + ) + .await?; + tokio::fs::rename( + format!("{out_dir}/client.json"), + format!("{cfg_dir}/client.json"), + ) + .await?; + info!("copied client configs"); + + Ok(Self { + members, + vars, + bitcoind, + }) + } + + pub async fn client(&self) -> Result { let workdir: PathBuf = env::var("FM_DATA_DIR")?.parse()?; let cfg_path = workdir.join("client.json"); let mut cfg: UserClientConfig = load_from_file(&cfg_path)?; @@ -52,12 +97,7 @@ impl Federation { DynClientModuleGen::from(LightningClientGen), ]); let client = UserClient::new(cfg, decoders, module_gens, db, Default::default()).await; - Ok(Self { - members, - vars, - bitcoind, - client: Arc::new(client), - }) + Ok(client) } pub async fn start_server(&mut self, process_mgr: &ProcessManager, peer: usize) -> Result<()> { @@ -124,12 +164,18 @@ impl Federation { } pub async fn federation_id(&self) -> String { - self.client.config().0.federation_id.to_string() + self.client() + .await + .unwrap() + .config() + .0 + .federation_id + .to_string() } pub async fn await_block_sync(&self) -> Result<()> { - let wallet_cfg: &WalletClientConfig = self - .client + let client = self.client().await?; + let wallet_cfg: &WalletClientConfig = client .config_ref() .0 .get_module(LEGACY_HARDCODED_INSTANCE_ID_WALLET)?; @@ -229,56 +275,204 @@ impl Fedimintd { /// Base port for devimint const BASE_PORT: u16 = 8173 + 10000; -pub async fn run_config_gen( - process_mgr: &ProcessManager, - servers: usize, - write_password: bool, -) -> Result> { +pub async fn run_dkg( + admin_clients: BTreeMap, + params: HashMap, +) -> anyhow::Result<()> { + let auth_for = |peer: &PeerId| -> ApiAuth { params[peer].local.api_auth.clone() }; + for (peer_id, client) in &admin_clients { + loop { + if client.status().await.is_ok() { + info!("Connected to {peer_id}"); + break; + } else { + info!("Waiting for {peer_id} to start..."); + fedimint_core::task::sleep(Duration::from_secs(1)).await; + } + } + } + for (peer_id, client) in &admin_clients { + assert_eq!( + client.status().await?.server, + fedimint_core::api::ServerStatus::AwaitingPassword, + "peer_id isn't waiting for password: {peer_id}" + ); + } + + for (peer_id, client) in &admin_clients { + client.set_password(auth_for(peer_id)).await?; + } + let (leader_id, leader) = admin_clients.iter().next().context("missing peer")?; + let followers = admin_clients + .iter() + .filter(|(id, _)| *id != leader_id) + .collect::>(); + + let leader_name = "leader".to_string(); + leader + .set_config_gen_connections( + ConfigGenConnectionsRequest { + our_name: leader_name.clone(), + leader_api_url: None, + }, + auth_for(leader_id), + ) + .await?; + + let _ = leader + .get_default_config_gen_params(auth_for(leader_id)) + .await?; // sanity check + let server_gen_params = params[leader_id].consensus.modules.clone(); + set_config_gen_params(leader, auth_for(leader_id), server_gen_params.clone()).await?; + let followers_names = followers + .keys() + .map(|peer_id| { + (*peer_id, { + // This is to be clear that the name will be unrelated to peer id + let random_string = rand::thread_rng() + .sample_iter(&rand::distributions::Alphanumeric) + .take(5) + .map(char::from) + .collect::(); + format!("random-{random_string}{peer_id}") + }) + }) + .collect::>(); + for (peer_id, client) in &followers { + let name = followers_names + .get(peer_id) + .context("missing follower name")?; + info!("calling set_config_gen_connections for {peer_id} {name}"); + client + .set_config_gen_connections( + ConfigGenConnectionsRequest { + our_name: name.clone(), + leader_api_url: Some(leader.url.clone()), + }, + auth_for(peer_id), + ) + .await?; + set_config_gen_params(client, auth_for(peer_id), server_gen_params.clone()).await?; + } + let found_names = leader + .get_config_gen_peers() + .await? + .into_iter() + .map(|peer| peer.name) + .collect::>(); + let all_names = { + let mut names = followers_names + .values() + .into_iter() + .cloned() + .collect::>(); + names.insert(leader_name); + names + }; + assert_eq!(found_names, all_names); + wait_server_status(leader, ServerStatus::SharingConfigGenParams).await?; + + let mut configs = vec![]; + for client in admin_clients.values() { + configs.push(client.get_consensus_config_gen_params().await?); + } + // Confirm all consensus configs are the same + let mut consensus: Vec<_> = configs.iter().map(|p| p.consensus.clone()).collect(); + consensus.dedup(); + assert_eq!(consensus.len(), 1); + // Confirm all peer ids are unique + let ids = configs + .iter() + .map(|p| p.our_current_id) + .collect::>(); + assert_eq!(ids.len(), admin_clients.len()); + let dkg_results = admin_clients + .iter() + .map(|(peer_id, client)| client.run_dkg(auth_for(peer_id))); + info!("Running DKG..."); + let (dkg_results, leader_wait_result) = tokio::join!( + join_all(dkg_results), + wait_server_status(leader, ServerStatus::ReadyForConfigGen) + ); + for result in dkg_results { + result?; + } + leader_wait_result?; + + // verify config hashes equal for all peers + let mut hashes = HashSet::new(); + for (peer_id, client) in &admin_clients { + wait_server_status(client, ServerStatus::VerifyingConfigs).await?; + hashes.insert(client.get_verify_config_hash(auth_for(peer_id)).await?); + } + assert_eq!(hashes.len(), 1); + // TODO: verify something else about config? + info!("DKG successfully complete. Starting consensus..."); + for (peer_id, client) in &admin_clients { + if let Err(e) = client.start_consensus(auth_for(peer_id)).await { + tracing::info!("Error calling start_consensus: {e:?}, trying to continue...") + } + const RETRIES: usize = 20; + for i in 0..RETRIES { + let status = client.status().await; + match status { + Ok(status) => { + let server_status = status.server; + if server_status == ServerStatus::ConsensusRunning { + break; + } else { + tracing::info!( + "Waiting for status {:?}, got {server_status:?} ({i}/{RETRIES})", + ServerStatus::ConsensusRunning + ); + fedimint_core::task::sleep(Duration::from_secs(1)).await; + } + } + Err(e) => { + tracing::info!("Error calling status: {e:?}, will retry... ({i}/{RETRIES})"); + fedimint_core::task::sleep(Duration::from_secs(1)).await; + } + } + } + } + info!("Consensus is running"); + Ok(()) +} + +async fn set_config_gen_params( + client: &WsAdminClient, + auth: ApiAuth, + mut server_gen_params: ServerModuleGenParamsRegistry, +) -> anyhow::Result<()> { + // let mut modules = ServerModuleGenParamsRegistry::default(); // TODO: Use proper builder - let mut fed = FedimintBuilder::new()?.with_default_modules(); attach_default_module_gen_params( BitcoinRpcConfig::from_env_vars()?, - &mut fed.server_gen_params, + &mut server_gen_params, Amount::from_sats(100_000_000), Network::Regtest, 10, ); + let request = ConfigGenParamsRequest { + meta: BTreeMap::from([("test".to_string(), "testvalue".to_string())]), + modules: server_gen_params, + }; + client.set_config_gen_params(request, auth.clone()).await?; + Ok(()) +} - let peers: Vec<_> = (0..servers).map(|id| PeerId::from(id as u16)).collect(); - let params = local_config_gen_params(&peers, BASE_PORT, fed.server_gen_params.clone())?; - let configs = ServerConfig::trusted_dealer_gen(¶ms, fed.server_gens.clone()); - let mut fedimintd_envs = BTreeMap::new(); - for (peer, cfg) in configs { - let bind_metrics_api = format!("127.0.0.1:{}", 3510 + peer.to_usize()); - let envs = vars::Fedimintd::init(&process_mgr.globals, &cfg, bind_metrics_api).await?; - let password = cfg.private.api_auth.0.clone(); - let data_dir = envs.FM_DATA_DIR.clone(); - fedimintd_envs.insert(peer.to_usize(), envs); - write_new(data_dir.join(SALT_FILE), random_salt())?; - write_server_config(&cfg, data_dir.clone(), &password, &fed.server_gens)?; - if write_password { - write_new(data_dir.join(PLAINTEXT_PASSWORD), &password)?; +async fn wait_server_status( + client: &WsAdminClient, + expected_status: ServerStatus, +) -> anyhow::Result<()> { + loop { + let server_status = client.status().await?.server; + if server_status == expected_status { + break; + } else { + tracing::debug!("Waiting for status {expected_status:?}, got {server_status:?}"); + fedimint_core::task::sleep(Duration::from_secs(1)).await; } } - - let out_dir = &fedimintd_envs[&0].FM_DATA_DIR; - let cfg_dir = &process_mgr.globals.FM_DATA_DIR; - let out_dir = utf8(out_dir); - let cfg_dir = utf8(cfg_dir); - // copy configs to config directory - fs::rename( - format!("{out_dir}/client-connect"), - format!("{cfg_dir}/client-connect"), - ) - .await?; - fs::rename( - format!("{out_dir}/client.json"), - format!("{cfg_dir}/client.json"), - ) - .await?; - info!("copied client configs"); - - info!("DKG complete"); - - Ok(fedimintd_envs) + Ok(()) } diff --git a/devimint/src/lib.rs b/devimint/src/lib.rs index 7b87275a0ec..104185c3580 100644 --- a/devimint/src/lib.rs +++ b/devimint/src/lib.rs @@ -7,16 +7,16 @@ use std::time::Duration; use anyhow::{Context, Result}; use bitcoincore_rpc::RpcApi; -use federation::{run_config_gen, Federation}; +use federation::Federation; use fedimint_client::module::gen::{ClientModuleGenRegistry, DynClientModuleGen}; use fedimint_client_legacy::modules::mint::MintClientGen; use fedimint_client_legacy::{module_decode_stubs, UserClient, UserClientConfig}; +use fedimint_core::admin_client::WsAdminClient; use fedimint_core::config::load_from_file; use fedimint_core::db::Database; use fedimint_ln_client::LightningClientGen; use fedimint_logging::LOG_DEVIMINT; use fedimint_wallet_client::WalletClientGen; -use tokio::fs; use tracing::info; pub mod util; @@ -170,16 +170,8 @@ pub struct Faucet { impl Faucet { pub async fn new(process_mgr: &ProcessManager) -> Result { - let connect_string = - fs::read_to_string(process_mgr.globals.FM_DATA_DIR.join("client-connect")).await?; - Ok(Self { - _process: process_mgr - .spawn_daemon( - "faucet", - cmd!("faucet", "--connect-string={connect_string}"), - ) - .await?, + _process: process_mgr.spawn_daemon("faucet", cmd!("faucet")).await?, }) } } @@ -207,9 +199,7 @@ pub async fn dev_fed(process_mgr: &ProcessManager) -> Result { Esplora::new(process_mgr, bitcoind.clone()), async { let fed_size = process_mgr.globals.FM_FED_SIZE; - let members = run_config_gen(process_mgr, fed_size, true).await?; - info!(LOG_DEVIMINT, "config gen done"); - Federation::new(process_mgr, bitcoind.clone(), members).await + Federation::new(process_mgr, bitcoind.clone(), fed_size).await }, )?; info!(LOG_DEVIMINT, "federation and gateways started"); diff --git a/devimint/src/main.rs b/devimint/src/main.rs index 64bcdb62f78..f51c1a1fcc5 100644 --- a/devimint/src/main.rs +++ b/devimint/src/main.rs @@ -152,7 +152,7 @@ async fn cli_tests(dev_fed: DevFed) -> Result<()> { "--in-file={data_dir}/server-0/private.encrypt", "--out-file={data_dir}/server-0/config-plaintext.json" ) - .env("FM_PASSWORD", "pass0") + .env("FM_PASSWORD", "pass") .run() .await?; @@ -181,13 +181,13 @@ async fn cli_tests(dev_fed: DevFed) -> Result<()> { // Test load last epoch with admin client info!("Testing load last epoch with admin client"); let epoch_json = cmd!(fed, "admin", "last-epoch") - .env("FM_PASSWORD", "pass0") + .env("FM_PASSWORD", "pass") .env("FM_OUR_ID", "0") .out_json() .await?; let epoch_hex = epoch_json["hex_outcome"].as_str().unwrap(); let _force_epoch = cmd!(fed, "admin", "force-epoch", epoch_hex) - .env("FM_PASSWORD", "pass0") + .env("FM_PASSWORD", "pass") .env("FM_OUR_ID", "0") .out_json() .await?; @@ -1119,8 +1119,7 @@ async fn setup(arg: CommonArgs) -> Result<(ProcessManager, TaskGroup)> { Ok((process_mgr, task_group)) } -#[tokio::main] -async fn main() -> Result<()> { +async fn handle_command() -> Result<()> { let args = Args::parse(); match args.command { Cmd::ExternalDaemons => { @@ -1175,6 +1174,18 @@ async fn main() -> Result<()> { Ok(()) } +#[tokio::main] +async fn main() -> Result<()> { + let ready_file = PathBuf::from(env::var("FM_TEST_DIR")?).join("ready"); + match handle_command().await { + Ok(r) => Ok(r), + Err(e) => { + write_overwrite_async(ready_file, "ERROR").await?; + Err(e) + } + } +} + async fn rpc_command(rpc: RpcCmd, common: CommonArgs) -> Result<()> { fedimint_logging::TracingSetup::default().init()?; match rpc { diff --git a/devimint/src/vars.rs b/devimint/src/vars.rs index 35f1f79fb52..14c85960aa4 100644 --- a/devimint/src/vars.rs +++ b/devimint/src/vars.rs @@ -72,7 +72,7 @@ async fn mkdir(dir: PathBuf) -> anyhow::Result { Ok(dir) } -use fedimint_server::config::ServerConfig; +use fedimint_server::config::ConfigGenParams; use format as f; pub fn utf8(path: &Path) -> &str { @@ -162,12 +162,12 @@ impl Global { // // * `id` - ID of the server. Used to calculate port numbers. declare_vars! { - Fedimintd = (globals: &Global, cfg: &ServerConfig, bind_metrics_api: String) => { - FM_BIND_P2P: String = cfg.local.fed_bind.to_string(); - FM_P2P_URL: String = cfg.local.p2p_endpoints[&cfg.local.identity].url.to_string(); - FM_BIND_API: String = cfg.local.api_bind.to_string(); - FM_BIND_METRICS_API: String = bind_metrics_api; - FM_API_URL: String = cfg.consensus.api_endpoints[&cfg.local.identity].url.to_string(); - FM_DATA_DIR: PathBuf = mkdir(globals.FM_DATA_DIR.join(format!("server-{}", cfg.local.identity.to_usize()))).await?; + Fedimintd = (globals: &Global, params: ConfigGenParams) => { + FM_BIND_P2P: String = params.local.p2p_bind.to_string(); + FM_BIND_API: String = params.local.api_bind.to_string(); + FM_P2P_URL: String = params.consensus.peers[¶ms.local.our_id].p2p_url.to_string(); + FM_API_URL: String = params.consensus.peers[¶ms.local.our_id].api_url.to_string(); + FM_BIND_METRICS_API: String = format!("127.0.0.1:{}", 3510 + params.local.our_id.to_usize()); + FM_DATA_DIR: PathBuf = mkdir(globals.FM_DATA_DIR.join(format!("server-{}", params.local.our_id.to_usize()))).await?; } } diff --git a/fedimint-core/src/admin_client.rs b/fedimint-core/src/admin_client.rs index 01bbe5125d4..d382b243798 100644 --- a/fedimint-core/src/admin_client.rs +++ b/fedimint-core/src/admin_client.rs @@ -22,6 +22,7 @@ use crate::PeerId; // TODO: Maybe should have it's own CLI client so it doesn't need to be in core pub struct WsAdminClient { inner: DynGlobalApi, + pub url: Url, } impl WsAdminClient { @@ -30,7 +31,8 @@ impl WsAdminClient { // multiple peers so errors can be attributed. The admin client has no use for // them. Self { - inner: WsFederationApi::new(vec![(PeerId(0), url)]).into(), + inner: WsFederationApi::new(vec![(PeerId(0), url.clone())]).into(), + url, } } diff --git a/fedimint-core/src/api.rs b/fedimint-core/src/api.rs index 6b87951cf37..82ce7702c63 100644 --- a/fedimint-core/src/api.rs +++ b/fedimint-core/src/api.rs @@ -38,7 +38,7 @@ use serde::{Deserialize, Serialize}; use serde_json::Value; use thiserror::Error; use threshold_crypto::{PublicKey, PK_SIZE}; -use tracing::{debug, error, instrument, trace}; +use tracing::{debug, error, instrument, trace, warn}; use url::Url; use crate::backup::ClientBackupSnapshot; @@ -939,7 +939,8 @@ impl FederationMember { .await? } Err(err) => { - error!( + // Warn instead of Error because we will probably retry connecting later + warn!( target: LOG_NET_API, %err, "unable to connect to server"); return Err(err)?; diff --git a/fedimint-dbtool/README.md b/fedimint-dbtool/README.md index d85f65a0a95..b5a641e48de 100644 --- a/fedimint-dbtool/README.md +++ b/fedimint-dbtool/README.md @@ -71,22 +71,22 @@ just mprocs Dump the entire database of server-0 ```shell -dbtool $FM_DATA_DIR/server-0/database dump -- $FM_DATA_DIR/server-0 pass0 +dbtool $FM_DATA_DIR/server-0/database dump -- $FM_DATA_DIR/server-0 pass ``` Dump the consensus db entries of server-0 ```shell -dbtool $FM_DATA_DIR/server-0/database dump -- $FM_DATA_DIR/server-0 pass0 consensus +dbtool $FM_DATA_DIR/server-0/database dump -- $FM_DATA_DIR/server-0 pass consensus ``` Dump the blocks from the wallet module of server-1 ```shell -dbtool $FM_DATA_DIR/server-1/database dump -- $FM_DATA_DIR/server-1 pass1 consensus blockhash +dbtool $FM_DATA_DIR/server-1/database dump -- $FM_DATA_DIR/server-1 pass consensus blockhash ``` Dump the used notes from the mint module and the accepted transactions from consensus ```shell -dbtool $FM_DATA_DIR/server-1/database dump -- $FM_DATA_DIR/server-1 pass1 consensus,mint notenonce,acceptedtransaction +dbtool $FM_DATA_DIR/server-1/database dump -- $FM_DATA_DIR/server-1 pass consensus,mint notenonce,acceptedtransaction ``` Dump the entire client database (client password can be anything since it doesn't require decryption) diff --git a/fedimint-server/src/config/api.rs b/fedimint-server/src/config/api.rs index ed4c804553b..d7fbb9c51e0 100644 --- a/fedimint-server/src/config/api.rs +++ b/fedimint-server/src/config/api.rs @@ -962,14 +962,14 @@ mod tests { let leader_amount = leader.amount; let leader_name = leader.name.clone(); followers.push(leader); - let followers = Arc::new(followers); + let all_peers = Arc::new(followers); let (results, _) = tokio::join!( join_all( - followers + all_peers .iter() .map(|peer| peer.client.run_dkg(peer.auth.clone())) ), - followers[0].wait_status(ServerStatus::ReadyForConfigGen) + all_peers[0].wait_status(ServerStatus::ReadyForConfigGen) ); for result in results { result.expect("DKG failed"); @@ -977,7 +977,7 @@ mod tests { // verify config hashes equal for all peers let mut hashes = HashSet::new(); - for peer in followers.iter() { + for peer in all_peers.iter() { peer.wait_status(ServerStatus::VerifyingConfigs).await; hashes.insert( peer.client @@ -989,7 +989,7 @@ mod tests { assert_eq!(hashes.len(), 1); // verify the local and consensus values for peers - for peer in followers.iter() { + for peer in all_peers.iter() { let cfg = peer.read_config(); let dummy: DummyConfig = cfg.get_module_config_typed(0).unwrap(); assert_eq!(dummy.consensus.tx_fee, leader_amount); @@ -998,17 +998,17 @@ mod tests { } // start consensus - for peer in followers.iter() { + for peer in all_peers.iter() { peer.client.start_consensus(peer.auth.clone()).await.ok(); assert_eq!(peer.status().await.server, ServerStatus::ConsensusRunning); } // shutdown - for peer in followers.iter() { + for peer in all_peers.iter() { peer.retry_signal_upgrade().await; } - followers + all_peers }; // Run the Fedimint servers and test concurrently diff --git a/fedimint-testing/src/federation.rs b/fedimint-testing/src/federation.rs index c2707b7ed27..6233ef0dc25 100644 --- a/fedimint-testing/src/federation.rs +++ b/fedimint-testing/src/federation.rs @@ -176,7 +176,7 @@ pub fn local_config_gen_params( local: ConfigGenParamsLocal { our_id: *peer, our_private_key: tls_keys[peer].1.clone(), - api_auth: ApiAuth(format!("pass{}", peer.to_usize())), + api_auth: ApiAuth("pass".to_string()), p2p_bind: p2p_bind.parse().expect("Valid address"), api_bind: api_bind.parse().expect("Valid address"), download_token_limit: None, diff --git a/misc/mprocs.yaml b/misc/mprocs.yaml index 1c99304bcd3..4c0bf2627cb 100644 --- a/misc/mprocs.yaml +++ b/misc/mprocs.yaml @@ -23,5 +23,7 @@ procs: shell: tail -n +0 -F $FM_LOGS_DIR/bitcoind.log devimint: shell: tail -n +0 -F $FM_LOGS_DIR/devimint.log + devimint-outer: + shell: tail -n +0 -F $FM_LOGS_DIR/devimint-outer.log faucet: shell: tail -n +0 -F $FM_LOGS_DIR/faucet.log diff --git a/scripts/mprocs.sh b/scripts/mprocs.sh index e311cbe560e..7dd6acccf79 100755 --- a/scripts/mprocs.sh +++ b/scripts/mprocs.sh @@ -12,7 +12,8 @@ export FM_VERBOSE_OUTPUT=0 source scripts/build.sh -devimint dev-fed 2>/dev/null & +mkdir -p $FM_LOGS_DIR +devimint dev-fed 2>$FM_LOGS_DIR/devimint-outer.log & echo $! >> $FM_PID_FILE eval "$(devimint env)"