Эх сурвалжийг харах

get keypair from walletdb instead of get keys separately

ghassmo 4 жил өмнө
parent
commit
8d1cb7bce6

+ 1 - 1
src/bin/darkfid.rs

@@ -31,7 +31,7 @@ async fn start(executor: Arc<Executor<'_>>, config: Arc<DarkfidConfig>) -> Resul
     let mint_params_path = join_config_path(&PathBuf::from("mint.params"))?;
     let spend_params_path = join_config_path(&PathBuf::from("spend.params"))?;
 
-    if let Err(_) = wallet.get_private_keys() {
+    if let Err(_) = wallet.get_keypairs() {
         wallet.init_db()?;
         wallet.key_gen()?;
     }

+ 17 - 3
src/client/client.rs

@@ -171,7 +171,7 @@ impl Client {
         let mut outputs: Vec<tx::TransactionBuilderOutputInfo> = vec![];
 
         if clear_input {
-            let cashier_secret = self.state.wallet.get_private_keys()?[0];
+            let cashier_secret = self.state.wallet.get_keypairs()?[0].private;
             let input = tx::TransactionBuilderClearInputInfo {
                 value: amount,
                 asset_id,
@@ -272,7 +272,13 @@ impl Client {
             let tx = tx::Transaction::decode(&slab.get_payload()[..])?;
             let mut client = client.lock().await;
             let update = state_transition(&client.state, tx)?;
-            let mut secret_keys = client.state.wallet.get_private_keys()?;
+            let mut secret_keys: Vec<jubjub::Fr> = client
+                .state
+                .wallet
+                .get_keypairs()?
+                .iter()
+                .map(|k| k.private)
+                .collect();
             let mut withdraw_keys = cashier_wallet.get_withdraw_private_keys()?;
             secret_keys.append(&mut withdraw_keys);
             client
@@ -309,7 +315,15 @@ impl Client {
             let tx = tx::Transaction::decode(&slab.get_payload()[..])?;
             let mut client = client.lock().await;
             let update = state_transition(&client.state, tx)?;
-            let secret_keys = client.state.wallet.get_private_keys()?;
+
+            let secret_keys: Vec<jubjub::Fr> = client
+                .state
+                .wallet
+                .get_keypairs()?
+                .iter()
+                .map(|k| k.private)
+                .collect();
+
             client
                 .state
                 .apply(update, secret_keys.clone(), notify.clone())

+ 2 - 4
src/client/mod.rs

@@ -12,8 +12,7 @@ pub enum ClientFailed {
     UnableToGetDepositAddress,
     UnableToGetWithdrawAddress,
     DoNotHaveCashierPublicKey,
-    DoNotHavePublicKey,
-    DoNotHavePrivateKey,
+    DoNotHaveKeypair,
     EmptyPassword,
     ClientError(String),
 }
@@ -37,8 +36,7 @@ impl fmt::Display for ClientFailed {
                 f.write_str("Unable to get withdraw address")
             }
             ClientFailed::DoNotHaveCashierPublicKey => f.write_str("Don't have cashier public key"),
-            ClientFailed::DoNotHavePublicKey => f.write_str("Don't have public key"),
-            ClientFailed::DoNotHavePrivateKey => f.write_str("Don't have private key"),
+            ClientFailed::DoNotHaveKeypair => f.write_str("Don't have keypair"),
             ClientFailed::EmptyPassword => f.write_str("Password is empty. Cannot create database"),
             ClientFailed::ClientError(i) => {
                 write!(f, "ClientError: {}", i)

+ 2 - 2
src/rpc/adapter/client_adapter.rs

@@ -67,7 +67,7 @@ impl RpcClientAdapter {
     }
 
     async fn get_key_process(client: Arc<Mutex<Client>>) -> Result<String> {
-        let key_public = client.lock().await.state.wallet.get_public_keys()?[0];
+        let key_public = client.lock().await.state.wallet.get_keypairs()?[0].public;
         let bs58_address = bs58::encode(serialize(&key_public)).into_string();
         Ok(bs58_address)
     }
@@ -150,7 +150,7 @@ impl RpcClientAdapter {
         T: Decodable + ToString,
     {
         let asset_id: jubjub::Fr = deserialize(&asset_id)?;
-        let deposit_addr = client.lock().await.state.wallet.get_public_keys()?[0];
+        let deposit_addr = client.lock().await.state.wallet.get_keypairs()?[0].public;
         let coin_public = cashier_client
             .lock()
             .await

+ 12 - 16
src/service/cashier.rs

@@ -16,6 +16,8 @@ use async_std::sync::{Arc, Mutex};
 use std::net::SocketAddr;
 use std::path::PathBuf;
 
+
+
 #[repr(u8)]
 enum CashierError {
     NoError,
@@ -42,7 +44,6 @@ impl CashierService {
         gateway_addrs: (SocketAddr, SocketAddr),
         params_paths: (PathBuf, PathBuf),
     ) -> Result<CashierService> {
-        // Pull address from config later
 
         let rocks = Rocks::new(&cashier_database_path)?;
 
@@ -50,6 +51,7 @@ impl CashierService {
 
         let client = Arc::new(Mutex::new(client));
 
+
         Ok(CashierService {
             addr,
             wallet,
@@ -59,6 +61,7 @@ impl CashierService {
     pub async fn start(
         &mut self,
         executor: Arc<Executor<'_>>,
+        // TODO: the endpoint should be generic according to asset_id 
         btc_endpoint: (bool, String),
         // TODO: make this a vector of assets
         asset_id: jubjub::Fr,
@@ -76,13 +79,12 @@ impl CashierService {
 
         let bridge = bridge::Bridge::new();
 
-        #[cfg(feature = "default")]
-        let btc_client = super::btc::BtcClient::new(btc_endpoint)?;
-        #[cfg(feature = "default")]
-        bridge
-            .clone()
-            .add_clients(asset_id, Arc::new(btc_client))
-            .await;
+        cfg_if::cfg_if! {
+            if #[cfg(feature = "default")]{
+                let btc_client = super::btc::BtcClient::new(btc_endpoint)?;
+                bridge.clone().add_clients(asset_id, Arc::new(btc_client)).await;
+            }
+        }
 
         let handle_request_task = executor.spawn(Self::handle_request_loop(
             send.clone(),
@@ -129,10 +131,9 @@ impl CashierService {
                     if res.error == 0 {
                         match res.payload {
                             bridge::BridgeResponsePayload::SendResponse => {
-                                // then delete this coin addr from withdraw_keys records
                                 // TODO Send the received coins to the main address
-                                wallet.delete_withdraw_key_record(&addr, &serialize(&1) )
-                                    .expect("Delete withdraw key record");
+                                // wallet.delete_withdraw_key_record(&addr, &serialize(&1) )
+                                //     .expect("Delete withdraw key record");
                             }
                             _ => {}
                         }
@@ -212,7 +213,6 @@ impl CashierService {
                 let (asset_id, dpub): (jubjub::Fr, jubjub::SubgroupPoint) =
                     deserialize(&request.get_payload())?;
 
-                //TODO: check if key has already been issued
                 let _check =
                     cashier_wallet.get_deposit_coin_keys_by_dkey_public(&dpub, &serialize(&1));
 
@@ -252,10 +252,6 @@ impl CashierService {
                 debug!(target: "CASHIER DAEMON", "Received withdraw request");
                 let (asset_id, coin_address): (jubjub::Fr, Vec<u8>) =
                     deserialize(&request.get_payload())?;
-                //let btc_address: String = deserialize(&btc_address)?;
-                //let btc_address = bitcoin::util::address::Address::from_str(&btc_address)
-                //   .map_err(|err| crate::Error::from(super::BtcFailed::from(err)))?;
-                //
 
                 let asset_id = serialize(&asset_id);
 

+ 21 - 69
src/wallet/walletdb.rs

@@ -4,7 +4,6 @@ use crate::crypto::{
     merkle::IncrementalWitness, merkle_node::MerkleNode, note::Note, OwnCoin, OwnCoins,
 };
 use crate::serial;
-use crate::serial::{deserialize, serialize, Decodable, Encodable};
 use crate::{Error, Result};
 
 use async_std::sync::Arc;
@@ -17,6 +16,11 @@ use std::path::PathBuf;
 
 pub type WalletPtr = Arc<WalletDb>;
 
+pub struct Keypair {
+    pub public: jubjub::SubgroupPoint,
+    pub private: jubjub::Fr,
+}
+
 pub struct WalletDb {
     pub path: PathBuf,
     pub password: String,
@@ -73,45 +77,31 @@ impl WalletDb {
         )?;
         Ok(())
     }
-    pub fn get_public_keys(&self) -> Result<Vec<jubjub::SubgroupPoint>> {
+    pub fn get_keypairs(&self) -> Result<Vec<Keypair>> {
         debug!(target: "WALLETDB", "Returning keys...");
         let conn = Connection::open(&self.path)?;
         conn.pragma_update(None, "key", &self.password)?;
-        let mut stmt = conn.prepare("SELECT key_public FROM keys")?;
+        let mut stmt = conn.prepare("SELECT * FROM keys")?;
         // this just gets the first key. maybe we should randomize this
-        let key_iter = stmt.query_map([], |row| row.get(0))?;
-        let mut pub_keys = Vec::new();
+        let key_iter = stmt.query_map([], |row| Ok((row.get(1)?, row.get(2)?)))?;
+        let mut keypairs = Vec::new();
         for key in key_iter {
+            let key = key?;
+            let public = key.0;
+            let private = key.1;
             let public: jubjub::SubgroupPoint =
-                self.get_value_deserialized::<jubjub::SubgroupPoint>(key?)?;
-            pub_keys.push(public);
+                self.get_value_deserialized::<jubjub::SubgroupPoint>(public)?;
+            let private: jubjub::Fr = self.get_value_deserialized::<jubjub::Fr>(private)?;
+            keypairs.push(Keypair { public, private });
         }
 
-        if pub_keys.is_empty() {
-            return Err(Error::from(ClientFailed::DoNotHavePublicKey));
+        if keypairs.is_empty() {
+            return Err(Error::from(ClientFailed::DoNotHaveKeypair));
         }
 
-        Ok(pub_keys)
+        Ok(keypairs)
     }
 
-    pub fn get_private_keys(&self) -> Result<Vec<jubjub::Fr>> {
-        debug!(target: "WALLETDB", "Returning keys...");
-        let conn = Connection::open(&self.path)?;
-        conn.pragma_update(None, "key", &self.password)?;
-        let mut stmt = conn.prepare("SELECT key_private FROM keys")?;
-        let key_iter = stmt.query_map([], |row| row.get(0))?;
-        let mut keys = Vec::new();
-        for key in key_iter {
-            let private: jubjub::Fr = self.get_value_deserialized(key?)?;
-            keys.push(private);
-        }
-
-        if keys.is_empty() {
-            return Err(Error::from(ClientFailed::DoNotHavePrivateKey));
-        }
-
-        Ok(keys)
-    }
     pub fn get_own_coins(&self) -> Result<OwnCoins> {
         // open connection
         let conn = Connection::open(&self.path)?;
@@ -290,43 +280,6 @@ impl WalletDb {
         let _rows = stmt.query([])?;
         Ok(())
     }
-
-    fn get_tables_name(&self) -> Result<Vec<String>> {
-        let conn = Connection::open(&self.path)?;
-        conn.pragma_update(None, "key", &self.password)?;
-        let mut stmt = conn.prepare("SELECT name FROM sqlite_master WHERE type='table'")?;
-        let table_iter = stmt.query_map::<String, _, _>([], |row| row.get(0))?;
-
-        let mut tables = Vec::new();
-
-        for table in table_iter {
-            tables.push(table?);
-        }
-
-        Ok(tables)
-    }
-
-    pub fn destroy(&self) -> Result<()> {
-        let conn = Connection::open(&self.path)?;
-        conn.pragma_update(None, "key", &self.password)?;
-
-        for table in self.get_tables_name()?.iter() {
-            let drop_stmt = format!("DROP TABLE IF EXISTS {}", table);
-            let drop_stmt = drop_stmt.as_str();
-            conn.execute(drop_stmt, [])?;
-        }
-
-        Ok(())
-    }
-    pub fn get_value_serialized<T: Encodable>(&self, data: &T) -> Result<Vec<u8>> {
-        let v = serialize(data);
-        Ok(v)
-    }
-
-    pub fn get_value_deserialized<D: Decodable>(&self, key: Vec<u8>) -> Result<D> {
-        let v: D = deserialize(&key)?;
-        Ok(v)
-    }
 }
 
 #[cfg(test)]
@@ -350,11 +303,10 @@ mod tests {
 
         wallet.put_keypair(key_public, key_private)?;
 
-        let public2 = wallet.get_public_keys()?;
-        let secret2 = wallet.get_private_keys()?;
+        let keypair = wallet.get_keypairs()?[0];
 
-        assert_eq!(public, public2[0]);
-        assert_eq!(secret, secret2[0]);
+        assert_eq!(public, keypair.public);
+        assert_eq!(secret, keypair.private);
 
         wallet.destroy()?;