wallet: WIP pasta port.

This commit is contained in:
parazyd
2021-11-02 15:20:49 +01:00
parent ee118fb6c1
commit 4b31d0b321
12 changed files with 2911 additions and 361 deletions

2890
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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(&params.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)
}
}
*/

View File

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

View File

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

View File

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

View File

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

View File

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