Explorar el Código

made walletdb constructor, modified darkfid.rs with reference to walletdb. updated walletdb with

wallet variables. partially implemented cashier check.
rachel-rose hace 5 años
padre
commit
4c7ce86360
Se han modificado 7 ficheros con 210 adiciones y 172 borrados
  1. 0 1
      res/schema.sql
  2. 57 54
      scripts/drk
  3. 23 21
      src/bin/darkfid.rs
  4. 10 0
      src/error.rs
  5. 16 33
      src/rpc/adapter.rs
  6. 53 38
      src/rpc/jsonserver.rs
  7. 51 25
      src/wallet/walletdb.rs

+ 0 - 1
res/schema.sql

@@ -1,4 +1,3 @@
-.open wallet.db
 PRAGMA key = 'testkey';
 PRAGMA key = 'testkey';
 CREATE TABLE IF NOT EXISTS keys(
 CREATE TABLE IF NOT EXISTS keys(
     key_id INTEGER PRIMARY KEY NOT NULL,
     key_id INTEGER PRIMARY KEY NOT NULL,

+ 57 - 54
scripts/drk

@@ -9,44 +9,47 @@ def arg_parser(client):
                                           usage='%(prog)s [commands]',
                                           usage='%(prog)s [commands]',
                                           description="""DarkFi wallet
                                           description="""DarkFi wallet
                                           command-line tool""")
                                           command-line tool""")
-    subparser = parser.add_subparsers(help='All available commands', title="Commands", dest='cmd')
-    subparser.metavar = 'subcommands';
-    #create = subparser.add_parser('create', help='create a new X')
-    login = subparser.add_parser('login', help='wallet login')
-    test = subparser.add_parser('test', help='test wallet functions')
-
-    #create.add_argument('-kp', '--keypair', dest='keypair', action='store_true', help='Create a new keypair')
-    #create.add_argument('-w', '--wallet', dest='wallet', action='store_true', help='Create a new wallet')
-    #create.add_argument('-c', '--cashier', dest='cashier',action='store_true', help='Create a cashier wallet')
-
-    login.add_argument('-u', '--username', type=str, required=True)
-    login.add_argument('-p', '--password', type=str, required=True)
-
-    test.add_argument('-k', '--key', dest='key', action='store_true', help='Test key')
-    test.add_argument('-p', '--path', dest='path', action='store_true', help='Test path')
-    test.add_argument('-pk', '--pkey', dest='pkey', action='store_true', help='Print test key')
-    test.add_argument('-ck', '--ckey', dest='ckey', action='store_true', help='Cashier test key')
-    test.add_argument('-i', '--info', dest='info', action='store_true', help='Request info from daemon')
-    test.add_argument('-hi', '--hello', dest='hello', action='store_true', help='Test hello')
-    test.add_argument('-w', '--wallet', dest='wallet', action='store_true', help='Create a new wallet')
-    test.add_argument('-c', '--cashier', dest='cashier',action='store_true', help='Create a cashier wallet')
-
+    #subparser = parser.add_subparsers(help='All available commands', title="Commands", dest='cmd')
+    #subparser.metavar = 'subcommands';
+    #login = subparser.add_parser('login', help='wallet login')
+    ##test = subparser.add_parser('test', help='test wallet functions')
+    #new = subparser.add_parser('new', help='create something new')
+
+    #new.add_argument('-w', '--wallet', action='store_true', help='Create a new wallet')
+    #new.add_argument('-k', '--key', action='store_true', help='Create a new key')
+    #new.add_argument('-c', '--cashier', action='store_true', help='Create a cashier wallet')
+
+    #login.add_argument('-u', '--username', type=str, required=True)
+    #login.add_argument('-p', '--password', type=str, required=True)
+
+    ##test.add_argument('-k', '--key', dest='key', action='store_true', help='Test key')
+    ##test.add_argument('-p', '--path', dest='path', action='store_true', help='Test path')
+    ##test.add_argument('-pk', '--pkey', dest='pkey', action='store_true', help='Print test key')
+    ##test.add_argument('-ck', '--ckey', dest='ckey', action='store_true', help='Cashier test key')
+    ##test.add_argument('-w', '--wallet', dest='wallet', action='store_true', help='Create a new wallet')
+    ##test.add_argument('-c', '--cashier', dest='cashier',action='store_true', help='Create a cashier wallet')
+
+    parser.add_argument('-c', '--cashier', action='store_true', help='Create a cashier wallet')
+    parser.add_argument('-w', '--wallet', action='store_true', help='Create a new wallet')
+    parser.add_argument('-k', '--key', action='store_true', help='Test key')
+    parser.add_argument('-i', '--info', action='store_true', help='Request info from daemon')
+    parser.add_argument('-hi', '--hello', action='store_true', help='Test hello')
     parser.add_argument("-s", "--stop", action='store_true', help="Send a stop signal to the daemon")
     parser.add_argument("-s", "--stop", action='store_true', help="Send a stop signal to the daemon")
     args = parser.parse_args()
     args = parser.parse_args()
 
 
-    if args.path:
-        try:
-            print("Testing path...")
-            client.test_path(client.payload)
-        except Exception:
-            raise
+    #if args.path:
+    #    try:
+    #        print("Testing path...")
+    #        client.test_path(client.payload)
+    #    except Exception:
+    #        raise
 
 
-    if args.pkey:
-        try:
-            print("Attempting to print cashier key...")
-            client.cashkey(client.payload)
-        except Exception:
-            raise
+    #if args.pkey:
+    #    try:
+    #        print("Attempting to print cashier key...")
+    #        client.cashkey(client.payload)
+    #    except Exception:
+    #        raise
 
 
     if args.key:
     if args.key:
         try:
         try:
@@ -105,26 +108,26 @@ class DarkClient:
             "id": [],
             "id": [],
         }
         }
 
 
