walletdb.rs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. use crate::crypto::{coin::Coin, merkle::IncrementalWitness, merkle_node::MerkleNode, note::Note};
  2. use crate::serial;
  3. use crate::serial::{deserialize, serialize, Decodable, Encodable};
  4. use crate::Error;
  5. use crate::Result;
  6. use async_std::sync::Arc;
  7. use ff::Field;
  8. use log::*;
  9. use rand::rngs::OsRng;
  10. use rusqlite::{named_params, Connection, OpenFlags};
  11. use std::path::{Path, PathBuf};
  12. pub struct WalletDB {
  13. pub path: PathBuf,
  14. pub secrets: Vec<jubjub::Fr>,
  15. pub cashier_secrets: Vec<jubjub::Fr>,
  16. pub own_coins: Vec<(Coin, Note, jubjub::Fr, IncrementalWitness<MerkleNode>)>,
  17. pub cashier_public: jubjub::SubgroupPoint,
  18. //conn: Arc<Connection>,
  19. }
  20. impl WalletDB {
  21. pub fn new(wallet: &str) -> Result<Self> {
  22. let path = Self::create_path(wallet)?;
  23. let conn = Connection::open(&path)?;
  24. let contents = include_str!("../../res/schema.sql");
  25. let cashier_secret = jubjub::Fr::random(&mut OsRng);
  26. let secret = jubjub::Fr::random(&mut OsRng);
  27. let _public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
  28. let cashier_public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * cashier_secret;
  29. match conn.execute_batch(&contents) {
  30. Ok(v) => println!("Database initalized successfully {:?}", v),
  31. Err(err) => println!("Error: {}", err),
  32. };
  33. Ok(Self {
  34. path,
  35. own_coins: vec![],
  36. cashier_secrets: vec![cashier_secret.clone()],
  37. secrets: vec![secret.clone()],
  38. cashier_public,
  39. //conn,
  40. })
  41. }
  42. pub async fn put_own_coins(&self) -> Result<()> {
  43. let coin = self.get_value_serialized(&self.own_coins[0].0.repr).await?;
  44. let note = &self.own_coins[0].1;
  45. let serial = self.get_value_serialized(&note.serial).await?;
  46. let coin_blind = self.get_value_serialized(&note.coin_blind).await?;
  47. let valcom_blind = self.get_value_serialized(&note.valcom_blind).await?;
  48. let value = self.get_value_serialized(&note.value).await?;
  49. let conn = Connection::open(&self.path)?;
  50. let witness = self.get_value_serialized(&self.own_coins[0].3).await?;
  51. conn.execute(
  52. "INSERT INTO coins(coin, serial, value, coin_blind, valcom_blind, witness, key_id)
  53. VALUES (NULL, :coin, :serial, :value, :coin_blind, :valcom_blind, :witness, :key_id)",
  54. named_params! {
  55. ":coin": coin,
  56. ":serial": serial,
  57. ":value": value,
  58. ":coin_blind": coin_blind,
  59. ":valcom_blind": valcom_blind,
  60. ":witness": witness,
  61. },
  62. )?;
  63. Ok(())
  64. }
  65. fn create_path(wallet: &str) -> Result<PathBuf> {
  66. let mut path = dirs::home_dir()
  67. .ok_or(Error::PathNotFound)?
  68. .as_path()
  69. .join(".config/darkfi/");
  70. path.push(wallet);
  71. debug!(target: "walletdb", "CREATE PATH {:?}", path);
  72. Ok(path)
  73. }
  74. pub async fn key_gen(&self) -> (Vec<u8>, Vec<u8>) {
  75. debug!(target: "key_gen", "Generating keys...");
  76. let secret: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
  77. let public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
  78. let pubkey = serial::serialize(&public);
  79. let privkey = serial::serialize(&secret);
  80. (pubkey, privkey)
  81. }
  82. pub async fn put_keypair(&self, pubkey: Vec<u8>, privkey: Vec<u8>) -> Result<()> {
  83. //debug!(target: "key_gen", "Generating keys...");
  84. let conn = Connection::open(&self.path)?;
  85. //debug!(target: "adapter", "key_gen() [Saving public key...]");
  86. conn.execute(
  87. "INSERT INTO keys(key_id, key_private, key_public)
  88. VALUES (NULL, :privkey, :pubkey)",
  89. named_params! {
  90. ":privkey": privkey,
  91. ":pubkey": pubkey
  92. },
  93. )?;
  94. Ok(())
  95. }
  96. pub async fn put_cashier_pub(&self, pubkey: Vec<u8>) -> Result<()> {
  97. debug!(target: "save_cash_key", "Save cashier keys...");
  98. let conn = Connection::open(&self.path)?;
  99. // Write keys to database
  100. conn.execute(
  101. "INSERT INTO cashier(key_id, key_public)
  102. VALUES (NULL, :pubkey)",
  103. named_params! {":pubkey": pubkey},
  104. )?;
  105. Ok(())
  106. }
  107. pub async fn get_public(&self) -> Result<Vec<u8>> {
  108. debug!(target: "get", "Returning keys...");
  109. let conn = Connection::open(&self.path)?;
  110. let mut stmt = conn.prepare("SELECT key_public FROM keys")?;
  111. let key_iter = stmt.query_map::<u8, _, _>([], |row| row.get(0))?;
  112. let mut pub_keys = Vec::new();
  113. for key in key_iter {
  114. pub_keys.push(key?);
  115. }
  116. Ok(pub_keys)
  117. }
  118. pub fn get_private(&self) -> Result<Vec<u8>> {
  119. debug!(target: "get", "Returning keys...");
  120. let conn = Connection::open(&self.path)?;
  121. let mut stmt = conn.prepare("SELECT key_private FROM keys")?;
  122. let key_iter = stmt.query_map::<u8, _, _>([], |row| row.get(0))?;
  123. let mut keys = Vec::new();
  124. for key in key_iter {
  125. keys.push(key?);
  126. }
  127. Ok(keys)
  128. }
  129. pub async fn get_value_serialized<T: Encodable>(&self, data: &T) -> Result<Vec<u8>> {
  130. let v = serialize(data);
  131. Ok(v)
  132. }
  133. pub async fn get_value_deserialized<D: Decodable>(&self, key: Vec<u8>) -> Result<D> {
  134. let v: D = deserialize(&key)?;
  135. Ok(v)
  136. }
  137. }