From f122de592ac813b579a54fbb211e4c1874a6f44e Mon Sep 17 00:00:00 2001 From: Justin Kilpatrick Date: Fri, 16 Aug 2024 08:53:19 -0400 Subject: [PATCH] Add operator address support for Exits While exits don't need to pay an operator fee they do need an operator address so we can categorize them per network / operator in operator tools or elsewhere. On the exit side this new setting actually has no real functionality, it's only a tag for remote management software. The operator fee has been removed becuase the fee is for operational upkeep of nodes and exits are expected to have bespoke operators. --- integration_tests/src/utils.rs | 8 +-- rita_client/src/dashboard/mod.rs | 5 +- rita_client/src/dashboard/operator.rs | 80 ---------------------- rita_client/src/dashboard/operator_fees.rs | 36 ++++++++++ rita_common/src/dashboard/mod.rs | 1 + rita_common/src/dashboard/operator.rs | 80 ++++++++++++++++++++++ rita_exit/src/dashboard.rs | 4 ++ settings/src/exit.rs | 4 ++ settings/src/lib.rs | 12 ++++ settings/src/operator.rs | 15 ++++ 10 files changed, 157 insertions(+), 88 deletions(-) delete mode 100644 rita_client/src/dashboard/operator.rs create mode 100644 rita_client/src/dashboard/operator_fees.rs create mode 100644 rita_common/src/dashboard/operator.rs diff --git a/integration_tests/src/utils.rs b/integration_tests/src/utils.rs index 55e4d381d..31a643f3d 100644 --- a/integration_tests/src/utils.rs +++ b/integration_tests/src/utils.rs @@ -38,12 +38,7 @@ use rita_common::{ payment_validator::{ALTHEA_CHAIN_PREFIX, ALTHEA_CONTACT_TIMEOUT}, }; use settings::{ - client::RitaClientSettings, - exit::{ExitNetworkSettings, RitaExitSettingsStruct}, - localization::LocalizationSettings, - logging::LoggingSettings, - network::NetworkSettings, - payment::PaymentSettings, + client::RitaClientSettings, exit::{ExitNetworkSettings, RitaExitSettingsStruct}, localization::LocalizationSettings, logging::LoggingSettings, network::NetworkSettings, operator::ExitOperatorSettings, payment::PaymentSettings }; use std::{ collections::{HashMap, HashSet}, @@ -397,6 +392,7 @@ pub fn get_default_settings( exit_network: ExitNetworkSettings::test_default(), allowed_countries: HashSet::new(), log: LoggingSettings::default(), + operator: ExitOperatorSettings::default(), }; let client = RitaClientSettings::default(); diff --git a/rita_client/src/dashboard/mod.rs b/rita_client/src/dashboard/mod.rs index de99858b1..5046b2a0f 100644 --- a/rita_client/src/dashboard/mod.rs +++ b/rita_client/src/dashboard/mod.rs @@ -11,7 +11,7 @@ pub mod extender_checkin; pub mod installation_details; pub mod neighbors; pub mod notifications; -pub mod operator; +pub mod operator_fees; pub mod prices; pub mod router; pub mod usage; @@ -22,13 +22,14 @@ use crate::dashboard::extender_checkin::*; use crate::dashboard::installation_details::*; use crate::dashboard::neighbors::*; use crate::dashboard::notifications::*; -use crate::dashboard::operator::*; +use crate::dashboard::operator_fees::*; use crate::dashboard::prices::*; use crate::dashboard::router::*; use crate::dashboard::usage::*; use actix_async::System; use actix_web_async::{web, App, HttpServer}; use rita_common::dashboard::auth::*; +use rita_common::dashboard::operator::*; use rita_common::dashboard::babel::*; use rita_common::dashboard::backup_created::*; use rita_common::dashboard::contact_info::*; diff --git a/rita_client/src/dashboard/operator.rs b/rita_client/src/dashboard/operator.rs deleted file mode 100644 index 50ff1a59e..000000000 --- a/rita_client/src/dashboard/operator.rs +++ /dev/null @@ -1,80 +0,0 @@ -use crate::operator_fee_manager::get_operator_fee_debt; -use actix_web_async::web::Path; -use actix_web_async::{HttpRequest, HttpResponse}; -use clarity::{Address, Uint256}; - -pub async fn get_operator(_req: HttpRequest) -> HttpResponse { - trace!("get operator address: Hit"); - let rita_client = settings::get_rita_client(); - match rita_client.operator.operator_address { - Some(address) => HttpResponse::Ok().json(Some(address)), - None => { - let emp_op: Option
= None; - HttpResponse::Ok().json(emp_op) - } - } -} - -pub async fn change_operator(path: Path
) -> HttpResponse { - trace!("add operator address: Hit"); - let provided_address = path.into_inner(); - let mut rita_client = settings::get_rita_client(); - let mut operator = rita_client.operator; - - operator.operator_address = Some(provided_address); - - rita_client.operator = operator; - settings::set_rita_client(rita_client); - - // save immediately - if let Err(_e) = settings::write_config() { - return HttpResponse::InternalServerError().finish(); - } - - HttpResponse::Ok().finish() -} - -pub async fn remove_operator(_path: Path
) -> HttpResponse { - let mut rita_client = settings::get_rita_client(); - let mut operator = rita_client.operator; - operator.operator_address = None; - - rita_client.operator = operator; - settings::set_rita_client(rita_client); - - // save immediately - if let Err(_e) = settings::write_config() { - return HttpResponse::InternalServerError().finish(); - } - - HttpResponse::Ok().finish() -} - -pub async fn get_operator_fee(_req: HttpRequest) -> HttpResponse { - debug!("get_operator_fee GET hit"); - HttpResponse::Ok().json(settings::get_rita_client().operator.operator_fee) -} - -pub async fn set_operator_fee(fee: Path) -> HttpResponse { - let op_fee = fee.into_inner(); - debug!("set_operator_fee POST hit {:?}", op_fee); - - let mut rita_client = settings::get_rita_client(); - rita_client.operator.operator_fee = op_fee; - - rita_client.operator.use_operator_price = op_fee == 0_u8.into(); - - settings::set_rita_client(rita_client); - - // save immediately - if let Err(_e) = settings::write_config() { - return HttpResponse::InternalServerError().finish(); - } - - HttpResponse::Ok().json(settings::get_rita_client().operator.operator_fee) -} - -pub async fn get_operator_debt(_req: HttpRequest) -> HttpResponse { - debug!("get operator debt hit"); - HttpResponse::Ok().json(get_operator_fee_debt()) -} diff --git a/rita_client/src/dashboard/operator_fees.rs b/rita_client/src/dashboard/operator_fees.rs new file mode 100644 index 000000000..2405eff0c --- /dev/null +++ b/rita_client/src/dashboard/operator_fees.rs @@ -0,0 +1,36 @@ +//! Operator fees are the fees that the operator charges for the service of running the network +//! and providing internet access. This module contains the operator fee related endpoints. + +use crate::operator_fee_manager::get_operator_fee_debt; +use actix_web_async::web::Path; +use actix_web_async::{HttpRequest, HttpResponse}; +use clarity::Uint256; + +pub async fn get_operator_fee(_req: HttpRequest) -> HttpResponse { + debug!("get_operator_fee GET hit"); + HttpResponse::Ok().json(settings::get_rita_client().operator.operator_fee) +} + +pub async fn set_operator_fee(fee: Path) -> HttpResponse { + let op_fee = fee.into_inner(); + debug!("set_operator_fee POST hit {:?}", op_fee); + + let mut rita_client = settings::get_rita_client(); + rita_client.operator.operator_fee = op_fee; + + rita_client.operator.use_operator_price = op_fee == 0_u8.into(); + + settings::set_rita_client(rita_client); + + // save immediately + if let Err(_e) = settings::write_config() { + return HttpResponse::InternalServerError().finish(); + } + + HttpResponse::Ok().json(settings::get_rita_client().operator.operator_fee) +} + +pub async fn get_operator_debt(_req: HttpRequest) -> HttpResponse { + debug!("get operator debt hit"); + HttpResponse::Ok().json(get_operator_fee_debt()) +} diff --git a/rita_common/src/dashboard/mod.rs b/rita_common/src/dashboard/mod.rs index 6dfac03aa..a178615bb 100644 --- a/rita_common/src/dashboard/mod.rs +++ b/rita_common/src/dashboard/mod.rs @@ -23,3 +23,4 @@ pub mod usage; pub mod wallet; pub mod wg_key; pub mod wifi; +pub mod operator; diff --git a/rita_common/src/dashboard/operator.rs b/rita_common/src/dashboard/operator.rs new file mode 100644 index 000000000..dcd489770 --- /dev/null +++ b/rita_common/src/dashboard/operator.rs @@ -0,0 +1,80 @@ +//! This module contains the operator address related endpoints the operator address is used to organize +//! what network a given device is a part of and for client devices the address to which operator fees are +//! paid, exits only use operator addresses for organization and not for fee collection. +use actix_web_async::web::Path; +use actix_web_async::{HttpRequest, HttpResponse}; +use clarity::Address; + +enum Mode { + Client, + Exit, +} + +fn get_mode() -> Option { + if settings::check_if_client() { + Some(Mode::Client) + } else if settings::check_if_exit() { + Some(Mode::Exit) + } else { + None + } +} + +fn get_operator_address(mode: Mode) -> Option
{ + match mode { + Mode::Client => settings::get_rita_client().operator.operator_address, + Mode::Exit => settings::get_rita_exit().operator.operator_address, + } +} + +fn set_operator_address_and_save(mode: Mode, address: Option
) { + match mode { + Mode::Client => { + let mut rita_client = settings::get_rita_client(); + rita_client.operator.operator_address = address; + settings::set_rita_client(rita_client); + } + Mode::Exit => { + let mut rita_exit = settings::get_rita_exit(); + rita_exit.operator.operator_address = address; + settings::set_rita_exit(rita_exit); + } + } + + // Save configuration immediately and log any error, but don't return it + if let Err(e) = settings::write_config() { + error!("Failed to write config: {:?}", e); + } +} + +pub async fn get_operator(_req: HttpRequest) -> HttpResponse { + trace!("get operator address: Hit"); + + match get_mode() { + Some(mode) => HttpResponse::Ok().json(get_operator_address(mode)), + None => HttpResponse::InternalServerError().finish(), + } +} + +pub async fn change_operator(path: Path
) -> HttpResponse { + trace!("add operator address: Hit"); + let provided_address = Some(path.into_inner()); + + match get_mode() { + Some(mode) => { + set_operator_address_and_save(mode, provided_address); + HttpResponse::Ok().finish() + } + None => HttpResponse::InternalServerError().finish(), + } +} + +pub async fn remove_operator(_path: Path
) -> HttpResponse { + match get_mode() { + Some(mode) => { + set_operator_address_and_save(mode, None); + HttpResponse::Ok().finish() + } + None => HttpResponse::InternalServerError().finish(), + } +} diff --git a/rita_exit/src/dashboard.rs b/rita_exit/src/dashboard.rs index 427f42c3c..366c9c714 100644 --- a/rita_exit/src/dashboard.rs +++ b/rita_exit/src/dashboard.rs @@ -17,6 +17,7 @@ use rita_common::dashboard::localization::*; use rita_common::dashboard::logging::*; use rita_common::dashboard::mesh_ip::*; use rita_common::dashboard::nickname::*; +use rita_common::dashboard::operator::*; use rita_common::dashboard::own_info::*; use rita_common::dashboard::remote_access::*; use rita_common::dashboard::settings::*; @@ -45,6 +46,9 @@ pub fn start_rita_exit_dashboard(startup_status: Arc>>) { .wrap(middleware::AuthMiddlewareFactory) .wrap(middleware::HeadersMiddlewareFactory) .route("/info", web::get().to(get_own_info)) + .route("/operator", web::get().to(get_operator)) + .route("/operator/{address}", web::post().to(change_operator)) + .route("/operator/remove", web::post().to(remove_operator)) .route("/local_fee", web::get().to(get_local_fee)) .route("/local_fee/{fee}", web::post().to(set_local_fee)) .route("/metric_factor", web::get().to(get_metric_factor)) diff --git a/settings/src/exit.rs b/settings/src/exit.rs index 7b7ae9761..afac8e23a 100644 --- a/settings/src/exit.rs +++ b/settings/src/exit.rs @@ -1,6 +1,7 @@ use crate::localization::LocalizationSettings; use crate::logging::LoggingSettings; use crate::network::NetworkSettings; +use crate::operator::ExitOperatorSettings; use crate::payment::PaymentSettings; use crate::{json_merge, set_rita_exit, SettingsError}; use althea_types::{regions::Regions, ExitIdentity, Identity, WgKey}; @@ -108,6 +109,8 @@ pub struct RitaExitSettingsStruct { pub localization: LocalizationSettings, pub network: NetworkSettings, pub exit_network: ExitNetworkSettings, + #[serde(default)] + pub operator: ExitOperatorSettings, /// Countries which the clients to the exit are allowed from, blank for no geoip validation. /// (ISO country code) #[serde(skip_serializing_if = "HashSet::is_empty", default)] @@ -131,6 +134,7 @@ impl RitaExitSettingsStruct { payment: PaymentSettings::default(), localization: LocalizationSettings::default(), network: NetworkSettings::default(), + operator: ExitOperatorSettings::default(), exit_network: ExitNetworkSettings::test_default(), allowed_countries: HashSet::new(), log: LoggingSettings::default(), diff --git a/settings/src/lib.rs b/settings/src/lib.rs index 7c11959dd..0be9f636e 100644 --- a/settings/src/lib.rs +++ b/settings/src/lib.rs @@ -342,6 +342,18 @@ pub fn get_rita_exit() -> RitaExitSettingsStruct { } } +/// This code checks to see if the current device/setting is client or not +pub fn check_if_client() -> bool { + let netns = KI.check_integration_test_netns(); + match SETTINGS.read().unwrap().get(&netns) { + Some(Settings::Adaptor(_)) => false, + Some(Settings::Client(_)) => true, + Some(Settings::Exit(_)) => false, + None => false, + } +} + + /// This code checks to see if the current device/setting is an exit or not pub fn check_if_exit() -> bool { let netns = KI.check_integration_test_netns(); diff --git a/settings/src/operator.rs b/settings/src/operator.rs index 1ff696e29..2e77f1205 100644 --- a/settings/src/operator.rs +++ b/settings/src/operator.rs @@ -74,3 +74,18 @@ impl Default for OperatorSettings { } } } + +#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)] +pub struct ExitOperatorSettings { + /// The operator managing this router + #[serde(default = "default_operator_address")] + pub operator_address: Option
, +} + +impl Default for ExitOperatorSettings { + fn default() -> ExitOperatorSettings { + ExitOperatorSettings { + operator_address: default_operator_address(), + } + } +}