Procházet zdrojové kódy

remove hardcoded network name across the project and use enum instead

ghassmo před 4 roky
rodič
revize
b90d2c09a1
5 změnil soubory, kde provedl 101 přidání a 51 odebrání
  1. 28 29
      src/bin/cashierd.rs
  2. 1 1
      src/bin/sol-test.rs
  3. 6 5
      src/service/bridge.rs
  4. 51 2
      src/service/mod.rs
  5. 15 14
      src/wallet/cashierdb.rs

+ 28 - 29
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<Bridge>,
     cashier_wallet: Arc<CashierDb>,
-    features: HashMap<String, String>,
+    features: HashMap<NetworkName, String>,
     client: Arc<Mutex<Client>>,
 }
 
@@ -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<Bridge>,
         cashier_wallet: Arc<CashierDb>,
-        features: HashMap<String, String>,
+        features: HashMap<NetworkName, String>,
     ) -> 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::<HashMap<String, String>>()),
+            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
-                
                 }
             }
         });

+ 1 - 1
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?;
 

+ 6 - 5
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<u8>,
     pub received_balance: u64,
 }
 
 pub struct Bridge {
-    clients: Mutex<HashMap<String, Arc<dyn NetworkClient + Send + Sync>>>,
+    clients: Mutex<HashMap<NetworkName, Arc<dyn NetworkClient + Send + Sync>>>,
     notifiers: FuturesUnordered<async_channel::Receiver<TokenNotification>>,
 }
 
@@ -69,7 +70,7 @@ impl Bridge {
 
     pub async fn add_clients(
         self: Arc<Self>,
-        network: String,
+        network: NetworkName,
         client: Arc<dyn NetworkClient + Send + Sync>,
     ) -> 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(())

+ 51 - 2
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<Self, Self::Err> {
+        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<S: std::io::Write>(&self, s: S) -> Result<usize> {
+        let name = self.to_string();
+        let len = name.encode(s)?;
+        Ok(len)
+    }
+}
 
+impl Decodable for NetworkName {
+    fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
+        let name: String = Decodable::decode(&mut d)?;
+        let name = NetworkName::from_str(&name)?;
+        Ok(name)
+    }
+}

+ 15 - 14
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<u8>,
         token_key_public: &Vec<u8>,
-        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<(Vec<u8>, Vec<u8>)>> {
         debug!(target: "CASHIERDB", "Get main keys");
@@ -129,7 +130,7 @@ impl CashierDb {
         token_key_public: &Vec<u8>,
         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<u8>,
         token_key_public: &Vec<u8>,
-        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<Option<(Vec<u8>, String, jubjub::Fr)>> {
+    ) -> Result<Option<(Vec<u8>, 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<(Vec<u8>, Vec<u8>)>> {
         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<(Vec<u8>, Vec<u8>)>> {
         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<u8>,
-        network: &String,
+        network: &NetworkName,
     ) -> Result<Option<Keypair>> {
         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<u8>,
-        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)?;