Просмотр исходного кода

wrap client with mutex inside cashier service

ghassmo 5 лет назад
Родитель
Сommit
4d35fc0e58
3 измененных файлов с 63 добавлено и 45 удалено
  1. 1 1
      src/bin/cashierd.rs
  2. 24 27
      src/client/client.rs
  3. 38 17
      src/service/cashier.rs

+ 1 - 1
src/bin/cashierd.rs

@@ -30,7 +30,7 @@ async fn start(executor: Arc<Executor<'_>>, config: Arc<CashierdConfig>) -> Resu
     let client_wallet_path = "cashier_client_wallet.db";
     let client_wallet_path = "cashier_client_wallet.db";
 
 
     debug!(target: "cashierd", "starting cashier service");
     debug!(target: "cashierd", "starting cashier service");
-    let cashier = CashierService::new(
+    let mut cashier = CashierService::new(
         accept_addr,
         accept_addr,
         btc_endpoint,
         btc_endpoint,
         wallet.clone(),
         wallet.clone(),

+ 24 - 27
src/client/client.rs

@@ -25,7 +25,7 @@ use bls12_381::Bls12;
 use log::*;
 use log::*;
 use rusqlite::Connection;
 use rusqlite::Connection;
 
 
-use async_std::sync::Arc;
+use async_std::sync::{Arc, Mutex};
 use futures::FutureExt;
 use futures::FutureExt;
 use std::net::SocketAddr;
 use std::net::SocketAddr;
 use std::path::PathBuf;
 use std::path::PathBuf;
@@ -36,7 +36,6 @@ pub struct Client {
     mint_params: bellman::groth16::Parameters<Bls12>,
     mint_params: bellman::groth16::Parameters<Bls12>,
     spend_params: bellman::groth16::Parameters<Bls12>,
     spend_params: bellman::groth16::Parameters<Bls12>,
     gateway: GatewayClient,
     gateway: GatewayClient,
-    connected_with_cashier: bool,
 }
 }
 
 
 impl Client {
 impl Client {
@@ -87,7 +86,6 @@ impl Client {
             mint_params,
             mint_params,
             spend_params,
             spend_params,
             gateway,
             gateway,
-            connected_with_cashier: false,
         })
         })
     }
     }
 
 
@@ -96,29 +94,6 @@ impl Client {
         Ok(())
         Ok(())
     }
     }
 
 
