From b90d2c09a12f1da33b779658f68865b48a55d826 Mon Sep 17 00:00:00 2001 From: ghassmo Date: Tue, 28 Sep 2021 18:55:05 +0300 Subject: [PATCH] remove hardcoded network name across the project and use enum instead --- src/bin/cashierd.rs | 57 ++++++++++++++++++++--------------------- src/bin/sol-test.rs | 2 +- src/service/bridge.rs | 11 ++++---- src/service/mod.rs | 53 ++++++++++++++++++++++++++++++++++++-- src/wallet/cashierdb.rs | 29 +++++++++++---------- 5 files changed, 101 insertions(+), 51 deletions(-) diff --git a/src/bin/cashierd.rs b/src/bin/cashierd.rs index 6f5ea9d91..b02c09760 100644 --- a/src/bin/cashierd.rs +++ b/src/bin/cashierd.rs @@ -3,11 +3,12 @@ use async_std::sync::{Arc, Mutex}; use async_trait::async_trait; use clap::clap_app; use ff::Field; -use log::{debug, warn}; +use log::debug; use rand::rngs::OsRng; use serde_json::{json, Value}; use std::collections::HashMap; use std::path::PathBuf; +use std::str::FromStr; use drk::{ blockchain::Rocks, @@ -19,7 +20,7 @@ use drk::{ rpcserver::{listen_and_serve, RequestHandler, RpcServerConfig}, }, serial::{deserialize, serialize}, - service::{bridge, bridge::Bridge}, + service::{bridge, bridge::Bridge, NetworkName}, util::{expand_path, generate_id, join_config_path}, wallet::{CashierDb, WalletDb}, Error, Result, @@ -37,7 +38,7 @@ struct Cashierd { config: CashierdConfig, bridge: Arc, cashier_wallet: Arc, - features: HashMap, + features: HashMap, client: Arc>, } @@ -97,7 +98,7 @@ impl Cashierd { let mut features = HashMap::new(); for network in config.clone().networks { - features.insert(network.name, network.blockchain); + features.insert(NetworkName::from_str(&network.name)?, network.blockchain); } let bridge = bridge::Bridge::new(); @@ -114,7 +115,7 @@ impl Cashierd { async fn resume_watch_deposit_keys( bridge: Arc, cashier_wallet: Arc, - features: HashMap, + features: HashMap, ) -> Result<()> { for (network, _) in features.iter() { let keypairs_to_watch = cashier_wallet.get_deposit_token_keys_by_network(&network)?; @@ -125,7 +126,7 @@ impl Cashierd { bridge_subscribtion .sender .send(bridge::BridgeRequests { - network: network.to_owned(), + network: network.clone(), payload: bridge::BridgeRequestsPayload::Watch(Some((keypair.0, keypair.1))), }) .await?; @@ -156,7 +157,7 @@ impl Cashierd { bridge_subscribtion .sender .send(bridge::BridgeRequests { - network: network.to_string(), + network: network.clone(), payload: bridge::BridgeRequestsPayload::Send(addr.clone(), amount), }) .await?; @@ -190,8 +191,7 @@ impl Cashierd { return JsonResult::Err(jsonerr(InvalidParams, None, id)); } - let network = &args[0].as_str().unwrap(); - let network = network.to_string(); + let network = NetworkName::from_str(args[0].as_str().unwrap()).unwrap(); let token_id = &args[1].as_str().unwrap(); let drk_pub_key = &args[2].as_str().unwrap(); @@ -284,8 +284,7 @@ impl Cashierd { return JsonResult::Err(jsonerr(InvalidParams, None, id)); } - let network = &args[0].as_str().unwrap(); - let network = network.to_string(); + let network = NetworkName::from_str(args[0].as_str().unwrap()).unwrap(); let token = &args[1].as_str().unwrap(); let address = &args[2].as_str().unwrap(); let _amount = &args[3]; @@ -320,7 +319,7 @@ impl Cashierd { &address, &cashier_public, &cashier_secret, - &network.to_string(), + &network, &asset_id, )?; } @@ -337,19 +336,25 @@ impl Cashierd { } async fn features(&self, id: Value, _params: Value) -> JsonResult { - JsonResult::Resp(jsonresp(json!(self.features), id)) + JsonResult::Resp(jsonresp( + json!(self + .features + .iter() + .map(|(k, v)| (k.to_string(), v.to_owned())) + .collect::>()), + id, + )) } - fn check_token_id(network: &str, token_id: &str) -> Result<()> { + fn check_token_id(network: &NetworkName, token_id: &str) -> Result<()> { match network { #[cfg(feature = "sol")] - "sol" | "solana" => { + NetworkName::Solana => { if token_id != "So11111111111111111111111111111111111111112" { // This is supposed to be a token mint account now use drk::service::sol::account_is_initialized_mint; use drk::service::sol::SolFailed::BadSolAddress; use solana_sdk::pubkey::Pubkey; - use std::str::FromStr; let pubkey = match Pubkey::from_str(token_id) { Ok(v) => v, @@ -365,10 +370,9 @@ impl Cashierd { } } #[cfg(feature = "btc")] - "btc" | "bitcoin" => { + NetworkName::Bitcoin => { // Handle bitcoin address here if needed } - _ => {} } Ok(()) } @@ -379,9 +383,9 @@ impl Cashierd { for (feature_name, chain) in self.features.iter() { let bridge2 = self.bridge.clone(); - match feature_name.as_str() { + match feature_name { #[cfg(feature = "sol")] - "sol" | "solana" => { + NetworkName::Solana => { debug!(target: "CASHIER DAEMON", "Add sol network"); use drk::service::SolClient; use solana_sdk::signer::keypair::Keypair; @@ -392,7 +396,7 @@ impl Cashierd { let native_sol_token_id = generate_id(native_sol_token_id)?; let main_keypairs = self .cashier_wallet - .get_main_keys(&"sol".into(), &native_sol_token_id)?; + .get_main_keys(&NetworkName::Solana, &native_sol_token_id)?; if main_keypairs.is_empty() { main_keypair = Keypair::new(); @@ -402,11 +406,11 @@ impl Cashierd { let sol_client = SolClient::new(serialize(&main_keypair), &chain).await?; - bridge2.add_clients("sol".into(), sol_client).await?; + bridge2.add_clients(NetworkName::Solana, sol_client).await?; } #[cfg(feature = "btc")] - "btc" | "bitcoin" => { + NetworkName::Bitcoin => { debug!(target: "CASHIER DAEMON", "Add btc network"); //use drk::service::btc::{BtcClient, BitcoinKeys}; @@ -417,7 +421,7 @@ impl Cashierd { let native_btc_token_id = generate_id("btc")?; let _main_keypairs = self .cashier_wallet - .get_main_keys(&"btc".into(), &native_btc_token_id)?; + .get_main_keys(&NetworkName::Bitcoin, &native_btc_token_id)?; // if main_keypairs.is_empty() { // //main_keypair = BitcoinKeys::new(bitcoin::network::constants::Network::Testnet)?; // } else { @@ -429,10 +433,6 @@ impl Cashierd { // //bridge2.add_clients("btc".into(), btc_client).await?; } - - _ => { - warn!("No feature enabled for {} network", feature_name); - } } } @@ -477,7 +477,6 @@ impl Cashierd { debug!(target: "CASHIER DAEMON", "Notification from birdge: {:?}", token_notification); // TODO should send drk coins - } } }); diff --git a/src/bin/sol-test.rs b/src/bin/sol-test.rs index 685c98f56..3d90af61e 100644 --- a/src/bin/sol-test.rs +++ b/src/bin/sol-test.rs @@ -22,7 +22,7 @@ async fn run() -> Result<()> { println!("main keypair {:?}", main_keypair.to_bytes()); println!("main pubkey {}", main_keypair.pubkey().to_string()); - let network = String::from("sol"); + let network = drk::service::NetworkName::Solana; let sol_client = SolClient::new(serialize(&main_keypair), "devnet").await?; diff --git a/src/service/bridge.rs b/src/service/bridge.rs index 34eb8fa1e..0be56c247 100644 --- a/src/service/bridge.rs +++ b/src/service/bridge.rs @@ -1,4 +1,5 @@ use crate::{Error, Result}; +use super::NetworkName; use async_trait::async_trait; use futures::stream::FuturesUnordered; @@ -9,7 +10,7 @@ use async_std::sync::{Arc, Mutex}; use std::collections::HashMap; pub struct BridgeRequests { - pub network: String, + pub network: NetworkName, pub payload: BridgeRequestsPayload, } @@ -48,14 +49,14 @@ pub struct TokenSubscribtion { #[derive(Debug)] pub struct TokenNotification { - pub network: String, + pub network: NetworkName, pub asset_id: jubjub::Fr, pub secret_key: Vec, pub received_balance: u64, } pub struct Bridge { - clients: Mutex>>, + clients: Mutex>>, notifiers: FuturesUnordered>, } @@ -69,7 +70,7 @@ impl Bridge { pub async fn add_clients( self: Arc, - network: String, + network: NetworkName, client: Arc, ) -> Result<()> { let client2 = client.clone(); @@ -78,7 +79,7 @@ impl Bridge { self.clients .lock() .await - .insert(network.clone(), client.clone()); + .insert(network, client.clone()); self.notifiers.push(notifier.clone()); Ok(()) diff --git a/src/service/mod.rs b/src/service/mod.rs index 464fc20af..07905365f 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -1,12 +1,12 @@ //pub mod cashier; +pub mod bridge; pub mod gateway; pub mod reqrep; -pub mod bridge; #[cfg(feature = "btc")] pub mod btc; #[cfg(feature = "btc")] -pub use btc::{BitcoinKeys, PubAddress, BtcFailed, BtcResult}; +pub use btc::{BitcoinKeys, BtcFailed, BtcResult, PubAddress}; #[cfg(feature = "sol")] pub mod sol; @@ -15,4 +15,53 @@ pub use sol::{SolClient, SolFailed, SolResult}; pub use gateway::{GatewayClient, GatewayService, GatewaySlabsSubscriber}; +use crate::serial::{Decodable, Encodable}; +use crate::Result; +use std::str::FromStr; +#[derive(Debug, PartialEq, Eq, Hash, Clone)] +pub enum NetworkName { + Solana, + Bitcoin, +} + +impl std::fmt::Display for NetworkName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Solana => { + write!(f, "Solana") + } + Self::Bitcoin => { + write!(f, "Bitcoin") + } + } + } +} + +impl FromStr for NetworkName { + type Err = crate::Error; + + fn from_str(s: &str) -> std::result::Result { + match s { + "sol" | "Sol" | "solana" | "Solana" | "SOLANA" => Ok(NetworkName::Solana), + "btc" | "Btc" | "bitcoin" | "Bitcoin" | "BITCOIN" => Ok(NetworkName::Bitcoin), + _ => Err(crate::Error::NotSupportedNetwork), + } + } +} + +impl Encodable for NetworkName { + fn encode(&self, s: S) -> Result { + let name = self.to_string(); + let len = name.encode(s)?; + Ok(len) + } +} + +impl Decodable for NetworkName { + fn decode(mut d: D) -> Result { + let name: String = Decodable::decode(&mut d)?; + let name = NetworkName::from_str(&name)?; + Ok(name) + } +} diff --git a/src/wallet/cashierdb.rs b/src/wallet/cashierdb.rs index e6e173879..5c51232cd 100644 --- a/src/wallet/cashierdb.rs +++ b/src/wallet/cashierdb.rs @@ -1,6 +1,7 @@ use super::{Keypair, WalletApi}; use crate::client::ClientFailed; use crate::{Error, Result}; +use crate::service::NetworkName; use async_std::sync::{Arc, Mutex}; use log::*; @@ -62,7 +63,7 @@ impl CashierDb { &self, token_key_private: &Vec, token_key_public: &Vec, - network: &String, + network: &NetworkName, token_id: &jubjub::Fr, ) -> Result<()> { debug!(target: "CASHIERDB", "Put main keys"); @@ -92,7 +93,7 @@ impl CashierDb { pub fn get_main_keys( &self, - network: &String, + network: &NetworkName, token_id: &jubjub::Fr, ) -> Result, Vec)>> { debug!(target: "CASHIERDB", "Get main keys"); @@ -129,7 +130,7 @@ impl CashierDb { token_key_public: &Vec, d_key_public: &jubjub::SubgroupPoint, d_key_private: &jubjub::Fr, - network: &String, + network: &NetworkName, token_id: &jubjub::Fr, ) -> Result<()> { debug!(target: "CASHIERDB", "Put withdraw keys"); @@ -167,7 +168,7 @@ impl CashierDb { d_key_public: &jubjub::SubgroupPoint, token_key_private: &Vec, token_key_public: &Vec, - network: &String, + network: &NetworkName, token_id: &jubjub::Fr, ) -> Result<()> { debug!(target: "CASHIERDB", "Put exchange keys"); @@ -230,7 +231,7 @@ impl CashierDb { pub fn get_withdraw_token_public_key_by_dkey_public( &self, pub_key: &jubjub::SubgroupPoint, - ) -> Result, String, jubjub::Fr)>> { + ) -> Result, NetworkName, jubjub::Fr)>> { debug!(target: "CASHIERDB", "Get token address by pub_key"); // open connection let conn = Connection::open(&self.path)?; @@ -256,7 +257,7 @@ impl CashierDb { for addr in addr_iter { let addr = addr?; let token_key_public = addr.0; - let network: String = self.get_value_deserialized(addr.1)?; + let network: NetworkName = self.get_value_deserialized(addr.1)?; let token_id: jubjub::Fr = self.get_value_deserialized(addr.2)?; token_addresses.push((token_key_public, network, token_id)); } @@ -268,7 +269,7 @@ impl CashierDb { pub fn get_deposit_token_keys_by_dkey_public( &self, d_key_public: &jubjub::SubgroupPoint, - network: &String, + network: &NetworkName, ) -> Result, Vec)>> { debug!(target: "CASHIERDB", "Check for existing dkey"); let d_key_public = self.get_value_serialized(d_key_public)?; @@ -308,7 +309,7 @@ impl CashierDb { // return private and public keys as a tuple pub fn get_deposit_token_keys_by_network( &self, - network: &String, + network: &NetworkName, ) -> Result, Vec)>> { debug!(target: "CASHIERDB", "Check for existing dkey"); // open connection @@ -342,7 +343,7 @@ impl CashierDb { pub fn get_withdraw_keys_by_token_public_key( &self, token_key_public: &Vec, - network: &String, + network: &NetworkName, ) -> Result> { debug!(target: "CASHIERDB", "Check for existing token address"); // open connection @@ -386,7 +387,7 @@ impl CashierDb { pub fn confirm_withdraw_key_record( &self, token_address: &Vec, - network: &String, + network: &NetworkName, ) -> Result<()> { debug!(target: "CASHIERDB", "Confirm withdraw keys"); @@ -412,7 +413,7 @@ impl CashierDb { pub fn confirm_deposit_key_record( &self, d_key_public: &jubjub::SubgroupPoint, - network: &String, + network: &NetworkName, ) -> Result<()> { debug!(target: "CASHIERDB", "Confirm withdraw keys"); @@ -474,7 +475,7 @@ mod tests { let token_addr = serialize(&String::from("mxVFsFW5N4mu1HPkxPttorvocvzeZ7KZyk")); let token_addr_private = serialize(&String::from("2222222222222222222222222222222222")); - let network = String::from("btc"); + let network = NetworkName::Bitcoin; let token_id: jubjub::Fr = jubjub::Fr::random(&mut OsRng); wallet.put_main_keys(&token_addr_private, &token_addr, &network, &token_id)?; @@ -502,7 +503,7 @@ mod tests { let token_addr = serialize(&String::from("mxVFsFW5N4mu1HPkxPttorvocvzeZ7KZyk")); let token_addr_private = serialize(&String::from("2222222222222222222222222222222222")); - let network = String::from("btc"); + let network = NetworkName::Bitcoin; let secret2: jubjub::Fr = jubjub::Fr::random(&mut OsRng); let public2 = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret2; @@ -548,7 +549,7 @@ mod tests { // btc addr testnet let token_addr = serialize(&String::from("mxVFsFW5N4mu1HPkxPttorvocvzeZ7KZyk")); - let network = String::from("btc"); + let network = NetworkName::Bitcoin; wallet.put_withdraw_keys(&token_addr, &public2, &secret2, &network, &token_id)?;