get keypair from walletdb instead of get keys separately

This commit is contained in:
ghassmo
2021-09-15 21:29:44 +03:00
parent 9fce761ae4
commit 8d1cb7bce6
6 changed files with 55 additions and 95 deletions

View File

@@ -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()?;
}

View File

@@ -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())

View File

@@ -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)

View File

@@ -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

View File

@@ -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);

View File

@@ -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()?;