Ver Fonte

refactoring and cleaning up functions inside cashierdb

ghassmo há 4 anos atrás
pai
commit
5fe2970827
3 ficheiros alterados com 89 adições e 61 exclusões
  1. 6 0
      src/service/btc.rs
  2. 17 12
      src/service/cashier.rs
  3. 66 49
      src/wallet/cashierdb.rs

+ 6 - 0
src/service/btc.rs

@@ -106,6 +106,12 @@ impl BitcoinKeys {
         Ok(address)
     }
 
+    // This should do a db lookup to return the same obj
+    pub fn private_key_from_slice(key: &[u8]) -> Result<PrivKey> {
+        let key = PrivKey::from_slice(key, Network::Testnet).unwrap();
+        Ok(key)
+    }
+
     pub fn get_deposit_address(&self) -> Result<&Address> {
         Ok(&self.pub_address)
     }

+ 17 - 12
src/service/cashier.rs

@@ -16,6 +16,7 @@ use log::*;
 use async_std::sync::{Arc, Mutex};
 use std::net::SocketAddr;
 use std::path::PathBuf;
+use std::str::FromStr;
 
 #[repr(u8)]
 enum CashierError {
@@ -100,11 +101,11 @@ impl CashierService {
             loop {
                 let (pub_key, amount) = recv_queue.recv().await.expect("Receive Own Coin");
                 debug!(target: "CASHIER DAEMON", "Receive coin with following address and amount: {}, {}", pub_key, amount);
-                let btc_addr = wallet.get_btc_addr_by_address(pub_key).expect("Get btc_key by pub_key");
+                let btc_addr = wallet.get_btc_addr_by_address(&pub_key).expect("Get btc_key by pub_key");
                 if let Some(addr) =  btc_addr {
                     // TODO send equivalent amount of btc to this address
                     // then delete this btc_addr from withdraw_keys records
-                    wallet.delete_withdraw_key_record(addr).expect("Delete withdraw key record");
+                    wallet.delete_withdraw_key_record(&addr).expect("Delete withdraw key record");
                 }
 
             }
@@ -120,7 +121,11 @@ impl CashierService {
     }
 
     async fn _mint_dbtc(&mut self, dkey_pub: jubjub::SubgroupPoint, value: u64) -> Result<()> {
-        self.client.lock().await.send(dkey_pub, value, 1).await?;
+        self.client
+            .lock()
+            .await
+            .send(dkey_pub, value, 1)
+            .await?;
         Ok(())
     }
 
@@ -166,7 +171,8 @@ impl CashierService {
                 let zkpub = request.get_payload();
 
                 //TODO: check if key has already been issued
-                let _check = cashier_wallet.get_keys_by_dkey(&zkpub);
+                let dpub: jubjub::SubgroupPoint = deserialize(&zkpub)?;
+                let _check = cashier_wallet.get_btc_keys_by_dkey(&dpub);
 
                 // Generate bitcoin Address
                 let btc_keys = BitcoinKeys::new(btc_client)?;
@@ -177,7 +183,7 @@ impl CashierService {
                 let _script = btc_keys.get_script();
 
                 // add pairings to db
-                let _result = cashier_wallet.put_exchange_keys(zkpub, *btc_priv, *btc_pub);
+                let _result = cashier_wallet.put_exchange_keys(&dpub, btc_priv, btc_pub);
 
                 let mut reply = Reply::from(&request, CashierError::NoError as u32, vec![]);
 
@@ -198,23 +204,22 @@ impl CashierService {
             1 => {
                 debug!(target: "CASHIER DAEMON", "Received withdraw request");
                 let btc_address = request.get_payload();
-                //let btc_address: String = deserialize(&btc_address)?;
-                //let btc_address = bitcoin::util::address::Address::from_str(&btc_address)?;
-                //
+                let btc_address: String = deserialize(&btc_address)?;
+                let btc_address = bitcoin::util::address::Address::from_str(&btc_address)?;
 
                 let cashier_public: jubjub::SubgroupPoint;
 
                 if let Some(addr) = cashier_wallet.get_address_by_btc_key(&btc_address)? {
-                    cashier_public = deserialize(&addr.0)?;
+                    cashier_public = addr.0;
                 } else {
                     let cashier_secret = jubjub::Fr::random(&mut OsRng);
                     cashier_public =
                         zcash_primitives::constants::SPENDING_KEY_GENERATOR * cashier_secret;
 
                     cashier_wallet.put_withdraw_keys(
-                        btc_address,
-                        serialize(&cashier_public),
-                        serialize(&cashier_secret),
+                        &btc_address,
+                        &cashier_public,
+                        &cashier_secret,
                     )?;
                 }
 

+ 66 - 49
src/wallet/cashierdb.rs

@@ -1,13 +1,13 @@
 use super::WalletApi;
 use crate::client::ClientFailed;
-use crate::service::btc::{PrivKey, PubKey};
+use crate::service::btc::{BitcoinKeys, PrivKey, PubKey};
 use crate::{Error, Result};
 
 use async_std::sync::Arc;
 
 use bitcoin::Address as BtcAddr;
 use log::*;
-use rusqlite::{named_params, Connection, params};
+use rusqlite::{named_params, params, Connection};
 
 use std::path::PathBuf;
 use std::str::FromStr;
@@ -51,39 +51,48 @@ impl CashierDb {
         Ok(())
     }
 
-    pub fn get_keys_by_dkey(&self, dkey_pub: &Vec<u8>) -> Result<()> {
+    pub fn get_btc_keys_by_dkey(
+        &self,
+        dkey_pub: &jubjub::SubgroupPoint,
+    ) -> Result<Vec<(PrivKey, PubKey)>> {
         debug!(target: "CASHIERDB", "Check for existing dkey");
-        //let dkey_id = self.get_value_deserialized(dkey_pub)?;
+        let dkey_pub = self.get_value_serialized(dkey_pub)?;
         // open connection
         let conn = Connection::open(&self.path)?;
         // unlock database
         conn.pragma_update(None, "key", &self.password)?;
 
-        // let mut keypairs = conn.prepare("SELECT dkey_id FROM keypairs WHERE dkey_id = :dkey_id")?;
-        // let rows = keypairs.query_map::<Vec<u8>, _, _>(&[(":dkey_id", &secret)], |row| row.get(0))?;
+        let mut stmt = conn.prepare("SELECT * FROM keypairs where dkey_id = :dkey_id")?;
+        let keys_iter =
+            stmt.query_map::<(PrivKey, PubKey), _, _>(&[(":dkey_id", &dkey_pub)], |row| {
+                let s_key: Vec<u8> = row.get(1)?;
+                let private = BitcoinKeys::private_key_from_slice(&s_key)
+                    .expect("get btc private key from slice");
+                let p_key: Vec<u8> = row.get(2)?;
+                let public = PubKey::from_slice(&p_key).expect("get btc public key from slice");
+                Ok((private, public))
+            })?;
 
-        let mut stmt = conn.prepare("SELECT * FROM keypairs where dkey_id = ?")?;
-        let mut rows = stmt.query([dkey_pub])?;
-        if let Some(_row) = rows.next()? {
-            println!("Got something");
-        } else {
-            println!("Did not get something");
+        let mut keys: Vec<(PrivKey, PubKey)> = vec![];
+
+        for k in keys_iter {
+            keys.push(k?);
         }
 
-        Ok(())
+        Ok(keys)
     }
 
     // Update to take BitcoinKeys instance instead
     pub fn put_exchange_keys(
         &self,
-        dkey_pub: Vec<u8>,
-        btc_private: PrivKey,
-        btc_public: PubKey,
+        dkey_pub: &jubjub::SubgroupPoint,
+        btc_private: &PrivKey,
+        btc_public: &PubKey,
         //txid will be updated when exists
     ) -> Result<()> {
         debug!(target: "CASHIERDB", "Put exchange keys");
         // prepare the values
-        //let dkey_pub = self.get_value_serialized(&dkey_pub)?;
+        let dkey_pub = self.get_value_serialized(dkey_pub)?;
         let btc_private = btc_private.to_bytes();
         let btc_public = btc_public.to_bytes();
 
@@ -131,37 +140,44 @@ impl CashierDb {
     // return (public key, private key)
     pub fn get_address_by_btc_key(
         &self,
-        btc_address: &Vec<u8>,
-    ) -> Result<Option<(Vec<u8>, Vec<u8>)>> {
+        btc_address: &BtcAddr,
+    ) -> Result<Option<(jubjub::SubgroupPoint, jubjub::Fr)>> {
         debug!(target: "CASHIERDB", "Check for existing btc address");
         // open connection
         let conn = Connection::open(&self.path)?;
         // unlock database
         conn.pragma_update(None, "key", &self.password)?;
 
+        let btc_address = btc_address.to_string();
+        let btc_address = self.get_value_serialized(&btc_address)?;
+
         let mut stmt =
             conn.prepare("SELECT * FROM withdraw_keypairs where btc_key_id = :btc_key_id")?;
-        let addr_iter = stmt
-            .query_map::<(Vec<u8>, Vec<u8>), _, _>(&[(":btc_key_id", btc_address)], |row| {
-                Ok((row.get(2)?, row.get(1)?))
-            })?;
+        let addr_iter = stmt.query_map::<(jubjub::SubgroupPoint, jubjub::Fr), _, _>(
+            &[(":btc_key_id", &btc_address)],
+            |row| {
+                let public: jubjub::SubgroupPoint = self
+                    .get_value_deserialized(row.get(2)?)
+                    .expect("get public key deserialize");
+                let private: jubjub::Fr = self
+                    .get_value_deserialized(row.get(1)?)
+                    .expect("get  private key deserialize");
+                Ok((public, private))
+            },
+        )?;
 
-        let mut btc_addresses = vec![];
+        let mut addresses: Vec<(jubjub::SubgroupPoint, jubjub::Fr)> = vec![];
 
         for addr in addr_iter {
-            btc_addresses.push(addr);
+            addresses.push(addr?);
         }
 
-        if let Some(addr) = btc_addresses.pop() {
-            return Ok(Some(addr?));
-        }
-
-        return Ok(None);
+        Ok(addresses.pop())
     }
 
     pub fn get_btc_addr_by_address(
         &self,
-        pub_key: jubjub::SubgroupPoint,
+        pub_key: &jubjub::SubgroupPoint,
     ) -> Result<Option<BtcAddr>> {
         debug!(target: "CASHIERDB", "Get btc address by pub_key");
         // open connection
@@ -169,7 +185,7 @@ impl CashierDb {
         // unlock database
         conn.pragma_update(None, "key", &self.password)?;
 
-        let d_key_public = self.get_value_serialized(&pub_key)?;
+        let d_key_public = self.get_value_serialized(pub_key)?;
 
         let mut stmt = conn.prepare(
             "SELECT btc_key_id FROM withdraw_keypairs where d_key_public = :d_key_public",
@@ -193,10 +209,7 @@ impl CashierDb {
         Ok(btc_addresses.pop())
     }
 
-    pub fn delete_withdraw_key_record(
-        &self,
-        btc_address: BtcAddr,
-    ) -> Result<()> {
+    pub fn delete_withdraw_key_record(&self, btc_address: &BtcAddr) -> Result<()> {
         debug!(target: "CASHIERDB", "Delete withdraw keys");
 
         // open connection
@@ -209,9 +222,7 @@ impl CashierDb {
 
         conn.execute(
             "DELETE FROM withdraw_keypairs WHERE btc_key_id = ?1;",
-            params! [
-                btc_address
-            ],
+            params![btc_address],
         )?;
 
         Ok(())
@@ -219,12 +230,18 @@ impl CashierDb {
 
     pub fn put_withdraw_keys(
         &self,
-        btc_key_id: Vec<u8>,
-        d_key_public: Vec<u8>,
-        d_key_private: Vec<u8>,
+        btc_key_id: &BtcAddr,
+        d_key_public: &jubjub::SubgroupPoint,
+        d_key_private: &jubjub::Fr,
     ) -> Result<()> {
         debug!(target: "CASHIERDB", "Put withdraw keys");
 
+        let btc_key_id = btc_key_id.to_string();
+        let btc_key_id = self.get_value_serialized(&btc_key_id)?;
+
+        let d_key_public = self.get_value_serialized(d_key_public)?;
+        let d_key_private = self.get_value_serialized(d_key_private)?;
+
         // open connection
         let conn = Connection::open(&self.path)?;
         // unlock database
@@ -247,13 +264,13 @@ impl CashierDb {
 mod tests {
 
     use super::*;
-    use crate::serial::serialize;
     use crate::util::join_config_path;
 
-    use crate::serial;
     use ff::Field;
     use rand::rngs::OsRng;
 
+    // TODO add more tests
+
     #[test]
     pub fn test_put_withdraw_keys_and_load_them_with_btc_key() -> Result<()> {
         let walletdb_path = join_config_path(&PathBuf::from("cashier_wallet_test.db"))?;
@@ -262,16 +279,16 @@ mod tests {
 
         let secret2: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
         let public2 = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret2;
-        let key_public2 = serial::serialize(&public2);
-        let key_private2 = serial::serialize(&secret2);
 
-        let btc_addr = serialize(&String::from("bc10000000000000000000000000000000000000000"));
+        // btc addr testnet
+        let btc_addr =
+            BtcAddr::from_str(&String::from("mxVFsFW5N4mu1HPkxPttorvocvzeZ7KZyk"))?;
 
-        wallet.put_withdraw_keys(btc_addr.clone(), key_public2.clone(), key_private2.clone())?;
+        wallet.put_withdraw_keys(&btc_addr, &public2, &secret2)?;
 
         let addr = wallet.get_address_by_btc_key(&btc_addr)?;
 
-        assert_eq!(addr, Some((key_public2, key_private2)));
+        assert_eq!(addr, Some((public2, secret2)));
 
         wallet.destroy()?;