Преглед изворни кода

added key_id param to put_own_coins

rachel-rose пре 5 година
родитељ
комит
01e109493d
11 измењених фајлова са 118 додато и 53 уклоњено
  1. 4 6
      res/schema.sql
  2. 5 3
      src/bin/darkfid.rs
  3. 2 2
      src/bin/gatewayd.rs
  4. 0 1
      src/bin/tutorial.rs
  5. 1 4
      src/blockchain/slab.rs
  6. 0 1
      src/crypto/fr_serial.rs
  7. 0 2
      src/error.rs
  8. 2 2
      src/lib.rs
  9. 6 21
      src/rpc/jsonserver.rs
  10. 0 1
      src/util.rs
  11. 98 10
      src/wallet/walletdb.rs

+ 4 - 6
res/schema.sql

@@ -9,17 +9,15 @@ CREATE TABLE IF NOT EXISTS coins(
     coin_id INTEGER PRIMARY KEY NOT NULL,
     coin BLOB NOT NULL,
     serial BLOB NOT NULL,
-    value INT NOT NULL,
-    asset_id INT NOT NULL,
     coin_blind BLOB NOT NULL,
     valcom_blind BLOB NOT NULL,
-    tree BLOB NOT NULL,
-    filled BLOB NOT NULL,
-    cursor_depth BLOB NOT NULL,
-    cursor_ BLOB NOT NULL,
+    value INT NOT NULL,
+    asset_id INT NOT NULL,
+    witness BLOB NOT NULL,
     key_id INTEGER NOT NULL,
     FOREIGN KEY (key_id)
         REFERENCES keys (key_id)
+        ON UPDATE CASCADE
 );
 CREATE TABLE IF NOT EXISTS cashier(
     key_id INTEGER PRIMARY KEY NOT NULL,

+ 5 - 3
src/bin/darkfid.rs

@@ -1,5 +1,4 @@
 use drk::blockchain::{rocks::columns, Rocks, RocksColumn};
-use log::*;
 use drk::cli::{cli_config, WalletCli};
 use drk::crypto::{
     load_params,
@@ -15,6 +14,7 @@ use drk::state::{state_transition, ProgramState, StateUpdate};
 use drk::util::join_config_path;
 use drk::wallet::{WalletDB, WalletPtr};
 use drk::{tx, Result};
+use log::*;
 //use drk::rpc::
 use drk::rpc::adapter::RpcAdapter;
 use drk::rpc::jsonserver;
@@ -104,7 +104,7 @@ impl State {
                 witness.append(node).expect("append to witness");
             }
 
-            if let Some((note, _secret)) = self.try_decrypt_note(enc_note).await {
+            if let Some((note, secret)) = self.try_decrypt_note(enc_note).await {
                 // 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
@@ -117,7 +117,9 @@ impl State {
                 // Make a new witness for this coin
                 let witness = IncrementalWitness::from_tree(&self.tree);
 
-                self.wallet.put_own_coins(coin, note, witness).await?;
+                self.wallet
+                    .put_own_coins(coin, note, witness, secret)
+                    .await?;
             }
         }
         Ok(())

+ 2 - 2
src/bin/gatewayd.rs

@@ -2,10 +2,10 @@ use std::net::SocketAddr;
 use std::sync::Arc;
 
 use drk::blockchain::{rocks::columns, Rocks, RocksColumn};
-use drk::service::GatewayService;
 use drk::cli::ServiceCli;
-use drk::Result;
+use drk::service::GatewayService;
 use drk::util::join_config_path;
+use drk::Result;
 
 extern crate clap;
 use async_executor::Executor;

+ 0 - 1
src/bin/tutorial.rs

@@ -84,4 +84,3 @@ fn main() -> Result<()> {
 
     Ok(())
 }
-

+ 1 - 4
src/blockchain/slab.rs

@@ -10,10 +10,7 @@ pub struct Slab {
 impl Slab {
     pub fn new(payload: Vec<u8>) -> Self {
         let index = 0;
-        Slab {
-            index,
-            payload,
-        }
+        Slab { index, payload }
     }
 
     pub fn set_index(&mut self, index: u64) {

+ 0 - 1
src/crypto/fr_serial.rs

@@ -1,7 +1,6 @@
 use group::GroupEncoding;
 use std::io;
 
-
 use crate::error::{Error, Result};
 use crate::serial::{Decodable, Encodable, ReadExt, WriteExt};
 

+ 0 - 2
src/error.rs

@@ -111,7 +111,6 @@ impl From<jsonrpc_core::Error> for Error {
     }
 }
 
-
 impl From<Error> for jsonrpc_core::Error {
     fn from(_err: Error) -> jsonrpc_core::Error {
         jsonrpc_core::Error::parse_error()
@@ -183,4 +182,3 @@ impl From<state::VerifyFailed> for Error {
         Error::VerifyFailed
     }
 }
-

+ 2 - 2
src/lib.rs

@@ -8,6 +8,7 @@ pub mod async_serial;
 pub mod blockchain;
 pub mod bls_extensions;
 pub mod circuit;
+pub mod cli;
 pub mod crypto;
 pub mod endian;
 pub mod error;
@@ -18,11 +19,10 @@ pub mod service;
 pub mod state;
 pub mod system;
 pub mod tx;
+pub mod util;
 pub mod vm;
 pub mod vm_serial;
 pub mod wallet;
-pub mod util;
-pub mod cli;
 
 pub use crate::bls_extensions::BlsStringConversion;
 pub use crate::error::{Error, Result};

+ 6 - 21
src/rpc/jsonserver.rs

@@ -1,5 +1,5 @@
-use crate::rpc::adapter::RpcAdapter;
 use crate::cli::cli_config;
+use crate::rpc::adapter::RpcAdapter;
 use crate::{Error, Result};
 use async_executor::Executor;
 use async_native_tls::TlsAcceptor;
@@ -153,10 +153,7 @@ impl RpcInterface {
         io.add_method("get_cash_key", move |_| {
             let self2 = self1.clone();
             async move {
-                self2
-                    .adapter
-                    .get_cash_key()
-                    .await?;
+                self2.adapter.get_cash_key().await?;
                 Ok(jsonrpc_core::Value::String("Getting cashier key...".into()))
             }
         });
@@ -186,10 +183,7 @@ impl RpcInterface {
                     "Attempting wallet generation at path {:?}",
                     self2.adapter.wallet.path
                 );
-                self2
-                    .adapter
-                    .init_db()
-                    .await?;
+                self2.adapter.init_db().await?;
                 Ok(jsonrpc_core::Value::String("Created wallet".into()))
             }
         });
@@ -198,10 +192,7 @@ impl RpcInterface {
             let self2 = self1.clone();
             async move {
                 println!("Key generation method called...");
-                self2
-                    .adapter
-                    .key_gen()
-                    .await?;
+                self2.adapter.key_gen().await?;
                 Ok(jsonrpc_core::Value::String(
                     "Key generation successful".into(),
                 ))
@@ -212,10 +203,7 @@ impl RpcInterface {
             let self2 = self1.clone();
             async move {
                 println!("Key generation method called...");
-                self2
-                    .adapter
-                    .cash_key_gen()
-                    .await?;
+                self2.adapter.cash_key_gen().await?;
                 Ok(jsonrpc_core::Value::String(
                     "Attempted key generation".into(),
                 ))
@@ -235,10 +223,7 @@ impl RpcInterface {
             let self2 = self1.clone();
             async move {
                 println!("New wallet method called...");
-                self2
-                    .adapter
-                    .init_cashier_db()
-                    .await?;
+                self2.adapter.init_cashier_db().await?;
                 println!("Wallet created at path {:?}", self2.adapter.wallet.path);
                 Ok(jsonrpc_core::Value::String("Created cashier wallet".into()))
             }

+ 0 - 1
src/util.rs

@@ -1,4 +1,3 @@
-
 use crate::Error;
 use crate::Result;
 

+ 98 - 10
src/wallet/walletdb.rs

@@ -1,14 +1,14 @@
 use crate::crypto::{coin::Coin, merkle::IncrementalWitness, merkle_node::MerkleNode, note::Note};
 use crate::serial;
 use crate::serial::{deserialize, serialize, Decodable, Encodable};
-use crate::Result;
 use crate::util::join_config_path;
+use crate::Result;
 
 use async_std::sync::{Arc, Mutex};
 use ff::Field;
 use log::*;
 use rand::rngs::OsRng;
-use rusqlite::{params, named_params, Connection};
+use rusqlite::{named_params, params, Connection};
 
 use std::path::PathBuf;
 
@@ -76,7 +76,9 @@ impl WalletDB {
         coin: Coin,
         note: Note,
         witness: IncrementalWitness<MerkleNode>,
+        secret: jubjub::Fr,
     ) -> Result<()> {
+        // prepare the values
         let coin = self.get_value_serialized(&coin.repr).await?;
         let serial = self.get_value_serialized(&note.serial).await?;
         let coin_blind = self.get_value_serialized(&note.coin_blind).await?;
@@ -84,12 +86,24 @@ impl WalletDB {
         let value = self.get_value_serialized(&note.value).await?;
         let asset_id = self.get_value_serialized(&note.asset_id).await?;
         let witness = self.get_value_serialized(&witness).await?;
+        let secret = self.get_value_serialized(&secret).await?;
+        // open connection
         let conn = Connection::open(&self.path)?;
-        let mut stmt = conn.prepare("PRAGMA key = 'testkey'")?;
-        let _rows = stmt.query([])?;
+        // unlock database
+        let mut unlock = conn.prepare("PRAGMA key = 'testkey'")?;
+        let _rows = unlock.query([])?;
+        // return key_id from key_private
+        let mut get_id =
+            conn.prepare("SELECT key_id FROM keys WHERE key_private = :key_private")?;
+        let rows = get_id.query_map::<u8, _, _>(&[(":key_private", &secret)], |row| row.get(0))?;
+        let mut key_id = Vec::new();
+        for id in rows {
+            key_id.push(id?)
+        }
+        debug!("FOUND KEY ID: {:?}", key_id.pop());
         conn.execute(
             "INSERT INTO coins(coin, serial, value, asset_id, coin_blind, valcom_blind, witness, key_id)
-            VALUES (NULL, :coin, :serial, :value, :asset_id, :coin_blind, :valcom_blind, :witness, :key_id)",
+            VALUES (:coin, :serial, :value, :asset_id, :coin_blind, :valcom_blind, :witness, :key_id)",
             named_params! {
             ":coin": coin,
             ":serial": serial,
@@ -98,6 +112,7 @@ impl WalletDB {
             ":coin_blind": coin_blind,
             ":valcom_blind": valcom_blind,
             ":witness": witness,
+            ":key_id": key_id.pop().expect("key_id not found!"),
             },
         )?;
         Ok(())
@@ -127,7 +142,8 @@ impl WalletDB {
         let _rows = stmt.query([])?;
         conn.execute(
             "INSERT INTO keys(key_public, key_private) VALUES (?1, ?2)",
-            params![key_public, key_private])?;
+            params![key_public, key_private],
+        )?;
         Ok(())
     }
 
@@ -138,7 +154,8 @@ impl WalletDB {
         let _rows = stmt.query([])?;
         conn.execute(
             "INSERT INTO cashier(key_public) VALUES (?1)",
-            params![key_public])?;
+            params![key_public],
+        )?;
         Ok(())
     }
 
@@ -206,9 +223,9 @@ impl WalletDB {
 #[cfg(test)]
 mod tests {
 
-use super::*;
+    use super::*;
 
-#[test] 
+    #[test]
     pub fn test_keypair() -> Result<()> {
         let path = join_config_path(&PathBuf::from("wallet.db"))?;
         let conn = Connection::open(path)?;
@@ -220,7 +237,78 @@ use super::*;
         let _rows = stmt.query([])?;
         conn.execute(
             "INSERT INTO keys(key_public, key_private) VALUES (?1, ?2)",
-            params![key_public, key_private])?;
+            params![key_public, key_private],
+        )?;
+        Ok(())
+    }
+
+    #[test]
+    pub fn test_get_id() -> Result<()> {
+        let path = join_config_path(&PathBuf::from("wallet.db"))?;
+        let conn = Connection::open(path)?;
+        let secret: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
+        let key_private = serial::serialize(&secret);
+        let public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
+        let key_public = serial::serialize(&public);
+        let mut stmt = conn.prepare("PRAGMA key = 'testkey'")?;
+        let _rows = stmt.query([])?;
+        conn.execute(
+            "INSERT INTO keys(key_public, key_private) VALUES (?1, ?2)",
+            params![key_public, key_private],
+        )?;
+        let mut get_id =
+            conn.prepare("SELECT key_id FROM keys WHERE key_private = :key_private")?;
+        let rows =
+            get_id.query_map::<u8, _, _>(&[(":key_private", &key_private)], |row| row.get(0))?;
+        let mut key_id = Vec::new();
+        for id in rows {
+            key_id.push(id?)
+        }
+        println!("FOUND ID: {:?}", key_id.pop().unwrap());
+        Ok(())
+    }
+
+    #[test]
+    pub fn test_own_coins() -> Result<()> {
+        let key_private = Vec::new();
+        let coin = Vec::new();
+        let serial = Vec::new();
+        let coin_blind = Vec::new();
+        let valcom_blind = Vec::new();
+        let value = Vec::new();
+        let asset_id = Vec::new();
+        let witness = Vec::new();
+        let path = join_config_path(&PathBuf::from("wallet.db"))?;
+        let conn = Connection::open(path)?;
+        let contents = include_str!("../../res/schema.sql");
+        match conn.execute_batch(&contents) {
+            Ok(v) => println!("Database initalized successfully {:?}", v),
+            Err(err) => println!("Error: {}", err),
+        };
+        let mut unlock = conn.prepare("PRAGMA key = 'testkey'")?;
+        let _rows = unlock.query([])?;
+        let mut get_id =
+            conn.prepare("SELECT key_id FROM keys WHERE key_private = :key_private")?;
+        let rows =
+            get_id.query_map::<u8, _, _>(&[(":key_private", &key_private)], |row| row.get(0))?;
+        let mut key_id = Vec::new();
+        for id in rows {
+            key_id.push(id?)
+        }
+        conn.execute(
+            "INSERT INTO coins(coin, serial, value, asset_id, coin_blind, valcom_blind, witness, key_id)
+            VALUES (:coin, :serial, :value, :asset_id, :coin_blind, :valcom_blind, :witness, :key_id)",
+            named_params! {
+            ":coin": coin,
+            ":serial": serial,
+            ":value": value,
+            ":asset_id": asset_id,
+            ":coin_blind": coin_blind,
+            ":valcom_blind": valcom_blind,
+            ":witness": witness,
+            ":key_id": key_id.pop().expect("key_id not found!"),
+            },
+        )?;
         Ok(())
     }
 }