From 56730496f29bd4ec615ac54a19b6021f6e232d8a Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 7 Aug 2024 15:18:27 +0100 Subject: [PATCH 1/4] feat(watcher): add cli and config --- Cargo.lock | 13 ++ Cargo.toml | 2 +- applications/tari_watcher/Cargo.toml | 19 +++ .../tari_watcher/data/watcher/config.toml | 36 ++++ applications/tari_watcher/src/cli.rs | 48 ++++++ applications/tari_watcher/src/config.rs | 154 ++++++++++++++++++ applications/tari_watcher/src/lib.rs | 2 + applications/tari_watcher/src/main.rs | 42 +++++ 8 files changed, 315 insertions(+), 1 deletion(-) create mode 100644 applications/tari_watcher/Cargo.toml create mode 100644 applications/tari_watcher/data/watcher/config.toml create mode 100644 applications/tari_watcher/src/cli.rs create mode 100644 applications/tari_watcher/src/config.rs create mode 100644 applications/tari_watcher/src/lib.rs create mode 100644 applications/tari_watcher/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index c05ebcfde..5671d45ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10134,6 +10134,19 @@ dependencies = [ "ts-rs", ] +[[package]] +name = "tari_watcher" +version = "0.7.0" +dependencies = [ + "anyhow", + "clap 3.2.25", + "log", + "serde", + "serde_json", + "tokio", + "toml 0.8.15", +] + [[package]] name = "tariswap_bench" version = "0.7.0" diff --git a/Cargo.toml b/Cargo.toml index 214249591..cf7ae9c84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,7 +56,7 @@ members = [ "utilities/tariswap_test_bench", "utilities/transaction_submitter", "utilities/transaction_submitter", - "utilities/generate_ristretto_value_lookup", + "utilities/generate_ristretto_value_lookup", "applications/tari_watcher", ] resolver = "2" diff --git a/applications/tari_watcher/Cargo.toml b/applications/tari_watcher/Cargo.toml new file mode 100644 index 000000000..aac794b1d --- /dev/null +++ b/applications/tari_watcher/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "tari_watcher" +version.workspace = true +edition.workspace = true +authors.workspace = true +repository.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clap = { workspace = true, features = ["derive"] } +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } +anyhow = { workspace = true } +tokio = { workspace = true, features = ["rt-multi-thread", "macros", "signal", "process", "time", "fs", "io-util"] } +log = { workspace = true } + +toml = "0.8.12" diff --git a/applications/tari_watcher/data/watcher/config.toml b/applications/tari_watcher/data/watcher/config.toml new file mode 100644 index 000000000..c674fc0de --- /dev/null +++ b/applications/tari_watcher/data/watcher/config.toml @@ -0,0 +1,36 @@ +auto_register = true +base_node_grpc_address = "localhost:18142" +base_wallet_grpc_address = "localhost:18143" +vn_registration_file = "/Users/dkast/go/src/github.com/therealdannzor/tari-dan/applications/tari_watcher/data/watcher/./data/watcher/vn_registration.toml" + +[[instance_config]] +name = "tari_validator_node" +instance_type = "TariValidatorNode" +num_instances = 1 + +[instance_config.settings] + +[[instance_config]] +name = "minotari_wallet" +instance_type = "MinoTariConsoleWallet" +num_instances = 1 + +[instance_config.settings] + +[[executable_config]] +instance_type = "TariValidatorNode" +executable_path = "target/release/minotari_node" +env = [] + +[executable_config.compile] +working_dir = "../tari" +package_name = "minotari_node" + +[[executable_config]] +instance_type = "MinoTariConsoleWallet" +executable_path = "target/release/minotari_wallet" +env = [] + +[executable_config.compile] +working_dir = "../tari" +package_name = "minotari_wallet" diff --git a/applications/tari_watcher/src/cli.rs b/applications/tari_watcher/src/cli.rs new file mode 100644 index 000000000..0df9ea3b2 --- /dev/null +++ b/applications/tari_watcher/src/cli.rs @@ -0,0 +1,48 @@ +// Copyright 2024 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use std::path::PathBuf; + +use clap::Parser; + +#[derive(Clone, Debug, Parser)] +pub struct Cli { + #[clap(flatten)] + pub common: CommonCli, + #[clap(subcommand)] + pub command: Commands, +} + +impl Cli { + pub fn init() -> Self { + Self::parse() + } + + pub fn get_config_path(&self) -> PathBuf { + let Some(ref base_dir) = self.common.base_dir else { + return self.common.config_path.clone(); + }; + if self.common.config_path.is_relative() { + base_dir.join(&self.common.config_path) + } else { + self.common.config_path.clone() + } + } +} + +#[derive(Debug, Clone, clap::Args)] +pub struct CommonCli { + #[clap(short = 'b', long, parse(from_os_str))] + pub base_dir: Option, + #[clap(short, long, parse(from_os_str), default_value = "./data/watcher/config.toml")] + pub config_path: PathBuf, +} + +#[derive(Clone, Debug, clap::Subcommand)] +pub enum Commands { + Init, + Start, +} + +#[derive(Clone, Debug, clap::Args)] +pub struct Overrides {} diff --git a/applications/tari_watcher/src/config.rs b/applications/tari_watcher/src/config.rs new file mode 100644 index 000000000..684bb2c22 --- /dev/null +++ b/applications/tari_watcher/src/config.rs @@ -0,0 +1,154 @@ +// Copyright 2024 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use crate::Cli; +use std::collections::HashMap; +use std::fmt::{self, Display}; +use std::path::PathBuf; +use tokio::io::{self, AsyncWriteExt}; + +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct Config { + /// Allow watcher to submit a new validator node registration transaction initially and before + /// the current registration expires + pub auto_register: bool, + + /// The Minotari node gRPC address + pub base_node_grpc_address: String, + + /// The Minotari console wallet gRPC address + pub base_wallet_grpc_address: String, + + /// The path of the validator node registration file, containing signed information required to + /// submit a registration transaction on behalf of the node + pub vn_registration_file: PathBuf, + + /// The sidechain ID to use. If not provided, the default Tari sidechain ID will be used. + pub sidechain_id: Option, + + /// The configuration for managing one or multiple processes + pub instance_config: Vec, + + /// The process specific configuration for the executables + pub executable_config: Vec, +} + +impl Config { + pub(crate) async fn write(&self, mut writer: W) -> anyhow::Result<()> { + let toml = toml::to_string_pretty(self)?; + writer.write_all(toml.as_bytes()).await?; + Ok(()) + } +} + +#[derive(Debug, Clone, Copy, Eq, PartialEq, serde::Serialize, serde::Deserialize)] +pub enum InstanceType { + TariValidatorNode, + MinoTariConsoleWallet, +} + +impl Display for InstanceType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(self, f) + } +} + +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct ExecutableConfig { + pub instance_type: InstanceType, + pub executable_path: Option, + pub compile: Option, + pub env: Vec<(String, String)>, +} + +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct CompileConfig { + pub working_dir: Option, + pub package_name: String, + pub target_dir: Option, +} + +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct InstanceConfig { + pub name: String, + pub instance_type: InstanceType, + pub num_instances: u32, + #[serde(alias = "extra_args")] + pub settings: HashMap, +} + +impl InstanceConfig { + pub fn new(instance_type: InstanceType) -> Self { + Self { + name: instance_type.to_string(), + instance_type, + num_instances: 1, + settings: HashMap::new(), + } + } + + pub fn with_name>(mut self, name: S) -> Self { + self.name = name.into(); + self + } + + pub fn with_num_instances(mut self, num_instances: u32) -> Self { + self.num_instances = num_instances; + self + } +} + +pub fn get_base_config(cli: &Cli) -> anyhow::Result { + let executables = vec![ + ExecutableConfig { + instance_type: InstanceType::TariValidatorNode, + executable_path: Some("target/release/minotari_node".into()), + compile: Some(CompileConfig { + working_dir: Some("../tari".into()), + package_name: "minotari_node".to_string(), + target_dir: None, + }), + env: vec![], + }, + ExecutableConfig { + instance_type: InstanceType::MinoTariConsoleWallet, + executable_path: Some("target/release/minotari_wallet".into()), + compile: Some(CompileConfig { + working_dir: Some("../tari".into()), + package_name: "minotari_wallet".to_string(), + target_dir: None, + }), + env: vec![], + }, + ]; + let instances = [ + InstanceConfig::new(InstanceType::TariValidatorNode) + .with_name("tari_validator_node") + .with_num_instances(1), + InstanceConfig::new(InstanceType::MinoTariConsoleWallet) + .with_name("minotari_wallet") + .with_num_instances(1), + ]; + + let base_dir = cli + .common + .base_dir + .clone() + .or_else(|| { + cli.get_config_path() + .canonicalize() + .ok() + .and_then(|p| p.parent().map(|p| p.to_path_buf())) + }) + .unwrap_or_else(|| std::env::current_dir().unwrap()); + + Ok(Config { + auto_register: true, + base_node_grpc_address: "localhost:18142".to_string(), + base_wallet_grpc_address: "localhost:18143".to_string(), + sidechain_id: None, + vn_registration_file: base_dir.join("vn_registration.toml"), + instance_config: instances.to_vec(), + executable_config: executables, + }) +} diff --git a/applications/tari_watcher/src/lib.rs b/applications/tari_watcher/src/lib.rs new file mode 100644 index 000000000..6917b32ae --- /dev/null +++ b/applications/tari_watcher/src/lib.rs @@ -0,0 +1,2 @@ +// Copyright 2024 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause diff --git a/applications/tari_watcher/src/main.rs b/applications/tari_watcher/src/main.rs new file mode 100644 index 000000000..174493501 --- /dev/null +++ b/applications/tari_watcher/src/main.rs @@ -0,0 +1,42 @@ +// Copyright 2024 The Tari Project +// SPDX-License-Identifier: BSD-3-Clause + +use crate::cli::{Cli, Commands}; +use anyhow::{anyhow, Context}; +use tokio::fs; + +use crate::config::get_base_config; + +mod cli; +mod config; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let cli = Cli::init(); + let config_path = cli.get_config_path(); + + match cli.command { + Commands::Init => { + // set by default in CommonCli + let parent = config_path.parent().unwrap(); + fs::create_dir_all(parent).await?; + + let config = get_base_config(&cli)?; + + let file = fs::File::create(&config_path) + .await + .with_context(|| anyhow!("Failed to open config path {}", config_path.display()))?; + config.write(file).await.context("Writing config failed")?; + + let config_path = config_path + .canonicalize() + .context("Failed to canonicalize config path")?; + log::info!("Config file created at {}", config_path.display()); + }, + Commands::Start => { + unimplemented!("Start command not implemented"); + }, + } + + Ok(()) +} From 5efa29435d8ef71e7e9414c77c82a0115b31ec2e Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 7 Aug 2024 17:38:39 +0100 Subject: [PATCH 2/4] feat(watcher): update config impl with alert channels --- applications/tari_watcher/Cargo.toml | 2 ++ .../tari_watcher/data/watcher/config.toml | 36 ------------------- applications/tari_watcher/src/cli.rs | 18 ++++++++-- applications/tari_watcher/src/config.rs | 34 +++++++++++++++--- applications/tari_watcher/src/main.rs | 15 +++++--- 5 files changed, 58 insertions(+), 47 deletions(-) delete mode 100644 applications/tari_watcher/data/watcher/config.toml diff --git a/applications/tari_watcher/Cargo.toml b/applications/tari_watcher/Cargo.toml index aac794b1d..4fdb5b2d9 100644 --- a/applications/tari_watcher/Cargo.toml +++ b/applications/tari_watcher/Cargo.toml @@ -9,6 +9,8 @@ license.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +#tari_common = { workspace = true } + clap = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } diff --git a/applications/tari_watcher/data/watcher/config.toml b/applications/tari_watcher/data/watcher/config.toml deleted file mode 100644 index c674fc0de..000000000 --- a/applications/tari_watcher/data/watcher/config.toml +++ /dev/null @@ -1,36 +0,0 @@ -auto_register = true -base_node_grpc_address = "localhost:18142" -base_wallet_grpc_address = "localhost:18143" -vn_registration_file = "/Users/dkast/go/src/github.com/therealdannzor/tari-dan/applications/tari_watcher/data/watcher/./data/watcher/vn_registration.toml" - -[[instance_config]] -name = "tari_validator_node" -instance_type = "TariValidatorNode" -num_instances = 1 - -[instance_config.settings] - -[[instance_config]] -name = "minotari_wallet" -instance_type = "MinoTariConsoleWallet" -num_instances = 1 - -[instance_config.settings] - -[[executable_config]] -instance_type = "TariValidatorNode" -executable_path = "target/release/minotari_node" -env = [] - -[executable_config.compile] -working_dir = "../tari" -package_name = "minotari_node" - -[[executable_config]] -instance_type = "MinoTariConsoleWallet" -executable_path = "target/release/minotari_wallet" -env = [] - -[executable_config.compile] -working_dir = "../tari" -package_name = "minotari_wallet" diff --git a/applications/tari_watcher/src/cli.rs b/applications/tari_watcher/src/cli.rs index 0df9ea3b2..ae1c1954d 100644 --- a/applications/tari_watcher/src/cli.rs +++ b/applications/tari_watcher/src/cli.rs @@ -5,6 +5,8 @@ use std::path::PathBuf; use clap::Parser; +use crate::config::Config; + #[derive(Clone, Debug, Parser)] pub struct Cli { #[clap(flatten)] @@ -34,15 +36,25 @@ impl Cli { pub struct CommonCli { #[clap(short = 'b', long, parse(from_os_str))] pub base_dir: Option, - #[clap(short, long, parse(from_os_str), default_value = "./data/watcher/config.toml")] + #[clap(short = 'c', long, parse(from_os_str), default_value = "./data/watcher/config.toml")] pub config_path: PathBuf, } #[derive(Clone, Debug, clap::Subcommand)] pub enum Commands { - Init, + Init(InitArgs), Start, } #[derive(Clone, Debug, clap::Args)] -pub struct Overrides {} +pub struct InitArgs { + #[clap(long)] + /// Disable initial and auto registration of the validator node + pub no_auto_register: bool, +} + +impl InitArgs { + pub fn apply(&self, config: &mut Config) { + config.auto_register = !self.no_auto_register; + } +} diff --git a/applications/tari_watcher/src/config.rs b/applications/tari_watcher/src/config.rs index 684bb2c22..ee6c3250b 100644 --- a/applications/tari_watcher/src/config.rs +++ b/applications/tari_watcher/src/config.rs @@ -1,12 +1,16 @@ // Copyright 2024 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use crate::Cli; -use std::collections::HashMap; -use std::fmt::{self, Display}; -use std::path::PathBuf; +use std::{ + collections::HashMap, + fmt::{self, Display}, + path::PathBuf, +}; + use tokio::io::{self, AsyncWriteExt}; +use crate::Cli; + #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct Config { /// Allow watcher to submit a new validator node registration transaction initially and before @@ -31,6 +35,9 @@ pub struct Config { /// The process specific configuration for the executables pub executable_config: Vec, + + /// The channel configuration for alerting and monitoring + pub channel_config: Vec, } impl Config { @@ -53,6 +60,13 @@ impl Display for InstanceType { } } +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct ChannelConfig { + pub name: String, + pub enabled: bool, + pub credentials: String, +} + #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct ExecutableConfig { pub instance_type: InstanceType, @@ -150,5 +164,17 @@ pub fn get_base_config(cli: &Cli) -> anyhow::Result { vn_registration_file: base_dir.join("vn_registration.toml"), instance_config: instances.to_vec(), executable_config: executables, + channel_config: vec![ + ChannelConfig { + name: "mattermost".to_string(), + enabled: true, + credentials: "".to_string(), + }, + ChannelConfig { + name: "telegram".to_string(), + enabled: true, + credentials: "".to_string(), + }, + ], }) } diff --git a/applications/tari_watcher/src/main.rs b/applications/tari_watcher/src/main.rs index 174493501..cb7c923b9 100644 --- a/applications/tari_watcher/src/main.rs +++ b/applications/tari_watcher/src/main.rs @@ -1,11 +1,13 @@ // Copyright 2024 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use crate::cli::{Cli, Commands}; use anyhow::{anyhow, Context}; use tokio::fs; -use crate::config::get_base_config; +use crate::{ + cli::{Cli, Commands}, + config::get_base_config, +}; mod cli; mod config; @@ -16,12 +18,14 @@ async fn main() -> anyhow::Result<()> { let config_path = cli.get_config_path(); match cli.command { - Commands::Init => { + Commands::Init(ref args) => { // set by default in CommonCli let parent = config_path.parent().unwrap(); fs::create_dir_all(parent).await?; - let config = get_base_config(&cli)?; + let mut config = get_base_config(&cli)?; + // optionally disables auto register + args.apply(&mut config); let file = fs::File::create(&config_path) .await @@ -31,6 +35,9 @@ async fn main() -> anyhow::Result<()> { let config_path = config_path .canonicalize() .context("Failed to canonicalize config path")?; + + // TODO: use standardised logging + // if let Err(e) = initialize_logging(..) log::info!("Config file created at {}", config_path.display()); }, Commands::Start => { From 7a543292c5dd87fa93aecf0e9eb6076f6e616b1a Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 7 Aug 2024 17:41:05 +0100 Subject: [PATCH 3/4] chore: remove unused file --- applications/tari_watcher/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 applications/tari_watcher/src/lib.rs diff --git a/applications/tari_watcher/src/lib.rs b/applications/tari_watcher/src/lib.rs deleted file mode 100644 index 6917b32ae..000000000 --- a/applications/tari_watcher/src/lib.rs +++ /dev/null @@ -1,2 +0,0 @@ -// Copyright 2024 The Tari Project -// SPDX-License-Identifier: BSD-3-Clause From c1851111fb9317c113a481fc6d4afdc2ee1ddd85 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 7 Aug 2024 18:08:17 +0100 Subject: [PATCH 4/4] chore: make machete happy --- Cargo.lock | 1 - applications/tari_watcher/Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5671d45ca..ea0100dcf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10142,7 +10142,6 @@ dependencies = [ "clap 3.2.25", "log", "serde", - "serde_json", "tokio", "toml 0.8.15", ] diff --git a/applications/tari_watcher/Cargo.toml b/applications/tari_watcher/Cargo.toml index 4fdb5b2d9..0367c410d 100644 --- a/applications/tari_watcher/Cargo.toml +++ b/applications/tari_watcher/Cargo.toml @@ -13,7 +13,6 @@ license.workspace = true clap = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] } -serde_json = { workspace = true } anyhow = { workspace = true } tokio = { workspace = true, features = ["rt-multi-thread", "macros", "signal", "process", "time", "fs", "io-util"] } log = { workspace = true }