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

cashierd: send drk coins once received a notification from bridge

ghassmo 4 лет назад
Родитель
Сommit
fbafdfe8c2
8 измененных файлов с 99 добавлено и 50 удалено
  1. 29 20
      src/bin/cashierd.rs
  2. 5 5
      src/bin/darkfid.rs
  3. 0 0
      src/bin/sol-test
  4. 4 5
      src/client/client.rs
  5. 9 7
      src/service/bridge.rs
  6. 6 1
      src/service/btc.rs
  7. 36 3
      src/service/sol.rs
  8. 10 9
      src/wallet/cashierdb.rs

+ 29 - 20
src/bin/cashierd.rs

@@ -120,10 +120,11 @@ impl Cashierd {
         for (network, _) in features.iter() {
             let keypairs_to_watch = cashier_wallet.get_deposit_token_keys_by_network(&network)?;
 
-            for (private_key, public_key, _token_id, mint_address) in keypairs_to_watch {
+            for (drk_pub_key, private_key, public_key, _token_id, mint_address) in keypairs_to_watch
+            {
                 let bridge = bridge.clone();
 
-                let bridge_subscribtion = bridge.subscribe(Some(mint_address)).await;
+                let bridge_subscribtion = bridge.subscribe(drk_pub_key, Some(mint_address)).await;
 
                 bridge_subscribtion
                     .sender
@@ -157,8 +158,7 @@ impl Cashierd {
         // send a request to bridge to send equivalent amount of
         // received drk coin to token publickey
         if let Some((addr, network, _token_id, mint_address)) = token {
-
-            let bridge_subscribtion = bridge.subscribe(Some(mint_address)).await;
+            let bridge_subscribtion = bridge.subscribe(drk_pub_key, Some(mint_address)).await;
 
             bridge_subscribtion
                 .sender
@@ -175,7 +175,6 @@ impl Cashierd {
             if error_code == 0 {
                 match res.payload {
                     bridge::BridgeResponsePayload::Send => {
-                        // TODO Send the received coins to the main address
                         cashier_wallet.confirm_withdraw_key_record(&addr, &network)?;
                     }
                     _ => {}
@@ -227,7 +226,7 @@ impl Cashierd {
                 .get_deposit_token_keys_by_dkey_public(&drk_pub_key, &network)?;
 
             let bridge = self.bridge.clone();
-            let bridge_subscribtion = bridge.subscribe(mint_address_opt).await;
+            let bridge_subscribtion = bridge.subscribe(drk_pub_key, mint_address_opt).await;
 
             if check.is_empty() {
                 bridge_subscribtion
@@ -458,31 +457,41 @@ impl Cashierd {
 
         let cashier_wallet = self.cashier_wallet.clone();
         let bridge = self.bridge.clone();
-        let listen_for_receiving_coins_task = smol::spawn(async move {
+        let listen_for_receiving_coins_task: smol::Task<Result<()>> = smol::spawn(async move {
             loop {
                 Self::listen_for_receiving_coins(
                     bridge.clone(),
                     cashier_wallet.clone(),
                     recv_coin.clone(),
                 )
-                .await
-                .expect(" listen for receiving coins");
+                .await?;
             }
         });
 
         let bridge2 = self.bridge.clone();
-        let listen_for_notification_from_bridge_task = smol::spawn(async move {
-            loop {
-                if let Some(token_notification) = bridge2.clone().listen().await {
-                    let token_notification =
-                        token_notification.expect("listen for notification from bridge");
-
-                    debug!(target: "CASHIER DAEMON", "Notification from birdge: {:?}", token_notification);
-
-                    // TODO should send drk coins
+        let client2 = self.client.clone();
+        let listen_for_notification_from_bridge_task: smol::Task<Result<()>> = smol::spawn(
+            async move {
+                loop {
+                    if let Some(token_notification) = bridge2.clone().listen().await {
+                        let token_notification = token_notification?;
+
+                        debug!(target: "CASHIER DAEMON", "Notification from birdge: {:?}", token_notification);
+
+                        client2
+                            .lock()
+                            .await
+                            .send(
+                                token_notification.drk_pub_key,
+                                token_notification.received_balance,
+                                token_notification.token_id,
+                                true,
+                            )
+                            .await?;
+                    }
                 }
-            }
-        });
+            },
+        );
 
         let cfg = RpcServerConfig {
             socket_addr: self.config.rpc_listen_address.clone(),

+ 5 - 5
src/bin/darkfid.rs

@@ -17,9 +17,7 @@ use drk::{
         rpcserver::{listen_and_serve, RequestHandler, RpcServerConfig},
     },
     serial::{deserialize, serialize},
-    util::{
-        expand_path, join_config_path, parse_network, parse_wrapped_token, search_id,
-    },
+    util::{expand_path, join_config_path, parse_network, parse_wrapped_token, search_id},
     wallet::WalletDb,
     Result,
 };
@@ -78,7 +76,8 @@ impl Darkfid {
                 expand_path(&config.spend_params_path.clone())?,
             ),
             wallet.clone(),
-        ).await?;
+        )
+        .await?;
 
         let client = Arc::new(Mutex::new(client));
 
@@ -334,10 +333,11 @@ impl Darkfid {
             let token_id = parse_wrapped_token(token)?;
             let address = bs58::decode(&address).into_vec()?;
             let address: jubjub::SubgroupPoint = deserialize(&address)?;
+            // TODO FIX THE AMOUNT
             self.client
                 .lock()
                 .await
-                .transfer(token_id, address, amount)
+                .transfer(token_id, address, amount as u64)
                 .await?;
             Ok(())
         }

+ 0 - 0
src/bin/sol-test.rs → src/bin/sol-test


+ 4 - 5
src/client/client.rs

@@ -112,14 +112,13 @@ impl Client {
         &mut self,
         asset_id: jubjub::Fr,
         pub_key: jubjub::SubgroupPoint,
-        // TODO: FIX THIS
-        amount: f64,
+        amount: u64,
     ) -> Result<()> {
-        if amount <= 0.0 {
+        if amount <= 0 {
             return Err(ClientFailed::InvalidAmount(amount as u64).into());
         }
 
-        self.send(pub_key, amount as u64, asset_id, false).await?;
+        self.send(pub_key, amount, asset_id, false).await?;
 
         Ok(())
     }
@@ -150,7 +149,7 @@ impl Client {
         let mut outputs: Vec<tx::TransactionBuilderOutputInfo> = vec![];
 
         if clear_input {
-            let signature_secret = self.state.wallet.get_keypairs()?[0].private;
+            let signature_secret = self.main_keypair.private;
             let input = tx::TransactionBuilderClearInputInfo {
                 value,
                 asset_id,

+ 9 - 7
src/service/bridge.rs

@@ -50,8 +50,8 @@ pub struct TokenSubscribtion {
 #[derive(Debug)]
 pub struct TokenNotification {
     pub network: NetworkName,
-    pub asset_id: jubjub::Fr,
-    pub secret_key: Vec<u8>,
+    pub token_id: jubjub::Fr,
+    pub drk_pub_key: jubjub::SubgroupPoint,
     pub received_balance: u64,
 }
 
@@ -93,12 +93,12 @@ impl Bridge {
             .map(|o| o.map_err(Error::from))
     }
 
-    pub async fn subscribe(self: Arc<Self>, mint: Option<String>) -> BridgeSubscribtion {
+    pub async fn subscribe(self: Arc<Self>, drk_pub_key: jubjub::SubgroupPoint, mint: Option<String>) -> BridgeSubscribtion {
         debug!(target: "BRIDGE", "Start new subscription");
         let (sender, req) = async_channel::unbounded();
         let (rep, receiver) = async_channel::unbounded();
 
-        smol::spawn(self.listen_for_new_subscription(req, rep, mint)).detach();
+        smol::spawn(self.listen_for_new_subscription(req, rep, drk_pub_key, mint)).detach();
 
         BridgeSubscribtion { sender, receiver }
     }
@@ -107,6 +107,7 @@ impl Bridge {
         self: Arc<Self>,
         req: async_channel::Receiver<BridgeRequests>,
         rep: async_channel::Sender<BridgeResponse>,
+        drk_pub_key: jubjub::SubgroupPoint,
         mint: Option<String>,
     ) -> Result<()> {
         debug!(target: "BRIDGE", "Listen for new subscription");
@@ -142,7 +143,7 @@ impl Bridge {
             BridgeRequestsPayload::Watch(val) => match val {
                 Some((private_key, public_key)) => {
                     let pub_key = client
-                        .subscribe_with_keypair(private_key, public_key, mint_address)
+                        .subscribe_with_keypair(private_key, public_key, drk_pub_key, mint_address)
                         .await?;
                     let res = BridgeResponse {
                         error: BridgeResponseError::NoError,
@@ -151,7 +152,7 @@ impl Bridge {
                     rep.send(res).await?;
                 }
                 None => {
-                    let sub = client.subscribe(mint_address).await?;
+                    let sub = client.subscribe(drk_pub_key, mint_address).await?;
                     let res = BridgeResponse {
                         error: BridgeResponseError::NoError,
                         payload: BridgeResponsePayload::Watch(sub.secret_key, sub.public_key),
@@ -175,13 +176,14 @@ impl Bridge {
 
 #[async_trait]
 pub trait NetworkClient {
-    async fn subscribe(self: Arc<Self>, mint: Option<String>) -> Result<TokenSubscribtion>;
+    async fn subscribe(self: Arc<Self>, drk_pub_key: jubjub::SubgroupPoint, mint: Option<String>) -> Result<TokenSubscribtion>;
 
     // should check if the keypair in not already subscribed
     async fn subscribe_with_keypair(
         self: Arc<Self>,
         private_key: Vec<u8>,
         public_key: Vec<u8>,
+        drk_pub_key: jubjub::SubgroupPoint,
         mint: Option<String>,
     ) -> Result<String>;
 

+ 6 - 1
src/service/btc.rs

@@ -149,7 +149,11 @@ impl BtcClient {
 
 #[async_trait]
 impl NetworkClient for BtcClient {
-    async fn subscribe(self: Arc<Self>, _mint: Option<String>) -> Result<TokenSubscribtion> {
+    async fn subscribe(
+        self: Arc<Self>,
+        _drk_pub_key: jubjub::SubgroupPoint,
+        _mint: Option<String>,
+    ) -> Result<TokenSubscribtion> {
         // Generate bitcoin keys
         let btc_keys = BitcoinKeys::new(self.network)?;
         let btc_privkey = btc_keys.clone();
@@ -174,6 +178,7 @@ impl NetworkClient for BtcClient {
         self: Arc<Self>,
         _private_key: Vec<u8>,
         _public_key: Vec<u8>,
+        _drk_pub_key: jubjub::SubgroupPoint,
         _mint: Option<String>,
     ) -> Result<String> {
         // TODO this not implemented yet

+ 36 - 3
src/service/sol.rs

@@ -24,10 +24,13 @@ use tungstenite::Message;
 
 use crate::rpc::{jsonrpc, jsonrpc::JsonResult, websockets};
 use crate::serial::{deserialize, serialize, Decodable, Encodable};
+use crate::util::{generate_id, NetworkName};
 use crate::{Error, Result};
 
 use super::bridge::{NetworkClient, TokenNotification, TokenSubscribtion};
 
+pub const SOL_NATIVE_TOKEN_ID: &str = "So11111111111111111111111111111111111111112";
+
 #[derive(Serialize)]
 struct SubscribeParams {
     encoding: Value,
@@ -85,6 +88,7 @@ impl SolClient {
     async fn handle_subscribe_request(
         self: Arc<Self>,
         keypair: Keypair,
+        drk_pub_key: jubjub::SubgroupPoint,
         mint: Option<Pubkey>,
     ) -> SolResult<()> {
         debug!(target: "SOL BRIDGE", "handle_subscribe_request()");
@@ -200,11 +204,35 @@ impl SolClient {
         if mint.is_some() {
             let amnt = cur_balance - prev_balance;
             let ui_amnt = amnt / u64::pow(10, decimals as u32);
+
+            self.notify_channel
+                .0
+                .send(TokenNotification {
+                    network: NetworkName::Solana,
+                    token_id: generate_id(&mint.unwrap().to_string())?,
+                    drk_pub_key,
+                    received_balance: amnt,
+                })
+                .await
+                .map_err(Error::from)?;
+
             debug!(target: "SOL BRIDGE", "Received {} {:?} tokens", ui_amnt, mint.unwrap());
             let _ = self.send_tok_to_main_wallet(&rpc, &mint.unwrap(), amnt, decimals, &keypair)?;
         } else {
             let amnt = cur_balance - prev_balance;
             let ui_amnt = lamports_to_sol(amnt);
+
+            self.notify_channel
+                .0
+                .send(TokenNotification {
+                    network: NetworkName::Solana,
+                    token_id: generate_id(SOL_NATIVE_TOKEN_ID)?,
+                    drk_pub_key,
+                    received_balance: amnt,
+                })
+                .await
+                .map_err(Error::from)?;
+
             debug!(target: "SOL BRIDGE", "Received {} SOL", ui_amnt);
             let _ = self.send_sol_to_main_wallet(&rpc, amnt, &keypair)?;
         }
@@ -329,7 +357,11 @@ impl SolClient {
 
 #[async_trait]
 impl NetworkClient for SolClient {
-    async fn subscribe(self: Arc<Self>, mint_address: Option<String>) -> Result<TokenSubscribtion> {
+    async fn subscribe(
+        self: Arc<Self>,
+        drk_pub_key: jubjub::SubgroupPoint,
+        mint_address: Option<String>,
+    ) -> Result<TokenSubscribtion> {
         let keypair = Keypair::generate(&mut OsRng);
 
         let public_key = keypair.pubkey().to_string();
@@ -337,7 +369,7 @@ impl NetworkClient for SolClient {
 
         let mint = self.check_mint_address(mint_address)?;
 
-        smol::spawn(self.handle_subscribe_request(keypair, mint)).detach();
+        smol::spawn(self.handle_subscribe_request(keypair, drk_pub_key, mint)).detach();
 
         Ok(TokenSubscribtion {
             secret_key,
@@ -350,6 +382,7 @@ impl NetworkClient for SolClient {
         self: Arc<Self>,
         private_key: Vec<u8>,
         _public_key: Vec<u8>,
+        drk_pub_key: jubjub::SubgroupPoint,
         mint_address: Option<String>,
     ) -> Result<String> {
         let keypair: Keypair = deserialize(&private_key)?;
@@ -358,7 +391,7 @@ impl NetworkClient for SolClient {
 
         let mint = self.check_mint_address(mint_address)?;
 
-        smol::spawn(self.handle_subscribe_request(keypair, mint)).detach();
+        smol::spawn(self.handle_subscribe_request(keypair, drk_pub_key, mint)).detach();
 
         Ok(public_key)
     }

+ 10 - 9
src/wallet/cashierdb.rs

@@ -305,11 +305,11 @@ impl CashierDb {
         Ok(keys)
     }
 
-    // return private key, public key, token_id, and mint_address as a tuple
+    // return drk_pub_key, private key, public key, token_id, and mint_address as a tuple
     pub fn get_deposit_token_keys_by_network(
         &self,
         network: &NetworkName,
-    ) -> Result<Vec<(Vec<u8>, Vec<u8>, jubjub::Fr, String)>> {
+    ) -> Result<Vec<(jubjub::SubgroupPoint, Vec<u8>, Vec<u8>, jubjub::Fr, String)>> {
         debug!(target: "CASHIERDB", "Check for existing dkey");
         // open connection
         let conn = Connection::open(&self.path)?;
@@ -320,25 +320,26 @@ impl CashierDb {
         let confirm = self.get_value_serialized(&false)?;
 
         let mut stmt = conn.prepare(
-            "SELECT token_key_private, token_key_public, token_id, mint_address
+            "SELECT d_pub_key, token_key_private, token_key_public, token_id, mint_address
             FROM deposit_keypairs
             WHERE network = :network
             AND confirm = :confirm ;",
         )?;
         let keys_iter = stmt
             .query_map(&[(":network", &network), (":confirm", &confirm)], |row| {
-                Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?))
+                Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?, row.get(4)?))
             })?;
 
         let mut keys = vec![];
 
         for key in keys_iter {
             let key = key?;
-            let private_key = key.0;
-            let pub_key = key.1;
-            let token_id: jubjub::Fr = self.get_value_deserialized(key.2)?;
-            let mint_address: String = self.get_value_deserialized(key.3)?;
-            keys.push((private_key, pub_key, token_id, mint_address));
+            let drk_pub_key: jubjub::SubgroupPoint = self.get_value_deserialized(key.0)?;
+            let private_key = key.1;
+            let pub_key = key.2;
+            let token_id: jubjub::Fr = self.get_value_deserialized(key.3)?;
+            let mint_address: String = self.get_value_deserialized(key.4)?;
+            keys.push((drk_pub_key, private_key, pub_key, token_id, mint_address));
         }
 
         Ok(keys)