-    def ckeygen(self, payload):
-        payload['method'] = "cash_key_gen"
-        payload['jsonrpc'] = "2.0"
-        payload['id'] = "0"
-        ckeygen = self.__request(payload)
-        print(ckeygen)
-
-    def cashkey(self, payload):
-        payload['method'] = "get_cash_key"
-        payload['jsonrpc'] = "2.0"
-        payload['id'] = "0"
-        cashk = self.__request(payload)
-        print(cashk)
-        
-    def test_path(self, payload):
-        payload['method'] = "test_path"
-        payload['jsonrpc'] = "2.0"
-        payload['id'] = "0"
-        test = self.__request(payload)
-        print(test)
+    #def ckeygen(self, payload):
+    #    payload['method'] = "cash_key_gen"
+    #    payload['jsonrpc'] = "2.0"
+    #    payload['id'] = "0"
+    #    ckeygen = self.__request(payload)
+    #    print(ckeygen)
+
+    #def cashkey(self, payload):
+    #    payload['method'] = "get_cash_key"
+    #    payload['jsonrpc'] = "2.0"
+    #    payload['id'] = "0"
+    #    cashk = self.__request(payload)
+    #    print(cashk)
+    #    
+    #def test_path(self, payload):
+    #    payload['method'] = "test_path"
+    #    payload['jsonrpc'] = "2.0"
+    #    payload['id'] = "0"
+    #    test = self.__request(payload)
+    #    print(test)
         
         
     def key_gen(self, payload):
     def key_gen(self, payload):
         payload['method'] = "key_gen"
         payload['method'] = "key_gen"

+ 23 - 21
src/bin/darkfid.rs

@@ -16,7 +16,7 @@ use drk::serial::{deserialize, Decodable};
 use drk::service::{ClientProgramOptions, GatewayClient, GatewaySlabsSubscriber};
 use drk::service::{ClientProgramOptions, GatewayClient, GatewaySlabsSubscriber};
 use drk::state::{state_transition, ProgramState, StateUpdate};
 use drk::state::{state_transition, ProgramState, StateUpdate};
 use drk::wallet::WalletDB;
 use drk::wallet::WalletDB;
-use drk::{tx, Result, Error};
+use drk::{tx, Error, Result};
 use rusqlite::Connection;
 use rusqlite::Connection;
 
 
 use async_executor::Executor;
 use async_executor::Executor;
