/* This file is part of DarkFi (https://dark.fi) * * Copyright (C) 2020-2023 Dyne.org foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ use std::collections::HashMap; use log::{info, warn}; use structopt_toml::{serde::Deserialize, structopt::StructOpt, StructOptToml}; use toml::Value; use url::Url; use darkfi::{cli_desc, Result}; #[derive(Clone, Debug, Deserialize, StructOpt, StructOptToml)] #[serde(default)] #[structopt(name = "lilith", about = cli_desc!())] pub struct Args { #[structopt(long, default_value = "tcp://127.0.0.1:18927")] /// JSON-RPC listen URL pub rpc_listen: Url, #[structopt(short, long)] /// Configuration file to use pub config: Option, #[structopt(long)] /// Daemon published urls, common for all enabled networks (repeatable flag) pub urls: Vec, #[structopt(long, default_value = "~/.config/darkfi/lilith_hosts.tsv")] /// Hosts .tsv file to use pub hosts_file: String, #[structopt(short, parse(from_occurrences))] /// Increase verbosity (-vvv supported) pub verbose: u8, } /// Defines the network specific settings #[derive(Clone)] pub struct NetInfo { /// Specific port the network will use pub port: u16, /// Connect to seeds (repeatable flag) pub seeds: Vec, /// Connect to peers (repeatable flag) pub peers: Vec, /// Enable localnet hosts pub localnet: bool, /// Enable channel log pub channel_log: bool, } /// Parse a TOML string for any configured network and return /// a map containing said configurations. /// /// ```toml /// [network."darkfid_sync"] /// port = 33032 /// seeds = [] /// peers = [] /// ``` pub fn parse_configured_networks(data: &str) -> Result> { let mut ret = HashMap::new(); if let Value::Table(map) = toml::from_str(data)? { if map.contains_key("network") && map["network"].is_table() { for net in map["network"].as_table().unwrap() { info!("Found configuration for network: {}", net.0); let table = net.1.as_table().unwrap(); if !table.contains_key("port") { warn!("Network port is mandatory, skipping network."); continue } let name = net.0.to_string(); let port = table["port"].as_integer().unwrap().try_into().unwrap(); let mut seeds = vec![]; if table.contains_key("seeds") { if let Some(s) = table["seeds"].as_array() { for seed in s { if let Some(u) = seed.as_str() { if let Ok(url) = Url::parse(u) { seeds.push(url); } } } } } let mut peers = vec![]; if table.contains_key("peers") { if let Some(p) = table["peers"].as_array() { for peer in p { if let Some(u) = peer.as_str() { if let Ok(url) = Url::parse(u) { peers.push(url); } } } } } let localnet = if table.contains_key("localnet") { table["localnet"].as_bool().unwrap() } else { false }; let channel_log = if table.contains_key("channel_log") { table["channel_log"].as_bool().unwrap() } else { false }; let net_info = NetInfo { port, seeds, peers, localnet, channel_log }; ret.insert(name, net_info); } } }; Ok(ret) }