Explorar o código

sol: Don't hardcode network endpoints.

parazyd %!s(int64=4) %!d(string=hai) anos
pai
achega
5e9a87eed9
Modificáronse 4 ficheiros con 138 adicións e 118 borrados
  1. 1 1
      example/config/cashierd.toml
  2. 105 98
      src/bin/cashierd.rs
  3. 1 1
      src/bin/sol-test.rs
  4. 31 18
      src/service/sol.rs

+ 1 - 1
example/config/cashierd.toml

@@ -47,7 +47,7 @@ database_path = "~/.config/darkfi/cashier_database.db"
 # The configured networks to use.
 [[networks]]
 name = "sol"
-blockchain = "testnet"
+blockchain = "devnet"
 
 [[networks]]
 name = "btc"

+ 105 - 98
src/bin/cashierd.rs

@@ -111,98 +111,6 @@ impl Cashierd {
         })
     }
 
-    async fn start(&self, executor: Arc<Executor<'static>>) -> Result<()> {
-        self.cashier_wallet.init_db().await?;
-
-        for (feature_name, _) in self.features.iter() {
-            let bridge2 = self.bridge.clone();
-            match feature_name.as_str() {
-                #[cfg(feature = "sol")]
-                "sol" | "solana" => {
-                    debug!(target: "CASHIER DAEMON", "Add sol network");
-                    use drk::service::SolClient;
-                    use solana_sdk::signer::keypair::Keypair;
-                    let main_keypair: Keypair;
-
-                    let main_keypairs = self.cashier_wallet.get_main_keys(&"sol".into())?;
-                    if main_keypairs.is_empty() {
-                        main_keypair = Keypair::new();
-                    } else {
-                        main_keypair = deserialize(&main_keypairs[0].0)?;
-                    }
-
-                    let sol_client = SolClient::new(serialize(&main_keypair)).await?;
-
-                    bridge2.add_clients("sol".into(), sol_client).await?;
-                }
-                #[cfg(feature = "btc")]
-                "btc" | "bitcoin" => {
-                    debug!(target: "CASHIER DAEMON", "Add btc network");
-                    let btc_endpoint: (bitcoin::network::constants::Network, String) = (
-                        bitcoin::network::constants::Network::Bitcoin,
-                        String::from("ssl://blockstream.info:993"),
-                    );
-                    use drk::service::btc::BtcClient;
-                    let _btc_client = BtcClient::new(btc_endpoint)?;
-                    // NOTE bitcoin is not implemented yet
-                    //
-                    // TODO check if there is main_keypair inside
-                    // cashierdb before generating new one
-                    //
-                    //bridge2.add_clients("btc".into(), btc_client).await?;
-                }
-                _ => {
-                    warn!("No feature enabled for {} network", feature_name);
-                }
-            }
-        }
-
-        let resume_watch_deposit_keys_task = executor.spawn(Self::resume_watch_deposit_keys(
-            self.bridge.clone(),
-            self.cashier_wallet.clone(),
-            self.features.clone(),
-        ));
-
-        self.client.lock().await.start().await?;
-
-        let (notify, recv_coin) = async_channel::unbounded::<(jubjub::SubgroupPoint, u64)>();
-        let cashier_client_subscriber_task =
-            smol::spawn(Client::connect_to_subscriber_from_cashier(
-                self.client.clone(),
-                executor.clone(),
-                self.cashier_wallet.clone(),
-                notify.clone(),
-            ));
-
-        let cashier_wallet = self.cashier_wallet.clone();
-        let bridge = self.bridge.clone();
-        let listen_for_receiving_coins_task = smol::spawn(async move {
-            loop {
-                Self::listen_for_receiving_coins(
-                    bridge.clone(),
-                    cashier_wallet.clone(),
-                    recv_coin.clone(),
-                )
-                .await
-                .expect(" listen for receiving coins");
-            }
-        });
-
-        let cfg = RpcServerConfig {
-            socket_addr: self.config.rpc_listen_address.clone(),
-            use_tls: self.config.serve_tls,
-            identity_path: expand_path(&self.config.clone().tls_identity_path)?,
-            identity_pass: self.config.tls_identity_password.clone(),
-        };
-
-        listen_and_serve(cfg, self.clone()).await?;
-
-        resume_watch_deposit_keys_task.cancel().await;
-        listen_for_receiving_coins_task.cancel().await;
-        cashier_client_subscriber_task.cancel().await;
-        Ok(())
-    }
-
     async fn resume_watch_deposit_keys(
         bridge: Arc<Bridge>,
         cashier_wallet: Arc<CashierDb>,
@@ -432,21 +340,24 @@ impl Cashierd {
         JsonResult::Resp(jsonresp(json!(self.features), id))
     }
 
-    fn check_token_id(network: &str, _token_id: &str) -> Result<()> {
+    fn check_token_id(network: &str, token_id: &str) -> Result<()> {
         match network {
             #[cfg(feature = "sol")]
             "sol" | "solana" => {
-                if _token_id != "So11111111111111111111111111111111111111112" {
+                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;
 
-                    if !account_is_initialized_mint(
-                        &Pubkey::from_str(_token_id)
-                            .map_err(|err| Error::from(BadSolAddress(err.to_string())))?,
-                    ) {
+                    let pubkey = match Pubkey::from_str(token_id) {
+                        Ok(v) => v,
+                        Err(e) => return Err(Error::from(BadSolAddress(e.to_string()))),
+                    };
+
+                    // FIXME: Use network name from variable
+                    if !account_is_initialized_mint("devnet".to_string(), &pubkey) {
                         return Err(Error::CashierInvalidTokenId(
                             "Given address is not a valid token mint".into(),
                         ));
@@ -461,6 +372,102 @@ impl Cashierd {
         }
         Ok(())
     }
+
+    async fn start(&self, executor: Arc<Executor<'static>>) -> Result<()> {
+        self.cashier_wallet.init_db().await?;
+
+        for (feature_name, chain) in self.features.iter() {
+            let bridge2 = self.bridge.clone();
+
+            match feature_name.as_str() {
+                #[cfg(feature = "sol")]
+                "sol" | "solana" => {
+                    debug!(target: "CASHIER DAEMON", "Add sol network");
+                    use drk::service::SolClient;
+                    use solana_sdk::signer::keypair::Keypair;
+
+                    let main_keypair: Keypair;
+
+                    let main_keypairs = self.cashier_wallet.get_main_keys(&"sol".into())?;
+                    if main_keypairs.is_empty() {
+                        main_keypair = Keypair::new();
+                    } else {
+                        main_keypair = deserialize(&main_keypairs[0].0)?;
+                    }
+
+                    let sol_client = SolClient::new(serialize(&main_keypair), &chain).await?;
+
+                    bridge2.add_clients("sol".into(), sol_client).await?;
+                }
+
+                #[cfg(feature = "btc")]
+                "btc" | "bitcoin" => {
+                    debug!(target: "CASHIER DAEMON", "Add btc network");
+                    let btc_endpoint: (bitcoin::network::constants::Network, String) = (
+                        bitcoin::network::constants::Network::Bitcoin,
+                        String::from("ssl://blockstream.info:993"),
+                    );
+                    use drk::service::btc::BtcClient;
+                    let _btc_client = BtcClient::new(btc_endpoint)?;
+                    // NOTE bitcoin is not implemented yet
+                    //
+                    // TODO check if there is main_keypair inside
+                    // cashierdb before generating new one
+                    //
+                    //bridge2.add_clients("btc".into(), btc_client).await?;
+                }
+
+                _ => {
+                    warn!("No feature enabled for {} network", feature_name);
+                }
+            }
+        }
+
+        let resume_watch_deposit_keys_task = executor.spawn(Self::resume_watch_deposit_keys(
+            self.bridge.clone(),
+            self.cashier_wallet.clone(),
+            self.features.clone(),
+        ));
+
+        self.client.lock().await.start().await?;
+
+        let (notify, recv_coin) = async_channel::unbounded::<(jubjub::SubgroupPoint, u64)>();
+        let cashier_client_subscriber_task =
+            smol::spawn(Client::connect_to_subscriber_from_cashier(
+                self.client.clone(),
+                executor.clone(),
+                self.cashier_wallet.clone(),
+                notify.clone(),
+            ));
+
+        let cashier_wallet = self.cashier_wallet.clone();
+        let bridge = self.bridge.clone();
+        let listen_for_receiving_coins_task = smol::spawn(async move {
+            loop {
+                Self::listen_for_receiving_coins(
+                    bridge.clone(),
+                    cashier_wallet.clone(),
+                    recv_coin.clone(),
+                )
+                .await
+                .expect(" listen for receiving coins");
+            }
+        });
+
+        let cfg = RpcServerConfig {
+            socket_addr: self.config.rpc_listen_address.clone(),
+            use_tls: self.config.serve_tls,
+            identity_path: expand_path(&self.config.clone().tls_identity_path)?,
+            identity_pass: self.config.tls_identity_password.clone(),
+        };
+
+        listen_and_serve(cfg, self.clone()).await?;
+
+        resume_watch_deposit_keys_task.cancel().await;
+        listen_for_receiving_coins_task.cancel().await;
+        cashier_client_subscriber_task.cancel().await;
+        Ok(())
+    }
 }
 
 #[async_std::main]

+ 1 - 1
src/bin/sol-test.rs

@@ -24,7 +24,7 @@ async fn run() -> Result<()> {
 
     let network = String::from("sol");
 
-    let sol_client = SolClient::new(serialize(&main_keypair)).await?;
+    let sol_client = SolClient::new(serialize(&main_keypair), "devnet").await?;
 
     bridge
         .clone()

+ 31 - 18
src/service/sol.rs

@@ -24,13 +24,6 @@ use std::convert::TryFrom;
 use std::str::FromStr;
 use tungstenite::Message;
 
-//const RPC_SERVER: &str = "https://api.mainnet-beta.solana.com";
-//const WSS_SERVER: &str = "wss://api.mainnet-beta.solana.com";
-const RPC_SERVER: &str = "https://api.devnet.solana.com";
-const WSS_SERVER: &str = "wss://api.devnet.solana.com";
-//const RPC_SERVER: &str = "http://localhost:8899";
-//const WSS_SERVER: &str = "ws://localhost:8900";
-
 #[derive(Serialize)]
 struct SubscribeParams {
     encoding: Value,
@@ -39,24 +32,44 @@ struct SubscribeParams {
 
 pub struct SolClient {
     keypair: Keypair,
-    // subscriptions vecotr of puykey
+    // Subscriptions vector of pubkey
     subscriptions: Arc<Mutex<Vec<Pubkey>>>,
     notify_channel: (
         async_channel::Sender<TokenNotification>,
         async_channel::Receiver<TokenNotification>,
     ),
+    rpc_server: &'static str,
+    wss_server: &'static str,
 }
 
 impl SolClient {
-    pub async fn new(keypair: Vec<u8>) -> Result<Arc<Self>> {
+    pub async fn new(keypair: Vec<u8>, network: &str) -> Result<Arc<Self>> {
         let keypair: Keypair = deserialize(&keypair)?;
-
         let notify_channel = async_channel::unbounded();
 
+        let (rpc_server, wss_server) = match network {
+            "mainnet" => (
+                "https://api.mainnet-beta.solana.com",
+                "wss://api.devnet.solana.com",
+            ),
+            "devnet" => (
+                "https://api.devnet.solana.com",
+                "wss://api.devnet.solana.com",
+            ),
+            "testnet" => (
+                "https://api.testnet.solana.com",
+                "wss://api.testnet.solana.com",
+            ),
+            "localhost" => ("http://localhost:8899", "ws://localhost:8900"),
+            _ => return Err(Error::NotSupportedNetwork),
+        };
+
         Ok(Arc::new(Self {
             keypair,
             subscriptions: Arc::new(Mutex::new(Vec::new())),
             notify_channel,
+            rpc_server,
+            wss_server,
         }))
     }
 
@@ -66,7 +79,7 @@ impl SolClient {
             "sending received token to main account"
         );
 
-        let rpc = RpcClient::new(RPC_SERVER.to_string());
+        let rpc = RpcClient::new(self.rpc_server.to_string());
 
         let fee = rpc
             .get_fees()
@@ -122,7 +135,7 @@ impl SolClient {
             json!([json!(keypair.pubkey().to_string()), json!(sub_params)]),
         );
 
-        let rpc = RpcClient::new(RPC_SERVER.to_string());
+        let rpc = RpcClient::new(self.rpc_server.to_string());
         let old_balance = rpc
             .get_balance(&keypair.pubkey())
             .map_err(|err| SolFailed::from(err))?;
@@ -130,8 +143,7 @@ impl SolClient {
         // WebSocket handshake/connect
         let builder = native_tls::TlsConnector::builder();
         let tls = TlsConnector::from(builder);
-        let (stream, _) = connect(WSS_SERVER, tls).await?;
-
+        let (stream, _) = connect(self.wss_server, tls).await?;
 
         let (mut write, mut read) = stream.split();
 
@@ -139,7 +151,8 @@ impl SolClient {
 
         let unsubscribe_channel_rv2 = unsubscribe_channel_rv.clone();
         let ws_write_task: smol::Task<Result<()>> = smol::spawn(async move {
-            write.send(Message::text(serde_json::to_string(&sub_msg)?))
+            write
+                .send(Message::text(serde_json::to_string(&sub_msg)?))
                 .await
                 .map_err(|err| SolFailed::from(err))?;
 
@@ -362,7 +375,7 @@ impl NetworkClient for SolClient {
     }
 
     async fn send(self: Arc<Self>, address: Vec<u8>, amount: u64) -> Result<()> {
-        let rpc = RpcClient::new(RPC_SERVER.to_string());
+        let rpc = RpcClient::new(self.rpc_server.to_string());
         let address: Pubkey = deserialize(&address)?;
         let instruction = system_instruction::transfer(&self.keypair.pubkey(), &address, amount);
 
@@ -397,8 +410,8 @@ pub fn get_associated_token_account(owner: &Pubkey, mint: &Pubkey) -> (Pubkey, u
 }
 
 /// Check if given account is a valid token mint
-pub fn account_is_initialized_mint(mint: &Pubkey) -> bool {
-    let rpc = RpcClient::new(RPC_SERVER.to_string());
+pub fn account_is_initialized_mint(rpc_server: String, mint: &Pubkey) -> bool {
+    let rpc = RpcClient::new(rpc_server);
     match rpc.get_token_supply(mint) {
         Ok(_) => return true,
         Err(_) => return false,