@@ -44,18 +44,18 @@ pub struct State {
     // Public key of the cashier
     // Public key of the cashier
     cashier_public: jubjub::SubgroupPoint,
     cashier_public: jubjub::SubgroupPoint,
     // List of all our secret keys
     // List of all our secret keys
+    wallet: Arc<WalletDB>,
     secrets: Vec<jubjub::Fr>,
     secrets: Vec<jubjub::Fr>,
 }
 }
 
 
 impl ProgramState for State {
 impl ProgramState for State {
     fn is_valid_cashier_public_key(&self, _public: &jubjub::SubgroupPoint) -> bool {
     fn is_valid_cashier_public_key(&self, _public: &jubjub::SubgroupPoint) -> bool {
-        //let path = WalletDB::path("cashier.db").expect("Failed to find path");
-        //let connect = Connection::open(&path).expect("Failed to connect to database.");
-        //let mut stmt = connect
-        //    .prepare("SELECT key_public FROM cashier WHERE key_public IN (SELECT key_public)")
-        //    .expect("Cannot generate statement.");
-        //stmt.exists([1i32]).unwrap()
-        0
+        let conn = Connection::open(&self.wallet.path).expect("Failed to connect to database");
+        let mut stmt = conn
+            .prepare("SELECT key_public FROM cashier WHERE key_public IN (SELECT key_public)")
+            .expect("Cannot generate statement.");
+        stmt.exists([1i32]).expect("Failed to read database")
+        // do actual validity check
     }
     }
 
 
     fn is_valid_merkle(&self, merkle_root: &MerkleNode) -> bool {
     fn is_valid_merkle(&self, merkle_root: &MerkleNode) -> bool {
@@ -101,20 +101,20 @@ impl State {
                 witness.append(node).expect("append to witness");
                 witness.append(node).expect("append to witness");
             }
             }
 
 
-           // if let Some((note, secret)) = self.try_decrypt_note(enc_note) {
-           //     // We need to keep track of the witness for this coin.
-           //     // This allows us to prove inclusion of the coin in the merkle tree with ZK.
-           //     // Just as we update the merkle tree with every new coin, so we do the same with
-           //     // the witness.
+            // if let Some((note, secret)) = self.try_decrypt_note(enc_note) {
+            //     // We need to keep track of the witness for this coin.
+            //     // This allows us to prove inclusion of the coin in the merkle tree with ZK.
+            //     // Just as we update the merkle tree with every new coin, so we do the same with
+            //     // the witness.
 
 
-           //     // Derive the current witness from the current tree.
-           //     // This is done right after we add our coin to the tree (but before any other
-           //     // coins are added)
+            //     // Derive the current witness from the current tree.
+            //     // This is done right after we add our coin to the tree (but before any other
+            //     // coins are added)
 
 
-           //     // Make a new witness for this coin
-           //     let witness = IncrementalWitness::from_tree(&self.tree);
-           //     self.own_coins.push((coin, note, secret, witness));
-           // }
+            //     // Make a new witness for this coin
+            //     let witness = IncrementalWitness::from_tree(&self.tree);
+            //     self.own_coins.push((coin, note, secret, witness));
+            // }
         }
         }
         Ok(())
         Ok(())
     }
     }
@@ -133,7 +133,7 @@ impl State {
         //match stmt {
         //match stmt {
         //let mut stmt = connect
         //let mut stmt = connect
         //    .prepare("SELECT key_public FROM cashier WHERE key_public IN (SELECT key_public)")
         //    .prepare("SELECT key_public FROM cashier WHERE key_public IN (SELECT key_public)")
-            //.expect("Cannot generate statement.");
+        //.expect("Cannot generate statement.");
         // test this
         // test this
         //stmt.exists([1i32]).unwrap()
         //stmt.exists([1i32]).unwrap()
         //    Some(v) => {
         //    Some(v) => {
@@ -205,6 +205,7 @@ async fn start(executor: Arc<Executor<'_>>, options: ClientProgramOptions) -> Re
 
 
     let merkle_roots = RocksColumn::<columns::MerkleRoots>::new(rocks.clone());
     let merkle_roots = RocksColumn::<columns::MerkleRoots>::new(rocks.clone());
     let nullifiers = RocksColumn::<columns::Nullifiers>::new(rocks);
     let nullifiers = RocksColumn::<columns::Nullifiers>::new(rocks);
+    let wallet = WalletDB::new("wallet.db")?;
 
 
     let state = State {
     let state = State {
         tree: CommitmentTree::empty(),
         tree: CommitmentTree::empty(),
@@ -213,6 +214,7 @@ async fn start(executor: Arc<Executor<'_>>, options: ClientProgramOptions) -> Re
         own_coins: vec![],
         own_coins: vec![],
         mint_pvk,
         mint_pvk,
         spend_pvk,
         spend_pvk,
+        wallet,
         cashier_public,
         cashier_public,
         secrets: vec![secret.clone()],
         secrets: vec![secret.clone()],
     };
     };

+ 10 - 0
src/error.rs

@@ -1,3 +1,4 @@
+// TODO: Add support for rusqlite error
 use rusqlite;
 use rusqlite;
 use std::fmt;
 use std::fmt;
 
 
@@ -40,6 +41,7 @@ pub enum Error {
     VerifyFailed,
     VerifyFailed,
     TryIntoError,
     TryIntoError,
     TryFromError,
     TryFromError,
+    JsonRpcError(String),
     RocksdbError(String),
     RocksdbError(String),
 }
 }
 
 
@@ -66,6 +68,7 @@ impl fmt::Display for Error {
             Error::Groth16Error => f.write_str("Groth16 error"),
             Error::Groth16Error => f.write_str("Groth16 error"),
             Error::RusqliteError => f.write_str("Rusqlite error"),
             Error::RusqliteError => f.write_str("Rusqlite error"),
             Error::OperationFailed => f.write_str("Operation failed"),
             Error::OperationFailed => f.write_str("Operation failed"),
+
             Error::ConnectFailed => f.write_str("Connection failed"),
             Error::ConnectFailed => f.write_str("Connection failed"),
             Error::ConnectTimeout => f.write_str("Connection timed out"),
             Error::ConnectTimeout => f.write_str("Connection timed out"),
             Error::ChannelStopped => f.write_str("Channel stopped"),
             Error::ChannelStopped => f.write_str("Channel stopped"),
@@ -79,6 +82,7 @@ impl fmt::Display for Error {
             Error::TryIntoError => f.write_str("TryInto error"),
             Error::TryIntoError => f.write_str("TryInto error"),
             Error::TryFromError => f.write_str("TryFrom error"),
             Error::TryFromError => f.write_str("TryFrom error"),
             Error::RocksdbError(ref err) => write!(f, "Rocksdb Error: {}", err),
             Error::RocksdbError(ref err) => write!(f, "Rocksdb Error: {}", err),
+            Error::JsonRpcError(ref err) => write!(f, "JsonRpc Error: {}", err),
         }
         }
     }
     }
 }
 }