-    pub async fn connect_to_subscriber(
-        &mut self,
-        executor: Arc<Executor<'_>>,
-        wallet: WalletPtr,
-    ) -> Result<()> {
-        if self.connected_with_cashier {
-            warn!("The client already connected to the subscriber");
-            return Ok(());
-        }
-
-        // start subscribing
-        debug!(target: "Client", "Start subscriber");
-        let gateway_slabs_sub: GatewaySlabsSubscriber =
-            self.gateway.start_subscriber(executor.clone()).await?;
-
-        loop {
-            let slab = gateway_slabs_sub.recv().await?;
-            let tx = tx::Transaction::decode(&slab.get_payload()[..])?;
-            let update = state_transition(&self.state, tx)?;
-            self.state.apply(update, wallet.clone()).await?;
-        }
-    }
-
     pub async fn connect_to_cashier(
     pub async fn connect_to_cashier(
         &mut self,
         &mut self,
         executor: Arc<Executor<'_>>,
         executor: Arc<Executor<'_>>,
@@ -126,7 +101,6 @@ impl Client {
         cashier_addr: SocketAddr,
         cashier_addr: SocketAddr,
         rpc_url: SocketAddr,
         rpc_url: SocketAddr,
     ) -> Result<()> {
     ) -> Result<()> {
-        self.connected_with_cashier = true;
         // create cashier client
         // create cashier client
         debug!(target: "Client", "Creating cashier client");
         debug!(target: "Client", "Creating cashier client");
         let mut cashier_client = CashierClient::new(cashier_addr)?;
         let mut cashier_client = CashierClient::new(cashier_addr)?;
@@ -307,6 +281,29 @@ impl Client {
 
 
         Ok(())
         Ok(())
     }
     }
+
+    pub async fn connect_to_subscriber(
+        client: Arc<Mutex<Client>>,
+        executor: Arc<Executor<'_>>,
+        wallet: WalletPtr,
+    ) -> Result<()> {
+        // start subscribing
+        debug!(target: "Client", "Start subscriber");
+        let gateway_slabs_sub: GatewaySlabsSubscriber = client
+            .lock()
+            .await
+            .gateway
+            .start_subscriber(executor.clone())
+            .await?;
+
+        loop {
+            let slab = gateway_slabs_sub.recv().await?;
+            let tx = tx::Transaction::decode(&slab.get_payload()[..])?;
+            let mut client = client.lock().await;
+            let update = state_transition(&client.state, tx)?;
+            client.state.apply(update, wallet.clone()).await?;
+        }
+    }
 }
 }
 
 
 pub struct State {
 pub struct State {

+ 38 - 17
src/service/cashier.rs

@@ -3,8 +3,7 @@ use super::reqrep::{PeerId, RepProtocol, Reply, ReqProtocol, Request};
 use crate::blockchain::Rocks;
 use crate::blockchain::Rocks;
 use crate::client::Client;
 use crate::client::Client;
 use crate::serial::{deserialize, serialize};
 use crate::serial::{deserialize, serialize};
-use crate::wallet::CashierDbPtr;
-use crate::wallet::WalletDb;
+use crate::wallet::{CashierDbPtr, WalletDb};
 use crate::{Error, Result};
 use crate::{Error, Result};
 
 
 use ff::Field;
 use ff::Field;
@@ -15,7 +14,7 @@ use async_executor::Executor;
 use electrum_client::Client as ElectrumClient;
 use electrum_client::Client as ElectrumClient;
 use log::*;
 use log::*;
 
 
-use async_std::sync::Arc;
+use async_std::sync::{Arc, Mutex};
 use std::net::SocketAddr;
 use std::net::SocketAddr;
 use std::path::PathBuf;
 use std::path::PathBuf;
 
 
@@ -34,7 +33,7 @@ pub struct CashierService {
     addr: SocketAddr,
     addr: SocketAddr,
     wallet: CashierDbPtr,
     wallet: CashierDbPtr,
     btc_client: Arc<ElectrumClient>,
     btc_client: Arc<ElectrumClient>,
-    client: Client,
+    client: Arc<Mutex<Client>>,
 }
 }
 
 
 impl CashierService {
 impl CashierService {
@@ -46,7 +45,7 @@ impl CashierService {
         gateway_addrs: (SocketAddr, SocketAddr),
         gateway_addrs: (SocketAddr, SocketAddr),
         params_paths: (PathBuf, PathBuf),
         params_paths: (PathBuf, PathBuf),
         client_wallet_path: PathBuf,
         client_wallet_path: PathBuf,
-    ) -> Result<Arc<CashierService>> {
+    ) -> Result<CashierService> {
         // Load trusted setup parameters
         // Load trusted setup parameters
 
 
         // Pull address from config later
         // Pull address from config later
@@ -61,7 +60,6 @@ impl CashierService {
         let cashier_secret = wallet.get_cashier_private()?;
         let cashier_secret = wallet.get_cashier_private()?;
         let rocks = Rocks::new(&cashier_database_path)?;
         let rocks = Rocks::new(&cashier_database_path)?;
 
 
-        // TODO find a way to start the connection and subscribe to gateway
         let client = Client::new(
         let client = Client::new(
             cashier_secret,
             cashier_secret,
             rocks,
             rocks,
@@ -70,14 +68,16 @@ impl CashierService {
             client_wallet_path.clone(),
             client_wallet_path.clone(),
         )?;
         )?;
 
 
-        Ok(Arc::new(CashierService {
+        let client = Arc::new(Mutex::new(client));
+
+        Ok(CashierService {
             addr,
             addr,
             wallet,
             wallet,
             btc_client,
             btc_client,
             client,
             client,
-        }))
+        })
     }
     }
-    pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
+    pub async fn start(&mut self, executor: Arc<Executor<'_>>) -> Result<()> {
         debug!(target: "Cashier", "Start Cashier");
         debug!(target: "Cashier", "Start Cashier");
         let service_name = String::from("CASHIER DAEMON");
         let service_name = String::from("CASHIER DAEMON");
 
 
@@ -85,17 +85,39 @@ impl CashierService {
 
 
         let (send, recv) = protocol.start().await?;
         let (send, recv) = protocol.start().await?;
 
 
-        let handle_request_task =
-            executor.spawn(self.handle_request_loop(send.clone(), recv.clone(), executor.clone()));
+        let wallet = self.wallet.clone();
+        let btc_client = self.btc_client.clone();
+
+        let handle_request_task = executor.spawn(Self::handle_request_loop(
+            send.clone(),
+            recv.clone(),
+            wallet.clone(),
+            btc_client.clone(),
+            executor.clone(),
+        ));
+
+        self.client.lock().await.start().await?;
+
+        // this for test
+        let client_wallet = Arc::new(WalletDb::new(
+            &PathBuf::from("cashier_client_wallet.db"),
+            "123".into(),
+        )?);
+
+        let cashier_client_subscriber_task = executor.spawn(Client::connect_to_subscriber(
+            self.client.clone(),
+            executor.clone(),
+            client_wallet,
+        ));
 
 
         protocol.run(executor.clone()).await?;
         protocol.run(executor.clone()).await?;
 
 
         let _ = handle_request_task.cancel().await;
         let _ = handle_request_task.cancel().await;
+        let _ = cashier_client_subscriber_task.cancel().await;
 
 
         Ok(())
         Ok(())
     }
     }
 
 
-
     //async fn mint_dbtc(&mut self, dkey_pub: jubjub::SubgroupPoint, value: u64) -> Result<()> {
     //async fn mint_dbtc(&mut self, dkey_pub: jubjub::SubgroupPoint, value: u64) -> Result<()> {
     //    let cashier_secret = self.wallet.get_cashier_private().unwrap();
     //    let cashier_secret = self.wallet.get_cashier_private().unwrap();
 
 
@@ -130,21 +152,20 @@ impl CashierService {
     //}
     //}
 
 
     async fn handle_request_loop(
     async fn handle_request_loop(
-        self: Arc<Self>,
         send_queue: async_channel::Sender<(PeerId, Reply)>,
         send_queue: async_channel::Sender<(PeerId, Reply)>,
         recv_queue: async_channel::Receiver<(PeerId, Request)>,
         recv_queue: async_channel::Receiver<(PeerId, Request)>,
+        wallet: CashierDbPtr,
+        btc_client: Arc<ElectrumClient>,
         executor: Arc<Executor<'_>>,
         executor: Arc<Executor<'_>>,
     ) -> Result<()> {
     ) -> Result<()> {
         loop {
         loop {
             match recv_queue.recv().await {
             match recv_queue.recv().await {
                 Ok(msg) => {
                 Ok(msg) => {
-                    let cashier_wallet = self.wallet.clone();
-                    let btc_client = self.btc_client.clone();
                     let _ = executor
                     let _ = executor
                         .spawn(Self::handle_request(
                         .spawn(Self::handle_request(
                             msg,
                             msg,
-                            btc_client,
-                            cashier_wallet,
+                            btc_client.clone(),
+                            wallet.clone(),
                             send_queue.clone(),
                             send_queue.clone(),
                             executor.clone(),
                             executor.clone(),
                         ))
                         ))