mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-10 07:08:05 -05:00
wallet: WIP pasta port.
This commit is contained in:
2890
Cargo.lock
generated
2890
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
49
Cargo.toml
49
Cargo.toml
@@ -25,28 +25,35 @@ git = "https://github.com/zcash/incrementalmerkletree.git"
|
||||
rev = "b7bd6246122a6e9ace8edb51553fbf5228906cbb"
|
||||
|
||||
[dependencies.rocksdb]
|
||||
# TODO: Revert to upstream after bd966750ec861d687913d59a9939a1408ac53131 is merged.
|
||||
git = "https://github.com/parazyd/rust-rocksdb"
|
||||
rev = "bd966750ec861d687913d59a9939a1408ac53131"
|
||||
default-features = false
|
||||
features = ["lz4"]
|
||||
|
||||
[dependencies]
|
||||
# Crypto
|
||||
pasta_curves = "0.2.1"
|
||||
rand = "0.8.4"
|
||||
num-bigint = "0.4.2"
|
||||
num-bigint = {version = "0.4.2", features = ["rand"]}
|
||||
blake2b_simd = "0.5.11"
|
||||
blake2s_simd = "0.5.11"
|
||||
group = "0.11.0"
|
||||
crypto_api_chachapoly = "0.5.0"
|
||||
arrayvec = "0.7.0"
|
||||
sha2 = "0.9.8"
|
||||
ripemd160 = "0.9.1"
|
||||
|
||||
hex = "0.4.3"
|
||||
# Encoding and parsing
|
||||
bs58 = "0.4.0"
|
||||
bytes = "1.1.0"
|
||||
hex = "0.4.3"
|
||||
toml = "0.5.8"
|
||||
url = "2.2.2"
|
||||
serde_json = "1.0.68"
|
||||
serde = {version = "1.0.130", features = ["derive"]}
|
||||
|
||||
# Async
|
||||
async-std = "1.10.0"
|
||||
async-trait = "0.1.51"
|
||||
async-channel = "1.6.1"
|
||||
@@ -56,14 +63,42 @@ async-executor = "1.4.1"
|
||||
futures = "0.3.17"
|
||||
smol = "1.2.5"
|
||||
|
||||
log = "0.4.14"
|
||||
simple_logger = "1.13.0"
|
||||
num_cpus = "1.13.0"
|
||||
|
||||
# Utilities
|
||||
anyhow = "1.0.44"
|
||||
dirs = "4.0.0"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.14"
|
||||
num_cpus = "1.13.0"
|
||||
simple_logger = "1.13.0"
|
||||
signal-hook = "0.3.10"
|
||||
signal-hook-async-std = "0.2.1"
|
||||
|
||||
tungstenite = "0.15.0"
|
||||
# Used for Websockets client implementation.
|
||||
async-tungstenite = "0.15.0"
|
||||
tungstenite = "0.15.0"
|
||||
|
||||
# Used for wallet management.
|
||||
rusqlite = {version = "0.26.1", features = ["bundled-sqlcipher"]}
|
||||
|
||||
# Used for gatewayd network transport.
|
||||
zeromq = {version = "0.3.0", default-features = false, features = ["async-std-runtime", "all-transport"]}
|
||||
|
||||
# Cashier Bitcoin dependencies
|
||||
bdk = {version = "0.12.0", optional = true}
|
||||
bitcoin = {version = "0.27.0", optional = true}
|
||||
secp256k1 = {version = "0.20.3", default-features = false, features = ["rand-std"], optional = true}
|
||||
|
||||
# Cashier Ethereum dependencies
|
||||
hash-db = {version = "0.15.2", optional = true}
|
||||
keccak-hasher = {version = "0.15.3", optional = true}
|
||||
|
||||
# Cashier Solana dependencies
|
||||
solana-client = {version = "1.8.2", optional = true}
|
||||
solana-sdk = {version = "1.8.2", optional = true}
|
||||
spl-associated-token-account = {version = "1.0.3", features = ["no-entrypoint"], optional = true}
|
||||
spl-token = {version = "3.2.0", features = ["no-entrypoint"], optional = true}
|
||||
|
||||
[features]
|
||||
btc = ["bdk", "bitcoin", "secp256k1"]
|
||||
eth = ["keccak-hasher", "hash-db"]
|
||||
sol = ["solana-sdk", "solana-client", "spl-token", "spl-associated-token-account"]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use futures::prelude::*;
|
||||
|
||||
use crate::endian;
|
||||
use crate::error::{Error, Result};
|
||||
use crate::serial::VarInt;
|
||||
use crate::{Error, Result};
|
||||
|
||||
impl VarInt {
|
||||
pub async fn encode_async<W: AsyncWrite + Unpin>(&self, stream: &mut W) -> Result<usize> {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use async_std::sync::Arc;
|
||||
use std::marker::PhantomData;
|
||||
use std::path::Path;
|
||||
|
||||
use async_std::sync::Arc;
|
||||
use rocksdb::{ColumnFamily, ColumnFamilyDescriptor, Options, DB};
|
||||
|
||||
use crate::serial::{deserialize, serialize, Decodable, Encodable};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/*
|
||||
use async_executor::Executor;
|
||||
use async_std::sync::{Arc, Mutex};
|
||||
|
||||
@@ -24,6 +25,7 @@ use crate::{
|
||||
wallet::{walletdb::Balances, CashierDbPtr, Keypair, WalletPtr},
|
||||
Result,
|
||||
};
|
||||
*/
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ClientFailed {
|
||||
@@ -41,6 +43,7 @@ pub enum ClientFailed {
|
||||
VerifyError(String),
|
||||
}
|
||||
|
||||
/*
|
||||
pub struct Client {
|
||||
mint_params: bellman::groth16::Parameters<Bls12>,
|
||||
spend_params: bellman::groth16::Parameters<Bls12>,
|
||||
@@ -525,6 +528,7 @@ impl State {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
impl std::error::Error for ClientFailed {}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::fmt;
|
||||
|
||||
//use crate::client;
|
||||
use crate::client;
|
||||
use crate::state;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
@@ -272,13 +272,11 @@ impl From<state::VerifyFailed> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl From<client::ClientFailed> for Error {
|
||||
fn from(err: client::ClientFailed) -> Error {
|
||||
Error::ClientFailed(err.to_string())
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[cfg(feature = "btc")]
|
||||
impl From<crate::service::BtcFailed> for Error {
|
||||
|
||||
115
src/lib.rs
115
src/lib.rs
@@ -1,127 +1,20 @@
|
||||
pub mod async_serial;
|
||||
pub mod blockchain;
|
||||
// pub mod bls_extensions;
|
||||
pub mod circuit;
|
||||
pub mod cli;
|
||||
// pub mod client;
|
||||
pub mod client;
|
||||
pub mod crypto;
|
||||
pub mod endian;
|
||||
pub mod error;
|
||||
pub mod net;
|
||||
pub mod rpc;
|
||||
pub mod serial;
|
||||
// pub mod service;
|
||||
pub mod service;
|
||||
pub mod state;
|
||||
pub mod system;
|
||||
pub mod tx;
|
||||
pub mod types;
|
||||
// pub mod util;
|
||||
// pub mod vm;
|
||||
// pub mod vm_serial;
|
||||
// pub mod wallet;
|
||||
pub mod util;
|
||||
pub mod wallet;
|
||||
|
||||
pub use crate::error::{Error, Result};
|
||||
/*
|
||||
pub use crate::bls_extensions::BlsStringConversion;
|
||||
pub use crate::net::p2p::P2p;
|
||||
pub use crate::serial::{Decodable, Encodable};
|
||||
pub use crate::vm::{
|
||||
AllocType, ConstraintInstruction, CryptoOperation, VariableIndex, VariableRef,
|
||||
ZkVirtualMachine, ZkVmCircuit,
|
||||
};
|
||||
|
||||
pub type Bytes = Vec<u8>;
|
||||
|
||||
pub struct ZkContract {
|
||||
pub name: String,
|
||||
pub vm: ZkVirtualMachine,
|
||||
params_map: HashMap<String, VariableIndex>,
|
||||
pub params: HashMap<VariableIndex, Scalar>,
|
||||
public_map: bimap::BiMap<String, VariableIndex>,
|
||||
}
|
||||
|
||||
pub struct ZkProof {
|
||||
pub public: HashMap<String, Scalar>,
|
||||
pub proof: groth16::Proof<Bls12>,
|
||||
}
|
||||
|
||||
impl ZkContract {
|
||||
// Just have a load() and save()
|
||||
// Load the contract, do the setup, save it...
|
||||
|
||||
pub fn setup(&mut self, filename: &str) -> Result<()> {
|
||||
self.vm.setup()?;
|
||||
|
||||
let buffer = std::fs::File::create(filename)?;
|
||||
self.vm.params.as_ref().unwrap().write(buffer)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn load_setup(&mut self, filename: &str) -> Result<()> {
|
||||
let buffer = std::fs::File::open(filename)?;
|
||||
let setup = groth16::Parameters::<Bls12>::read(buffer, false)?;
|
||||
let vk = groth16::prepare_verifying_key(&setup.vk);
|
||||
self.vm.params = Some(setup);
|
||||
self.vm.verifying_key = Some(vk);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn param_names(&self) -> Vec<String> {
|
||||
self.params_map.keys().cloned().collect()
|
||||
}
|
||||
pub fn set_param(&mut self, name: &str, value: Scalar) -> Result<()> {
|
||||
match self.params_map.get(name) {
|
||||
Some(index) => {
|
||||
self.params.insert(*index, value);
|
||||
Ok(())
|
||||
}
|
||||
None => Err(Error::InvalidParamName),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prove(&mut self) -> Result<ZkProof> {
|
||||
// Error if params not all set
|
||||
let user_params: HashSet<_> = self.params.keys().collect();
|
||||
let req_params: HashSet<_> = self.params_map.values().collect();
|
||||
if user_params != req_params {
|
||||
return Err(Error::MissingParams);
|
||||
}
|
||||
|
||||
// execute
|
||||
let params = std::mem::take(&mut self.params);
|
||||
self.vm.initialize(¶ms.into_iter().collect())?;
|
||||
|
||||
// prove
|
||||
let proof = self.vm.prove();
|
||||
|
||||
let mut public = HashMap::new();
|
||||
for (index, value) in self.vm.public() {
|
||||
match self.public_map.get_by_right(&index) {
|
||||
Some(name) => {
|
||||
public.insert(name.clone(), value);
|
||||
}
|
||||
None => return Err(Error::BadContract),
|
||||
}
|
||||
}
|
||||
|
||||
// return proof and public values (Hashmap string -> scalars)
|
||||
Ok(ZkProof { public, proof })
|
||||
}
|
||||
pub fn verify(&self, proof: &ZkProof) -> bool {
|
||||
let mut public = vec![];
|
||||
for (name, value) in &proof.public {
|
||||
match self.public_map.get_by_left(name) {
|
||||
Some(index) => {
|
||||
public.push((index, *value));
|
||||
}
|
||||
None => return false,
|
||||
}
|
||||
}
|
||||
public.sort_by(|a, b| a.0.partial_cmp(b.0).unwrap());
|
||||
let (_, public): (Vec<VariableIndex>, Vec<Scalar>) = public.into_iter().unzip();
|
||||
|
||||
// Takes proof and public values
|
||||
self.vm.verify(&proof.proof, &public)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
use group::GroupEncoding;
|
||||
use sha2::Digest;
|
||||
|
||||
use crate::{
|
||||
serial::{Decodable, Encodable},
|
||||
Result,
|
||||
};
|
||||
use crate::types::*;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Address {
|
||||
pub raw: jubjub::SubgroupPoint,
|
||||
pub raw: DrkPublicKey,
|
||||
pub pkh: String,
|
||||
}
|
||||
|
||||
impl Address {
|
||||
pub fn new(raw: jubjub::SubgroupPoint) -> Self {
|
||||
pub fn new(raw: DrkPublicKey) -> Self {
|
||||
let pkh = Self::pkh_address(&raw);
|
||||
|
||||
Address { raw, pkh }
|
||||
}
|
||||
|
||||
fn get_hash(raw: &jubjub::SubgroupPoint) -> Vec<u8> {
|
||||
fn get_hash(raw: &DrkPublicKey) -> Vec<u8> {
|
||||
// sha256
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
hasher.update(raw.to_bytes());
|
||||
@@ -33,7 +30,7 @@ impl Address {
|
||||
hash.to_vec()
|
||||
}
|
||||
|
||||
pub fn pkh_address(raw: &jubjub::SubgroupPoint) -> String {
|
||||
pub fn pkh_address(raw: &DrkPublicKey) -> String {
|
||||
let mut hash = Self::get_hash(raw);
|
||||
|
||||
let mut payload = vec![];
|
||||
@@ -63,4 +60,3 @@ impl std::fmt::Display for Address {
|
||||
write!(f, "{}", self.pkh)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,20 +6,21 @@ use sha2::{Digest, Sha256};
|
||||
|
||||
use crate::{
|
||||
serial::{deserialize, serialize},
|
||||
types::*,
|
||||
util::{NetworkName, TokenList},
|
||||
Error, Result,
|
||||
};
|
||||
|
||||
// hash the external token ID and NetworkName param.
|
||||
// if fails, change the last 4 bytes and hash it again. keep repeating until it works.
|
||||
pub fn generate_id(tkn_str: &str, network: &NetworkName) -> Result<jubjub::Fr> {
|
||||
pub fn generate_id(tkn_str: &str, network: &NetworkName) -> Result<DrkTokenId> {
|
||||
let mut id_string = network.to_string();
|
||||
|
||||
id_string.push_str(tkn_str);
|
||||
|
||||
let mut data: Vec<u8> = serialize(&id_string);
|
||||
|
||||
let token_id = match deserialize::<jubjub::Fr>(&data) {
|
||||
let token_id = match deserialize::<DrkTokenId>(&data) {
|
||||
Ok(v) => v,
|
||||
Err(_) => {
|
||||
let mut counter = 0;
|
||||
@@ -30,7 +31,7 @@ pub fn generate_id(tkn_str: &str, network: &NetworkName) -> Result<jubjub::Fr> {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(&data);
|
||||
let hash = hasher.finalize();
|
||||
let token_id = deserialize::<jubjub::Fr>(&hash);
|
||||
let token_id = deserialize::<DrkTokenId>(&hash);
|
||||
if token_id.is_err() {
|
||||
counter += 1;
|
||||
continue;
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::collections::HashMap;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::{
|
||||
types::*,
|
||||
util::{generate_id, NetworkName},
|
||||
Error, Result,
|
||||
};
|
||||
@@ -57,14 +58,14 @@ impl TokenList {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DrkTokenList {
|
||||
pub tokens: HashMap<String, jubjub::Fr>,
|
||||
pub tokens: HashMap<String, DrkTokenId>,
|
||||
}
|
||||
|
||||
impl DrkTokenList {
|
||||
pub fn new(sol_list: TokenList) -> Result<Self> {
|
||||
let sol_symbols = sol_list.get_symbols()?;
|
||||
|
||||
let mut tokens: HashMap<String, jubjub::Fr> = sol_symbols
|
||||
let mut tokens: HashMap<String, DrkTokenId> = sol_symbols
|
||||
.iter()
|
||||
.filter_map(|symbol| Self::generate_hash_pair(&sol_list, symbol).ok())
|
||||
.collect();
|
||||
@@ -77,7 +78,7 @@ impl DrkTokenList {
|
||||
Ok(Self { tokens })
|
||||
}
|
||||
|
||||
fn generate_hash_pair(sol_list: &TokenList, symbol: &str) -> Result<(String, jubjub::Fr)> {
|
||||
fn generate_hash_pair(sol_list: &TokenList, symbol: &str) -> Result<(String, DrkTokenId)> {
|
||||
if let Some(token_id) = &sol_list.search_id(symbol)? {
|
||||
Ok((
|
||||
symbol.to_string(),
|
||||
@@ -88,10 +89,13 @@ impl DrkTokenList {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn symbol_from_id(&self, id: jubjub::Fr) -> Result<Option<String>> {
|
||||
pub fn symbol_from_id(&self, id: DrkTokenId) -> Result<Option<String>> {
|
||||
// TODO:
|
||||
/*
|
||||
if id.to_string() == "0x01300f9bce0f9ba7168dc001a67bcbda3a5bf4bdb4c56ae900fe4698cee9a7bd" {
|
||||
return Ok(Some("BTC".to_string()));
|
||||
}
|
||||
*/
|
||||
|
||||
Ok(self
|
||||
.tokens
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
use async_std::sync::{Arc, Mutex};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use async_std::sync::{Arc, Mutex};
|
||||
use log::debug;
|
||||
use rusqlite::{named_params, params, Connection};
|
||||
|
||||
use super::{Keypair, WalletApi};
|
||||
use crate::client::ClientFailed;
|
||||
use crate::crypto::types::{PublicKey, SecretKey, TokenId};
|
||||
use crate::util::NetworkName;
|
||||
use crate::{Error, Result};
|
||||
use crate::{types::*, Error, Result};
|
||||
|
||||
pub type CashierDbPtr = Arc<CashierDb>;
|
||||
|
||||
@@ -27,14 +26,14 @@ pub struct TokenKey {
|
||||
pub struct WithdrawToken {
|
||||
pub token_public_key: Vec<u8>,
|
||||
pub network: NetworkName,
|
||||
pub token_id: TokenId,
|
||||
pub token_id: DrkTokenId,
|
||||
pub mint_address: String,
|
||||
}
|
||||
|
||||
pub struct DepositToken {
|
||||
pub drk_public_key: PublicKey,
|
||||
pub drk_public_key: DrkPublicKey,
|
||||
pub token_key: TokenKey,
|
||||
pub token_id: TokenId,
|
||||
pub token_id: DrkTokenId,
|
||||
pub mint_address: String,
|
||||
}
|
||||
|
||||
@@ -152,10 +151,10 @@ impl CashierDb {
|
||||
pub fn put_withdraw_keys(
|
||||
&self,
|
||||
token_key_public: &[u8],
|
||||
d_key_public: &PublicKey,
|
||||
d_key_private: &SecretKey,
|
||||
d_key_public: &DrkPublicKey,
|
||||
d_key_private: &DrkSecretKey,
|
||||
network: &NetworkName,
|
||||
token_id: &TokenId,
|
||||
token_id: &DrkTokenId,
|
||||
mint_address: String,
|
||||
) -> Result<()> {
|
||||
debug!(target: "CASHIERDB", "Put withdraw keys");
|
||||
@@ -192,11 +191,11 @@ impl CashierDb {
|
||||
|
||||
pub fn put_deposit_keys(
|
||||
&self,
|
||||
d_key_public: &PublicKey,
|
||||
d_key_public: &DrkPublicKey,
|
||||
token_key_private: &[u8],
|
||||
token_key_public: &[u8],
|
||||
network: &NetworkName,
|
||||
token_id: &TokenId,
|
||||
token_id: &DrkTokenId,
|
||||
mint_address: String,
|
||||
) -> Result<()> {
|
||||
debug!(target: "CASHIERDB", "Put exchange keys");
|
||||
@@ -231,7 +230,7 @@ impl CashierDb {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_withdraw_private_keys(&self) -> Result<Vec<SecretKey>> {
|
||||
pub fn get_withdraw_private_keys(&self) -> Result<Vec<DrkSecretKey>> {
|
||||
debug!(target: "CASHIERDB", "Get withdraw private keys");
|
||||
// open connection
|
||||
let conn = Connection::open(&self.path)?;
|
||||
@@ -248,10 +247,10 @@ impl CashierDb {
|
||||
|
||||
let keys = stmt.query_map(&[(":confirm", &confirm)], |row| Ok(row.get(0)))?;
|
||||
|
||||
let mut private_keys: Vec<SecretKey> = vec![];
|
||||
let mut private_keys: Vec<DrkSecretKey> = vec![];
|
||||
|
||||
for k in keys {
|
||||
let private_key: SecretKey = self.get_value_deserialized(k??)?;
|
||||
let private_key: DrkSecretKey = self.get_value_deserialized(k??)?;
|
||||
private_keys.push(private_key);
|
||||
}
|
||||
|
||||
@@ -260,7 +259,7 @@ impl CashierDb {
|
||||
|
||||
pub fn get_withdraw_token_public_key_by_dkey_public(
|
||||
&self,
|
||||
pub_key: &PublicKey,
|
||||
pub_key: &DrkPublicKey,
|
||||
) -> Result<Option<WithdrawToken>> {
|
||||
debug!(target: "CASHIERDB", "Get token address by pub_key");
|
||||
// open connection
|
||||
@@ -288,7 +287,7 @@ impl CashierDb {
|
||||
let addr = addr?;
|
||||
let token_public_key = addr.0;
|
||||
let network: NetworkName = self.get_value_deserialized(addr.1)?;
|
||||
let token_id: TokenId = self.get_value_deserialized(addr.2)?;
|
||||
let token_id: DrkTokenId = self.get_value_deserialized(addr.2)?;
|
||||
let mint_address: String = self.get_value_deserialized(addr.3)?;
|
||||
token_addresses.push(WithdrawToken {
|
||||
token_public_key,
|
||||
@@ -303,7 +302,7 @@ impl CashierDb {
|
||||
|
||||
pub fn get_deposit_token_keys_by_dkey_public(
|
||||
&self,
|
||||
d_key_public: &PublicKey,
|
||||
d_key_public: &DrkPublicKey,
|
||||
network: &NetworkName,
|
||||
) -> Result<Vec<TokenKey>> {
|
||||
debug!(target: "CASHIERDB", "Check for existing dkey");
|
||||
@@ -379,10 +378,10 @@ impl CashierDb {
|
||||
|
||||
for key in keys_iter {
|
||||
let key = key?;
|
||||
let drk_public_key: PublicKey = self.get_value_deserialized(key.0)?;
|
||||
let drk_public_key: DrkPublicKey = self.get_value_deserialized(key.0)?;
|
||||
let private_key = key.1;
|
||||
let public_key = key.2;
|
||||
let token_id: TokenId = self.get_value_deserialized(key.3)?;
|
||||
let token_id: DrkTokenId = self.get_value_deserialized(key.3)?;
|
||||
let mint_address: String = self.get_value_deserialized(key.4)?;
|
||||
keys.push(DepositToken {
|
||||
drk_public_key,
|
||||
@@ -433,8 +432,8 @@ impl CashierDb {
|
||||
|
||||
for kp in keypair_iter {
|
||||
let kp = kp?;
|
||||
let public: PublicKey = self.get_value_deserialized(kp.1)?;
|
||||
let private: SecretKey = self.get_value_deserialized(kp.0)?;
|
||||
let public: DrkPublicKey = self.get_value_deserialized(kp.1)?;
|
||||
let private: DrkSecretKey = self.get_value_deserialized(kp.0)?;
|
||||
let keypair = Keypair { public, private };
|
||||
keypairs.push(keypair);
|
||||
}
|
||||
@@ -470,7 +469,7 @@ impl CashierDb {
|
||||
|
||||
pub fn confirm_deposit_key_record(
|
||||
&self,
|
||||
d_key_public: &PublicKey,
|
||||
d_key_public: &DrkPublicKey,
|
||||
network: &NetworkName,
|
||||
) -> Result<()> {
|
||||
debug!(target: "CASHIERDB", "Confirm withdraw keys");
|
||||
@@ -567,9 +566,9 @@ mod tests {
|
||||
|
||||
let network = NetworkName::Bitcoin;
|
||||
|
||||
let secret2 = SecretKey::random(&mut OsRng);
|
||||
let secret2 = DrkSecretKey::random(&mut OsRng);
|
||||
let public2 = derive_publickey(secret2);
|
||||
let token_id = TokenId::random(&mut OsRng);
|
||||
let token_id = DrkTokenId::random(&mut OsRng);
|
||||
|
||||
wallet.put_deposit_keys(
|
||||
&public2,
|
||||
@@ -612,9 +611,9 @@ mod tests {
|
||||
let wallet = CashierDb::new(&walletdb_path, password.clone())?;
|
||||
init_db(&walletdb_path, password)?;
|
||||
|
||||
let secret2: SecretKey = SecretKey::random(&mut OsRng);
|
||||
let secret2 = DrkSecretKey::random(&mut OsRng);
|
||||
let public2 = derive_publickey(secret2);
|
||||
let token_id: TokenId = TokenId::random(&mut OsRng);
|
||||
let token_id = DrkTokenId::random(&mut OsRng);
|
||||
|
||||
// btc addr testnet
|
||||
let token_addr = serialize(&String::from("mxVFsFW5N4mu1HPkxPttorvocvzeZ7KZyk"));
|
||||
|
||||
@@ -1,21 +1,15 @@
|
||||
use std::collections::HashMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_std::sync::Arc;
|
||||
use log::debug;
|
||||
use log::{debug, error};
|
||||
use pasta_curves::arithmetic::Field;
|
||||
use rand::rngs::OsRng;
|
||||
use rusqlite::{named_params, params, Connection};
|
||||
|
||||
use super::WalletApi;
|
||||
use crate::{
|
||||
client::ClientFailed,
|
||||
crypto::{
|
||||
coin::Coin, merkle::IncrementalWitness, merkle_node::MerkleNode, note::Note,
|
||||
nullifier::Nullifier, types::*, OwnCoin, OwnCoins,
|
||||
},
|
||||
serial, Error, Result,
|
||||
};
|
||||
use crate::crypto::{coin::Coin, note::Note, nullifier::Nullifier, OwnCoin, OwnCoins};
|
||||
use crate::{client::ClientFailed, serial, types::*, Error, Result};
|
||||
|
||||
pub type WalletPtr = Arc<WalletDb>;
|
||||
|
||||
@@ -50,7 +44,6 @@ impl Balances {
|
||||
}
|
||||
}
|
||||
|
||||
//#[derive(Clone)]
|
||||
pub struct WalletDb {
|
||||
pub path: PathBuf,
|
||||
pub password: String,
|
||||
@@ -74,28 +67,27 @@ impl WalletDb {
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn init_db(&self) -> Result<()> {
|
||||
debug!(target: "WALLETDB", "Initialize...");
|
||||
if !self.password.trim().is_empty() {
|
||||
let contents = include_str!("../../sql/schema.sql");
|
||||
let conn = Connection::open(&self.path)?;
|
||||
debug!(target: "WALLETDB", "OPENED CONNECTION AT PATH {:?}", self.path);
|
||||
conn.pragma_update(None, "key", &self.password)?;
|
||||
conn.execute_batch(contents)?;
|
||||
} else {
|
||||
debug!(
|
||||
target: "WALLETDB",
|
||||
"Password is empty. You must set a password to use the wallet."
|
||||
);
|
||||
fn connect(&self) -> Result<Connection> {
|
||||
if self.password.trim().is_empty() {
|
||||
error!(target: "WALLETDB", "Password is empty. You must set a password to use the wallet.");
|
||||
return Err(Error::from(ClientFailed::EmptyPassword));
|
||||
}
|
||||
Ok(())
|
||||
let conn = Connection::open(&self.path)?;
|
||||
debug!(target: "WALLETDB", "OPENED CONNECTION AT PATH {:?}", self.path);
|
||||
conn.pragma_update(None, "key", &self.password)?;
|
||||
Ok(conn)
|
||||
}
|
||||
|
||||
pub fn init_db(&self) -> Result<()> {
|
||||
debug!(target: "WALLETDB", "Initialize...");
|
||||
let contents = include_str!("../../sql/schema.sql");
|
||||
let conn = self.connect()?;
|
||||
Ok(conn.execute_batch(contents)?)
|
||||
}
|
||||
|
||||
pub fn key_gen(&self) -> Result<()> {
|
||||
debug!(target: "WALLETDB", "Attempting to generate keys...");
|
||||
let conn = Connection::open(&self.path)?;
|
||||
conn.pragma_update(None, "key", &self.password)?;
|
||||
let conn = self.connect()?;
|
||||
let mut stmt = conn.prepare("SELECT * FROM keys WHERE key_id > ?")?;
|
||||
let key_check = stmt.exists(params!["0"])?;
|
||||
if !key_check {
|
||||
@@ -110,10 +102,7 @@ impl WalletDb {
|
||||
}
|
||||
|
||||
pub fn put_keypair(&self, key_public: &DrkPublicKey, key_private: &DrkSecretKey) -> Result<()> {
|
||||
let conn = Connection::open(&self.path)?;
|
||||
|
||||
conn.pragma_update(None, "key", &self.password)?;
|
||||
|
||||
let conn = self.connect()?;
|
||||
let key_public = serial::serialize(key_public);
|
||||
let key_private = serial::serialize(key_private);
|
||||
|
||||
@@ -121,13 +110,13 @@ impl WalletDb {
|
||||
"INSERT INTO keys(key_public, key_private) VALUES (?1, ?2)",
|
||||
params![key_public, key_private],
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_keypairs(&self) -> Result<Vec<Keypair>> {
|
||||
debug!(target: "WALLETDB", "Returning keypairs...");
|
||||
let conn = Connection::open(&self.path)?;
|
||||
conn.pragma_update(None, "key", &self.password)?;
|
||||
let conn = self.connect()?;
|
||||
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| Ok((row.get(1)?, row.get(2)?)))?;
|
||||
@@ -147,13 +136,8 @@ impl WalletDb {
|
||||
|
||||
pub fn get_own_coins(&self) -> Result<OwnCoins> {
|
||||
debug!(target: "WALLETDB", "Get own coins");
|
||||
|
||||
let conn = self.connect()?;
|
||||
let is_spent = 0;
|
||||
|
||||
let conn = Connection::open(&self.path)?;
|
||||
// unlock database
|
||||
conn.pragma_update(None, "key", &self.password)?;
|
||||
|
||||
let mut coins = conn.prepare("SELECT * FROM coins WHERE is_spent = :is_spent ;")?;
|
||||
let rows = coins.query_map(&[(":is_spent", &is_spent)], |row| {
|
||||
Ok((
|
||||
@@ -163,7 +147,7 @@ impl WalletDb {
|
||||
row.get(3)?,
|
||||
row.get(4)?,
|
||||
row.get(5)?,
|
||||
row.get(6)?,
|
||||
// TODO: row.get(6)?,
|
||||
row.get(7)?,
|
||||
row.get(9)?,
|
||||
))
|
||||
@@ -178,7 +162,7 @@ impl WalletDb {
|
||||
// note
|
||||
let serial = self.get_value_deserialized(row.1)?;
|
||||
let coin_blind = self.get_value_deserialized(row.2)?;
|
||||
let valcom_blind = self.get_value_deserialized(row.3)?;
|
||||
let value_blind = self.get_value_deserialized(row.3)?;
|
||||
let value: u64 = row.4;
|
||||
let token_id = self.get_value_deserialized(row.5)?;
|
||||
|
||||
@@ -187,18 +171,21 @@ impl WalletDb {
|
||||
value,
|
||||
token_id,
|
||||
coin_blind,
|
||||
valcom_blind,
|
||||
value_blind,
|
||||
};
|
||||
|
||||
let witness = self.get_value_deserialized(row.6)?;
|
||||
let secret: DrkSecretKey = self.get_value_deserialized(row.7)?;
|
||||
let nullifier: Nullifier = self.get_value_deserialized(row.8)?;
|
||||
// TODO:
|
||||
// let witness = self.get_value_deserialized(row.6)?;
|
||||
// let secret: DrkSecretKey = self.get_value_deserialized(row.7)?;
|
||||
// let nullifier: Nullifier = self.get_value_deserialized(row.8)?;
|
||||
let secret: DrkSecretKey = self.get_value_deserialized(row.6)?;
|
||||
let nullifier: Nullifier = self.get_value_deserialized(row.7)?;
|
||||
|
||||
let oc = OwnCoin {
|
||||
coin,
|
||||
note,
|
||||
secret,
|
||||
witness,
|
||||
// TODO: witness,
|
||||
nullifier,
|
||||
};
|
||||
|
||||
@@ -210,20 +197,16 @@ impl WalletDb {
|
||||
|
||||
pub fn put_own_coins(&self, own_coin: OwnCoin) -> Result<()> {
|
||||
debug!(target: "WALLETDB", "Put own coins");
|
||||
let conn = self.connect()?;
|
||||
|
||||
// open connection
|
||||
let conn = Connection::open(&self.path)?;
|
||||
// unlock database
|
||||
conn.pragma_update(None, "key", &self.password)?;
|
||||
|
||||
let coin = self.get_value_serialized(&own_coin.coin.repr)?;
|
||||
let coin = self.get_value_serialized(&own_coin.coin.to_bytes())?;
|
||||
|
||||
let serial = self.get_value_serialized(&own_coin.note.serial)?;
|
||||
let coin_blind = self.get_value_serialized(&own_coin.note.coin_blind)?;
|
||||
let valcom_blind = self.get_value_serialized(&own_coin.note.valcom_blind)?;
|
||||
let value_blind = self.get_value_serialized(&own_coin.note.value_blind)?;
|
||||
let value: u64 = own_coin.note.value;
|
||||
let token_id = self.get_value_serialized(&own_coin.note.token_id)?;
|
||||
let witness = self.get_value_serialized(&own_coin.witness)?;
|
||||
// TODO: let witness = self.get_value_serialized(&own_coin.witness)?;
|
||||
let secret = self.get_value_serialized(&own_coin.secret)?;
|
||||
let is_spent = 0;
|
||||
let nullifier = self.get_value_serialized(&own_coin.nullifier)?;
|
||||
@@ -241,8 +224,8 @@ impl WalletDb {
|
||||
":value": value,
|
||||
":token_id": token_id,
|
||||
":coin_blind": coin_blind,
|
||||
":valcom_blind": valcom_blind,
|
||||
":witness": witness,
|
||||
":valcom_blind": value_blind,
|
||||
// TODO: ":witness": witness,
|
||||
":secret": secret,
|
||||
":is_spent": is_spent,
|
||||
":nullifier": nullifier,
|
||||
@@ -253,28 +236,16 @@ impl WalletDb {
|
||||
|
||||
pub fn remove_own_coins(&self) -> Result<()> {
|
||||
debug!(target: "WALLETDB", "Remove own coins");
|
||||
|
||||
// open connection
|
||||
let conn = Connection::open(&self.path)?;
|
||||
// unlock database
|
||||
conn.pragma_update(None, "key", &self.password)?;
|
||||
|
||||
let conn = self.connect()?;
|
||||
conn.execute("DROP TABLE coins;", [])?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn confirm_spend_coin(&self, coin: &Coin) -> Result<()> {
|
||||
debug!(target: "WALLETDB", "Confirm spend coin");
|
||||
|
||||
let coin = self.get_value_serialized(coin)?;
|
||||
|
||||
// open connection
|
||||
let conn = Connection::open(&self.path)?;
|
||||
// unlock database
|
||||
conn.pragma_update(None, "key", &self.password)?;
|
||||
|
||||
let conn = self.connect()?;
|
||||
let is_spent = 1;
|
||||
|
||||
conn.execute(
|
||||
"UPDATE coins
|
||||
SET is_spent = ?1
|
||||
@@ -285,6 +256,7 @@ impl WalletDb {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/* TODO:
|
||||
pub fn get_witnesses(&self) -> Result<HashMap<Vec<u8>, IncrementalWitness<MerkleNode>>> {
|
||||
let conn = Connection::open(&self.path)?;
|
||||
conn.pragma_update(None, "key", &self.password)?;
|
||||
@@ -330,11 +302,11 @@ impl WalletDb {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn get_balances(&self) -> Result<Balances> {
|
||||
debug!(target: "WALLETDB", "Get token and balances...");
|
||||
let conn = Connection::open(&self.path)?;
|
||||
conn.pragma_update(None, "key", &self.password)?;
|
||||
let conn = self.connect()?;
|
||||
|
||||
let is_spent = 0;
|
||||
|
||||
@@ -364,8 +336,7 @@ impl WalletDb {
|
||||
|
||||
pub fn get_token_id(&self) -> Result<Vec<DrkTokenId>> {
|
||||
debug!(target: "WALLETDB", "Get token ID...");
|
||||
let conn = Connection::open(&self.path)?;
|
||||
conn.pragma_update(None, "key", &self.password)?;
|
||||
let conn = self.connect()?;
|
||||
|
||||
let is_spent = 0;
|
||||
|
||||
@@ -385,8 +356,7 @@ impl WalletDb {
|
||||
|
||||
pub fn token_id_exists(&self, token_id: &DrkTokenId) -> Result<bool> {
|
||||
debug!(target: "WALLETDB", "Check tokenID exists");
|
||||
let conn = Connection::open(&self.path)?;
|
||||
conn.pragma_update(None, "key", &self.password)?;
|
||||
let conn = self.connect()?;
|
||||
|
||||
let id = self.get_value_serialized(token_id)?;
|
||||
let is_spent = 0;
|
||||
|
||||
Reference in New Issue
Block a user