From 01e109493de33dc489f125991fecace963d0972f Mon Sep 17 00:00:00 2001 From: rachel-rose Date: Mon, 5 Jul 2021 13:00:31 +0200 Subject: [PATCH] added key_id param to put_own_coins --- res/schema.sql | 10 ++-- src/bin/darkfid.rs | 8 +-- src/bin/gatewayd.rs | 4 +- src/bin/tutorial.rs | 1 - src/blockchain/slab.rs | 5 +- src/crypto/fr_serial.rs | 1 - src/error.rs | 2 - src/lib.rs | 4 +- src/rpc/jsonserver.rs | 27 +++------- src/util.rs | 1 - src/wallet/walletdb.rs | 108 ++++++++++++++++++++++++++++++++++++---- 11 files changed, 118 insertions(+), 53 deletions(-) diff --git a/res/schema.sql b/res/schema.sql index 6ff909b05..23ec6ec24 100644 --- a/res/schema.sql +++ b/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, diff --git a/src/bin/darkfid.rs b/src/bin/darkfid.rs index 7de2cdfb3..40f20c2ac 100644 --- a/src/bin/darkfid.rs +++ b/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(()) diff --git a/src/bin/gatewayd.rs b/src/bin/gatewayd.rs index 0aa08e524..18e48c211 100644 --- a/src/bin/gatewayd.rs +++ b/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; diff --git a/src/bin/tutorial.rs b/src/bin/tutorial.rs index e8c9445a2..f0fea01dc 100644 --- a/src/bin/tutorial.rs +++ b/src/bin/tutorial.rs @@ -84,4 +84,3 @@ fn main() -> Result<()> { Ok(()) } - diff --git a/src/blockchain/slab.rs b/src/blockchain/slab.rs index e8229f8fc..e2f10a651 100644 --- a/src/blockchain/slab.rs +++ b/src/blockchain/slab.rs @@ -10,10 +10,7 @@ pub struct Slab { impl Slab { pub fn new(payload: Vec) -> Self { let index = 0; - Slab { - index, - payload, - } + Slab { index, payload } } pub fn set_index(&mut self, index: u64) { diff --git a/src/crypto/fr_serial.rs b/src/crypto/fr_serial.rs index 9459e8ee3..d73a1e699 100644 --- a/src/crypto/fr_serial.rs +++ b/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}; diff --git a/src/error.rs b/src/error.rs index cee0927aa..7af0f6a29 100644 --- a/src/error.rs +++ b/src/error.rs @@ -111,7 +111,6 @@ impl From for Error { } } - impl From for jsonrpc_core::Error { fn from(_err: Error) -> jsonrpc_core::Error { jsonrpc_core::Error::parse_error() @@ -183,4 +182,3 @@ impl From for Error { Error::VerifyFailed } } - diff --git a/src/lib.rs b/src/lib.rs index 50f9aa204..7a08c66fa 100644 --- a/src/lib.rs +++ b/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}; diff --git a/src/rpc/jsonserver.rs b/src/rpc/jsonserver.rs index d3be0cf00..6f82eb080 100644 --- a/src/rpc/jsonserver.rs +++ b/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())) } diff --git a/src/util.rs b/src/util.rs index 230d4f230..de3b3643e 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,4 +1,3 @@ - use crate::Error; use crate::Result; diff --git a/src/wallet/walletdb.rs b/src/wallet/walletdb.rs index 7bca0f74d..89ee4feb3 100644 --- a/src/wallet/walletdb.rs +++ b/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, + secret: jubjub::Fr, ) -> Result<()> { + // prepare the values let coin = self.get_value_serialized(&coin.repr).await?; let serial = self.get_value_serialized(¬e.serial).await?; let coin_blind = self.get_value_serialized(¬e.coin_blind).await?; @@ -84,12 +86,24 @@ impl WalletDB { let value = self.get_value_serialized(¬e.value).await?; let asset_id = self.get_value_serialized(¬e.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::(&[(":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::(&[(":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::(&[(":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(()) } }