@@ -96,6 +100,12 @@ impl From<rocksdb::Error> for Error {
     }
     }
 }
 }
 
 
+impl From<jsonrpc_core::Error> for Error {
+    fn from(err: jsonrpc_core::Error) -> Error {
+        Error::JsonRpcError(err.to_string())
+    }
+}
+
 impl From<std::io::Error> for Error {
 impl From<std::io::Error> for Error {
     fn from(err: std::io::Error) -> Error {
     fn from(err: std::io::Error) -> Error {
         Error::Io(err.kind())
         Error::Io(err.kind())

+ 16 - 33
src/rpc/adapter.rs

@@ -3,46 +3,29 @@ use crate::Result;
 use log::*;
 use log::*;
 use std::sync::Arc;
 use std::sync::Arc;
 
 
-// there should 
+// there should
 // Dummy adapter for now
 // Dummy adapter for now
 pub struct RpcAdapter {
 pub struct RpcAdapter {
-    wallet: Arc<WalletDB>
+    wallet: Arc<WalletDB>,
 }
 }
 
 
 impl RpcAdapter {
 impl RpcAdapter {
     pub fn new(dbname: &str) -> Result<Arc<Self>> {
     pub fn new(dbname: &str) -> Result<Arc<Self>> {
         let wallet = WalletDB::new(dbname)?;
         let wallet = WalletDB::new(dbname)?;
-        Ok(Arc::new(Self {
-            wallet
-        }))
+        Ok(Arc::new(Self { wallet }))
     }
     }
 
 
-    pub async fn new_wallet() -> Result<()> {
-        debug!(target: "adapter", "new_wallet() [START]");
-        //let path = WalletDB::path("wallet.db")?;
-        //WalletDB::new(path).await?;
-        Ok(())
-    }
-
-    pub async fn new_cash_wallet() -> Result<()> {
-        debug!(target: "adapter", "new_cashier_wallet() [START]");
-        //let path = WalletDB::path("cashier.db")?;
-        //WalletDB::new(path).await?;
-        Ok(())
-    }
+    //pub async fn get_path(&self) -> Result<PathBuf> {
+    //}
 
 
-    pub async fn key_gen() -> Result<()> {
+    pub async fn key_gen(&self) -> Result<()> {
         debug!(target: "adapter", "key_gen() [START]");
         debug!(target: "adapter", "key_gen() [START]");
-        //let (public, private) = WalletDB::create_key().await;
-        //let path = WalletDB::path("wallet.db")?;
-        ////self.wallet.save_key()
-        //WalletDB::save_key(path, public, private)
-        //    .await
-        //    .expect("Failed to save key");
+        let (public, private) = self.wallet.key_gen().await;
+        self.wallet.put_key(public, private).await?;
         Ok(())
         Ok(())
     }
     }
 
 
-    pub async fn cash_key_gen() -> Result<()> {
+    pub async fn cash_key_gen(&self) -> Result<()> {
         debug!(target: "adapter", "key_gen() [START]");
         debug!(target: "adapter", "key_gen() [START]");
         //let (public, private) = WalletDB::create_key().await;
         //let (public, private) = WalletDB::create_key().await;
         //let path = WalletDB::path("cashier.db")?;
         //let path = WalletDB::path("cashier.db")?;
@@ -52,37 +35,37 @@ impl RpcAdapter {
         Ok(())
         Ok(())
     }
     }
 
 
-    pub async fn get_key() -> Result<()> {
+    pub async fn get_key(&self) -> Result<()> {
         debug!(target: "adapter", "get_key() [START]");
         debug!(target: "adapter", "get_key() [START]");
         //let path = WalletDB::path("wallet.db")?;
         //let path = WalletDB::path("wallet.db")?;
         //WalletDB::get_public(path).await?;
         //WalletDB::get_public(path).await?;
         Ok(())
         Ok(())
     }
     }
 
 
-    pub async fn get_cash_key() -> Result<()> {
+    pub async fn get_cash_key(&self) -> Result<()> {
         debug!(target: "adapter", "get_cash_key() [START]");
         debug!(target: "adapter", "get_cash_key() [START]");
         //let path = WalletDB::path("cashier.db")?;
         //let path = WalletDB::path("cashier.db")?;
         //let key = WalletDB::get_public(path).await?;
         //let key = WalletDB::get_public(path).await?;
         //println!("{:?}", key);
         //println!("{:?}", key);
         Ok(())
         Ok(())
     }
     }
-    pub async fn save_key(pubkey: Vec<u8>) -> Result<()> {
+    pub async fn save_key(&self, pubkey: Vec<u8>) -> Result<()> {
         debug!(target: "adapter", "save_key() [START]");
         debug!(target: "adapter", "save_key() [START]");
         //let path = WalletDB::path("wallet.db")?;
         //let path = WalletDB::path("wallet.db")?;
         //WalletDB::save(path, pubkey).await?;
         //WalletDB::save(path, pubkey).await?;
         Ok(())
         Ok(())
     }
     }
 
 
-    pub async fn save_cash_key(pubkey: Vec<u8>) -> Result<()> {
+    pub async fn save_cash_key(&self, pubkey: Vec<u8>) -> Result<()> {
         debug!(target: "adapter", "save_cash_key() [START]");
         debug!(target: "adapter", "save_cash_key() [START]");
         //let path = WalletDB::path("cashier.db")?;
         //let path = WalletDB::path("cashier.db")?;
         //WalletDB::save(path, pubkey).await?;
         //WalletDB::save(path, pubkey).await?;
         Ok(())
         Ok(())
     }
     }
 
 
-    pub async fn get_info() {}
+    pub async fn get_info(&self) {}
 
 
-    pub async fn say_hello() {}
+    pub async fn say_hello(&self) {}
 
 
-    pub async fn stop() {}
+    pub async fn stop(&self) {}
 }
 }

+ 53 - 38
src/rpc/jsonserver.rs

@@ -78,7 +78,7 @@ pub async fn start(
 ) -> Result<()> {
 ) -> Result<()> {
     let p2p = net::P2p::new(options.network_settings);
     let p2p = net::P2p::new(options.network_settings);
 
 
-    let rpc = RpcInterface::new(p2p.clone());
+    let rpc = RpcInterface::new(p2p.clone())?;
     let http = listen(
     let http = listen(
         executor.clone(),
         executor.clone(),
         rpc.clone(),
         rpc.clone(),
@@ -107,18 +107,20 @@ pub struct RpcInterface {
     pub started: Mutex<bool>,
     pub started: Mutex<bool>,
     stop_send: async_channel::Sender<()>,
     stop_send: async_channel::Sender<()>,
     stop_recv: async_channel::Receiver<()>,
     stop_recv: async_channel::Receiver<()>,
+    adapter: Arc<RpcAdapter>,
 }
 }
 
 
 impl RpcInterface {
 impl RpcInterface {
-    pub fn new(p2p: Arc<net::P2p>) -> Arc<Self> {
+    pub fn new(p2p: Arc<net::P2p>) -> Result<Arc<Self>> {
         let (stop_send, stop_recv) = async_channel::unbounded::<()>();
         let (stop_send, stop_recv) = async_channel::unbounded::<()>();
-
-        Arc::new(Self {
+        let adapter = RpcAdapter::new("wallet.db")?;
+        Ok(Arc::new(Self {
             p2p,
             p2p,
             started: Mutex::new(false),
             started: Mutex::new(false),
             stop_send,
             stop_send,
             stop_recv,
             stop_recv,
-        })
+            adapter,
+        }))
     }
     }
 
 
     pub async fn serve(self: Arc<Self>, mut req: Request) -> http_types::Result<Response> {
     pub async fn serve(self: Arc<Self>, mut req: Request) -> http_types::Result<Response> {
@@ -138,7 +140,7 @@ impl RpcInterface {
         Ok(res)
         Ok(res)
     }
     }
 
 
-    pub async fn handle_input(&self) -> Result<jsonrpc_core::IoHandler> {
+    pub async fn handle_input(self: Arc<Self>) -> Result<jsonrpc_core::IoHandler> {
         debug!(target: "rpc", "JsonRpcInterface::handle_input() [START]");
         debug!(target: "rpc", "JsonRpcInterface::handle_input() [START]");
         let mut io = jsonrpc_core::IoHandler::new();
         let mut io = jsonrpc_core::IoHandler::new();
 
 
@@ -151,50 +153,63 @@ impl RpcInterface {
             Ok(jsonrpc_core::Value::String("TEST PATH!".into()))
             Ok(jsonrpc_core::Value::String("TEST PATH!".into()))
         });
         });
 
 
-        io.add_method("get_cash_key", move |_| async move {
-            RpcAdapter::get_cash_key().await.expect("Failed to get key");
-            Ok(jsonrpc_core::Value::String("Getting cashier key...".into()))
+        io.add_method("get_cash_key", move |_| {
+            async move {
+                //RpcAdapter::get_cash_key().await.expect("Failed to get key");
+                Ok(jsonrpc_core::Value::String("Getting cashier key...".into()))
+            }
         });
         });
 
 
-        io.add_method("get_info", move |_| async move {
-            RpcAdapter::get_info().await;
-            Ok(jsonrpc_core::Value::Null)
+        io.add_method("get_info", move |_| {
+            async move {
+                //RpcAdapter::get_info().await;
+                Ok(jsonrpc_core::Value::Null)
+            }
         });
         });
 
 
-        io.add_method("stop", move |_| async move {
-            RpcAdapter::stop().await;
-            Ok(jsonrpc_core::Value::Null)
+        io.add_method("stop", move |_| {
+            async move {
+                //self.adapter.stop().await;
+                Ok(jsonrpc_core::Value::Null)
+            }
         });
         });
         io.add_method("new_wallet", move |_| async move {
         io.add_method("new_wallet", move |_| async move {
             println!("New wallet method called...");
             println!("New wallet method called...");
-            RpcAdapter::new_wallet()
-                .await
-                .expect("Failed to create wallet.");
-            Ok(jsonrpc_core::Value::Null)
-        });
-        io.add_method("key_gen", move |_| async move {
-            println!("Key generation method called...");
-            RpcAdapter::key_gen().await.expect("Failed to generate key");
+            RpcAdapter::new("wallet.db").expect("Failed to create wallet");
             Ok(jsonrpc_core::Value::String(
             Ok(jsonrpc_core::Value::String(
-                "Attempted key generation".into(),
-            ))
-        });
-        io.add_method("cash_key_gen", move |_| async move {
-            println!("Key generation method called...");
-            RpcAdapter::cash_key_gen()
-                .await
-                .expect("Failed to generate key");
-            Ok(jsonrpc_core::Value::String(
-                "Attempted key generation".into(),
+                "Attempted wallet generation".into(),
             ))
             ))
         });
         });
+        let self3 = self.clone();
+        //io.add_method("key_gen", move |_| {
+        //    let self4 = self3.clone();
+        //    async move {
+        //        println!("Key generation method called...");
+        //        self4.adapter.key_gen().await.expect("Failed to generate key");
+        //        //RpcAdapter::key_gen().await.expect("Failed to generate key");
+        //        Ok(jsonrpc_core::Value::String(
+        //            "Attempted key generation".into(),
+        //        ))
+        //    }
+        //});
+        let self5 = self.clone();
+        //io.add_method("cash_key_gen", move |_| {
+        //    let self6 = self5.clone();
+        //    async move {
+        //        println!("Key generation method called...");
+        //        //RpcAdapter::cash_key_gen()
+        //            //.await
+        //            //.expect("Failed to generate key");
+        //        Ok(jsonrpc_core::Value::String(
+        //            "Attempted key generation".into(),
+        //        ))
+        //    }
+        //});
         io.add_method("new_cashier_wallet", move |_| async move {
         io.add_method("new_cashier_wallet", move |_| async move {
-            println!("Key generation method called...");
-            RpcAdapter::new_cash_wallet()
-                .await
-                .expect("Failed to generate key");
+            println!("New wallet method called...");
+            RpcAdapter::new("cashier.db").expect("Failed to create wallet");
             Ok(jsonrpc_core::Value::String(
             Ok(jsonrpc_core::Value::String(
-                "Tried to create new cashier wallet".into(),
+                "Attempted wallet generation".into(),
             ))
             ))
         });
         });
         debug!(target: "rpc", "JsonRpcInterface::handle_input() [END]");
         debug!(target: "rpc", "JsonRpcInterface::handle_input() [END]");

+ 51 - 25
src/wallet/walletdb.rs

@@ -1,30 +1,46 @@
+use crate::crypto::{coin::Coin, merkle::IncrementalWitness, merkle_node::MerkleNode, note::Note};
 use crate::serial;
 use crate::serial;
-use async_std::sync::Arc;
-use crate::serial::{deserialize, serialize, Decodable, Encodable};
+use crate::serial::{deserialize, Decodable};
 use crate::Error;
 use crate::Error;
 use crate::Result;
 use crate::Result;
+use async_std::sync::Arc;
 use ff::Field;
 use ff::Field;
 use log::*;
 use log::*;
 use rand::rngs::OsRng;
 use rand::rngs::OsRng;
-use rusqlite::{named_params, Connection};
+use rusqlite::{named_params, Connection, OpenFlags};
 use std::path::PathBuf;
 use std::path::PathBuf;
 
 
 pub struct WalletDB {
 pub struct WalletDB {
-    path: PathBuf,
+    pub path: PathBuf,
+    secrets: Vec<jubjub::Fr>,
+    cashier_secrets: Vec<jubjub::Fr>,
+    own_coins: Vec<(Coin, Note, jubjub::Fr, IncrementalWitness<MerkleNode>)>,
+    cashier_public: jubjub::SubgroupPoint,
+    //conn: Arc<Connection>,
 }
 }
 
 
 impl WalletDB {
 impl WalletDB {
     pub fn new(wallet: &str) -> Result<Arc<Self>> {
     pub fn new(wallet: &str) -> Result<Arc<Self>> {
         let path = Self::create_path(wallet)?;
         let path = Self::create_path(wallet)?;
-        let connect = Connection::open(&path)?;
+        let conn = Connection::open(&path)?;
+        //let conn = Arc::new(Connection::open_with_flags(&path, OpenFlags::SQLITE_OPEN_NO_MUTEX)?);
         let contents = include_str!("../../res/schema.sql");
         let contents = include_str!("../../res/schema.sql");
-        connect.execute_batch(&contents)?;
+        let cashier_secret = jubjub::Fr::random(&mut OsRng);
+        let secret = jubjub::Fr::random(&mut OsRng);
+        let _public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
+        let cashier_public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * cashier_secret;
+        conn.execute_batch(&contents)?;
         Ok(Arc::new(Self {
         Ok(Arc::new(Self {
-            path
+            path,
+            own_coins: vec![],
+            cashier_secrets: vec![cashier_secret.clone()],
+            secrets: vec![secret.clone()],
+            cashier_public,
+            //conn,
         }))
         }))
     }
     }
 
 
-    pub fn create_path(wallet: &str) -> Result<PathBuf> {
+    fn create_path(wallet: &str) -> Result<PathBuf> {
         let mut path = dirs::home_dir()
         let mut path = dirs::home_dir()
             .ok_or(Error::PathNotFound)?
             .ok_or(Error::PathNotFound)?
             .as_path()
             .as_path()
@@ -34,11 +50,15 @@ impl WalletDB {
         Ok(path)
         Ok(path)
     }
     }
 
 
-    pub async fn save_key(&self, path: PathBuf, pubkey: Vec<u8>, privkey: Vec<u8>) -> Result<()> {
-        debug!(target: "key_gen", "Generating keys...");
-        let connect = Connection::open(&path)?;
-        debug!(target: "adapter", "key_gen() [Saving public key...]");
-        connect.execute(
+    //fn get_path() -> Result<PathBuf> {
+    //    Ok(self.path)
+    //}
+
+    pub async fn put_key(&self, pubkey: Vec<u8>, privkey: Vec<u8>) -> Result<()> {
+        //debug!(target: "key_gen", "Generating keys...");
+        let conn = Connection::open(&self.path)?;
+        //debug!(target: "adapter", "key_gen() [Saving public key...]");
+        conn.execute(
             "INSERT INTO keys(key_id, key_private, key_public)
             "INSERT INTO keys(key_id, key_private, key_public)
             VALUES (NULL, :privkey, :pubkey)",
             VALUES (NULL, :privkey, :pubkey)",
             named_params! {
             named_params! {
@@ -49,20 +69,19 @@ impl WalletDB {
         Ok(())
         Ok(())
     }
     }
 
 
-    pub async fn create_key(&self) -> (Vec<u8>, Vec<u8>) {
+    pub async fn key_gen(&self) -> (Vec<u8>, Vec<u8>) {
         debug!(target: "key_gen", "Generating keys...");
         debug!(target: "key_gen", "Generating keys...");
         let secret: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
         let secret: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
         let public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
         let public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
         let pubkey = serial::serialize(&public);
         let pubkey = serial::serialize(&public);
         let privkey = serial::serialize(&secret);
         let privkey = serial::serialize(&secret);
-        // Write keys to database
         (pubkey, privkey)
         (pubkey, privkey)
     }
     }
 
 
-    pub async fn get_public(&self, path: PathBuf) -> Result<Vec<u8>> {
+    pub async fn get_public(&self) -> Result<Vec<u8>> {
         debug!(target: "get", "Returning keys...");
         debug!(target: "get", "Returning keys...");
-        let connect = Connection::open(&path)?;
-        let mut stmt = connect.prepare("SELECT key_public FROM keys")?;
+        let conn = Connection::open(&self.path)?;
+        let mut stmt = conn.prepare("SELECT key_public FROM keys")?;
         let key_iter = stmt.query_map::<u8, _, _>([], |row| row.get(0))?;
         let key_iter = stmt.query_map::<u8, _, _>([], |row| row.get(0))?;
         let mut pub_keys = Vec::new();
         let mut pub_keys = Vec::new();
         for key in key_iter {
         for key in key_iter {
@@ -71,10 +90,10 @@ impl WalletDB {
         Ok(pub_keys)
         Ok(pub_keys)
     }
     }
 
 
-    pub fn get_private(&self, path: PathBuf) -> Result<Vec<u8>> {
+    pub fn get_private(&self) -> Result<Vec<u8>> {
         debug!(target: "get", "Returning keys...");
         debug!(target: "get", "Returning keys...");
-        let connect = Connection::open(&path)?;
-        let mut stmt = connect.prepare("SELECT key_private FROM keys")?;
+        let conn = Connection::open(&self.path)?;
+        let mut stmt = conn.prepare("SELECT key_private FROM keys")?;
         let key_iter = stmt.query_map::<u8, _, _>([], |row| row.get(0))?;
         let key_iter = stmt.query_map::<u8, _, _>([], |row| row.get(0))?;
         let mut keys = Vec::new();
         let mut keys = Vec::new();
         for key in key_iter {
         for key in key_iter {
@@ -88,16 +107,23 @@ impl WalletDB {
         Ok(v)
         Ok(v)
     }
     }
 
 
-    pub async fn save(&self, path: PathBuf, pubkey: Vec<u8>) -> Result<()> {
+    pub async fn put_cashier_pub(&self, pubkey: Vec<u8>) -> Result<()> {
         debug!(target: "save_cash_key", "Save cashier keys...");
         debug!(target: "save_cash_key", "Save cashier keys...");
-        //let path = Self::wallet_path();
-        let connect = Connection::open(&path)?;
+        let conn = Connection::open(&self.path)?;
         // Write keys to database
         // Write keys to database
-        connect.execute(
+        conn.execute(
             "INSERT INTO cashier(key_id, key_public)
             "INSERT INTO cashier(key_id, key_public)
             VALUES (NULL, :pubkey)",
             VALUES (NULL, :pubkey)",
             named_params! {":pubkey": pubkey},
             named_params! {":pubkey": pubkey},
         )?;
         )?;
         Ok(())
         Ok(())
     }
     }
+
+    pub async fn is_valid_cashier_pub(&self, public: &jubjub::SubgroupPoint) -> Result<bool> {
+        let conn = Connection::open(&self.path)?;
+        let mut stmt = conn
+            .prepare("SELECT key_public FROM cashier WHERE key_public IN (SELECT key_public)")
+            .expect("Cannot generate statement.");
+        Ok(stmt.exists([1i32])?)
+    }
 }
 }