|
@@ -1,9 +1,8 @@
|
|
|
use std::{fs::create_dir_all, path::Path, str::FromStr, time::Duration};
|
|
use std::{fs::create_dir_all, path::Path, str::FromStr, time::Duration};
|
|
|
|
|
|
|
|
use async_std::sync::Arc;
|
|
use async_std::sync::Arc;
|
|
|
-use group::ff::PrimeField;
|
|
|
|
|
use incrementalmerkletree::bridgetree::BridgeTree;
|
|
use incrementalmerkletree::bridgetree::BridgeTree;
|
|
|
-use log::{debug, error, info, warn, LevelFilter};
|
|
|
|
|
|
|
+use log::{debug, error, info, LevelFilter};
|
|
|
use rand::rngs::OsRng;
|
|
use rand::rngs::OsRng;
|
|
|
use sqlx::{
|
|
use sqlx::{
|
|
|
sqlite::{SqliteConnectOptions, SqliteJournalMode},
|
|
sqlite::{SqliteConnectOptions, SqliteJournalMode},
|
|
@@ -19,14 +18,12 @@ use crate::{
|
|
|
merkle_node::MerkleNode,
|
|
merkle_node::MerkleNode,
|
|
|
note::Note,
|
|
note::Note,
|
|
|
nullifier::Nullifier,
|
|
nullifier::Nullifier,
|
|
|
- token_list::DrkTokenList,
|
|
|
|
|
types::DrkTokenId,
|
|
types::DrkTokenId,
|
|
|
OwnCoin, OwnCoins,
|
|
OwnCoin, OwnCoins,
|
|
|
},
|
|
},
|
|
|
util::{
|
|
util::{
|
|
|
expand_path,
|
|
expand_path,
|
|
|
serial::{deserialize, serialize},
|
|
serial::{deserialize, serialize},
|
|
|
- NetworkName,
|
|
|
|
|
},
|
|
},
|
|
|
Error::{WalletEmptyPassword, WalletTreeExists},
|
|
Error::{WalletEmptyPassword, WalletTreeExists},
|
|
|
Result,
|
|
Result,
|
|
@@ -270,7 +267,7 @@ impl WalletDb {
|
|
|
let coin_blind = deserialize(row.get("coin_blind"))?;
|
|
let coin_blind = deserialize(row.get("coin_blind"))?;
|
|
|
let value_blind = deserialize(row.get("valcom_blind"))?;
|
|
let value_blind = deserialize(row.get("valcom_blind"))?;
|
|
|
let value = deserialize(row.get("value"))?;
|
|
let value = deserialize(row.get("value"))?;
|
|
|
- let token_id = deserialize(row.get("drk_address"))?;
|
|
|
|
|
|
|
+ let token_id = deserialize(row.get("token_id"))?;
|
|
|
let token_blind = deserialize(row.get("token_blind"))?;
|
|
let token_blind = deserialize(row.get("token_blind"))?;
|
|
|
let note = Note { serial, value, token_id, coin_blind, value_blind, token_blind };
|
|
let note = Note { serial, value, token_id, coin_blind, value_blind, token_blind };
|
|
|
|
|
|
|
@@ -286,11 +283,7 @@ impl WalletDb {
|
|
|
Ok(own_coins)
|
|
Ok(own_coins)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- pub async fn put_own_coin(
|
|
|
|
|
- &self,
|
|
|
|
|
- own_coin: OwnCoin,
|
|
|
|
|
- tokenlist: Arc<DrkTokenList>,
|
|
|
|
|
- ) -> Result<()> {
|
|
|
|
|
|
|
+ pub async fn put_own_coin(&self, own_coin: OwnCoin) -> Result<()> {
|
|
|
debug!("Putting own coin into wallet database");
|
|
debug!("Putting own coin into wallet database");
|
|
|
|
|
|
|
|
let coin = serialize(&own_coin.coin.to_bytes());
|
|
let coin = serialize(&own_coin.coin.to_bytes());
|
|
@@ -299,32 +292,19 @@ impl WalletDb {
|
|
|
let value_blind = serialize(&own_coin.note.value_blind);
|
|
let value_blind = serialize(&own_coin.note.value_blind);
|
|
|
let token_blind = serialize(&own_coin.note.token_blind);
|
|
let token_blind = serialize(&own_coin.note.token_blind);
|
|
|
let value = serialize(&own_coin.note.value);
|
|
let value = serialize(&own_coin.note.value);
|
|
|
- let drk_address = serialize(&own_coin.note.token_id);
|
|
|
|
|
|
|
+ let token_id = serialize(&own_coin.note.token_id);
|
|
|
let secret = serialize(&own_coin.secret);
|
|
let secret = serialize(&own_coin.secret);
|
|
|
let nullifier = serialize(&own_coin.nullifier);
|
|
let nullifier = serialize(&own_coin.nullifier);
|
|
|
let leaf_position = serialize(&own_coin.leaf_position);
|
|
let leaf_position = serialize(&own_coin.leaf_position);
|
|
|
let is_spent: u8 = 0;
|
|
let is_spent: u8 = 0;
|
|
|
|
|
|
|
|
- let token_id_enc = bs58::encode(&own_coin.note.token_id.to_repr()).into_string();
|
|
|
|
|
-
|
|
|
|
|
- let (network, net_address) =
|
|
|
|
|
- if let Some((network, token_info)) = tokenlist.by_addr.get(&token_id_enc) {
|
|
|
|
|
- (network, token_info.net_address.clone())
|
|
|
|
|
- } else {
|
|
|
|
|
- warn!("Could not find network and token info in parsed token list");
|
|
|
|
|
- (&NetworkName::DarkFi, "unknown".to_string())
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- let network = serialize(network);
|
|
|
|
|
-
|
|
|
|
|
let mut conn = self.conn.acquire().await?;
|
|
let mut conn = self.conn.acquire().await?;
|
|
|
sqlx::query(
|
|
sqlx::query(
|
|
|
"INSERT OR REPLACE INTO coins
|
|
"INSERT OR REPLACE INTO coins
|
|
|
(coin, serial, coin_blind, valcom_blind, token_blind, value,
|
|
(coin, serial, coin_blind, valcom_blind, token_blind, value,
|
|
|
- network, drk_address, net_address,
|
|
|
|
|
- secret, is_spent, nullifier, leaf_position)
|
|
|
|
|
|
|
+ token_id, secret, is_spent, nullifier, leaf_position)
|
|
|
VALUES
|
|
VALUES
|
|
|
- (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13);",
|
|
|
|
|
|
|
+ (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11);",
|
|
|
)
|
|
)
|
|
|
.bind(coin)
|
|
.bind(coin)
|
|
|
.bind(serial)
|
|
.bind(serial)
|
|
@@ -332,9 +312,7 @@ impl WalletDb {
|
|
|
.bind(value_blind)
|
|
.bind(value_blind)
|
|
|
.bind(token_blind)
|
|
.bind(token_blind)
|
|
|
.bind(value)
|
|
.bind(value)
|
|
|
- .bind(network)
|
|
|
|
|
- .bind(drk_address) // token_id
|
|
|
|
|
- .bind(net_address)
|
|
|
|
|
|
|
+ .bind(token_id) // token_id
|
|
|
.bind(secret)
|
|
.bind(secret)
|
|
|
.bind(is_spent)
|
|
.bind(is_spent)
|
|
|
.bind(nullifier)
|
|
.bind(nullifier)
|
|
@@ -372,18 +350,17 @@ impl WalletDb {
|
|
|
let is_spent = 0;
|
|
let is_spent = 0;
|
|
|
|
|
|
|
|
let mut conn = self.conn.acquire().await?;
|
|
let mut conn = self.conn.acquire().await?;
|
|
|
- let rows =
|
|
|
|
|
- sqlx::query("SELECT value, drk_address, nullifier FROM coins WHERE is_spent = ?1;")
|
|
|
|
|
- .bind(is_spent)
|
|
|
|
|
- .fetch_all(&mut conn)
|
|
|
|
|
- .await?;
|
|
|
|
|
|
|
+ let rows = sqlx::query("SELECT value, token_id, nullifier FROM coins WHERE is_spent = ?1;")
|
|
|
|
|
+ .bind(is_spent)
|
|
|
|
|
+ .fetch_all(&mut conn)
|
|
|
|
|
+ .await?;
|
|
|
|
|
|
|
|
debug!("Found {} rows", rows.len());
|
|
debug!("Found {} rows", rows.len());
|
|
|
|
|
|
|
|
let mut list = vec![];
|
|
let mut list = vec![];
|
|
|
for row in rows {
|
|
for row in rows {
|
|
|
let value = deserialize(row.get("value"))?;
|
|
let value = deserialize(row.get("value"))?;
|
|
|
- let token_id = deserialize(row.get("drk_address"))?;
|
|
|
|
|
|
|
+ let token_id = deserialize(row.get("token_id"))?;
|
|
|
let nullifier = deserialize(row.get("nullifier"))?;
|
|
let nullifier = deserialize(row.get("nullifier"))?;
|
|
|
list.push(Balance { token_id, value, nullifier });
|
|
list.push(Balance { token_id, value, nullifier });
|
|
|
}
|
|
}
|
|
@@ -396,14 +373,14 @@ impl WalletDb {
|
|
|
let is_spent = 0;
|
|
let is_spent = 0;
|
|
|
|
|
|
|
|
let mut conn = self.conn.acquire().await?;
|
|
let mut conn = self.conn.acquire().await?;
|
|
|
- let rows = sqlx::query("SELECT drk_address FROM coins WHERE is_spent = ?1;")
|
|
|
|
|
|
|
+ let rows = sqlx::query("SELECT token_id FROM coins WHERE is_spent = ?1;")
|
|
|
.bind(is_spent)
|
|
.bind(is_spent)
|
|
|
.fetch_all(&mut conn)
|
|
.fetch_all(&mut conn)
|
|
|
.await?;
|
|
.await?;
|
|
|
|
|
|
|
|
let mut token_ids = vec![];
|
|
let mut token_ids = vec![];
|
|
|
for row in rows {
|
|
for row in rows {
|
|
|
- let token_id = deserialize(row.get("drk_address"))?;
|
|
|
|
|
|
|
+ let token_id = deserialize(row.get("token_id"))?;
|
|
|
token_ids.push(token_id);
|
|
token_ids.push(token_id);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -418,7 +395,7 @@ impl WalletDb {
|
|
|
|
|
|
|
|
let mut conn = self.conn.acquire().await?;
|
|
let mut conn = self.conn.acquire().await?;
|
|
|
|
|
|
|
|
- let id_check = sqlx::query("SELECT * FROM coins WHERE drk_address = ?1 AND is_spent = ?2;")
|
|
|
|
|
|
|
+ let id_check = sqlx::query("SELECT * FROM coins WHERE token_id = ?1 AND is_spent = ?2;")
|
|
|
.bind(id)
|
|
.bind(id)
|
|
|
.bind(is_spent)
|
|
.bind(is_spent)
|
|
|
.fetch_optional(&mut conn)
|
|
.fetch_optional(&mut conn)
|
|
@@ -472,13 +449,6 @@ mod tests {
|
|
|
let wallet = WalletDb::new("sqlite::memory:", WPASS).await?;
|
|
let wallet = WalletDb::new("sqlite::memory:", WPASS).await?;
|
|
|
let keypair = Keypair::random(&mut OsRng);
|
|
let keypair = Keypair::random(&mut OsRng);
|
|
|
|
|
|
|
|
- let tokenlist = Arc::new(DrkTokenList::new(&[
|
|
|
|
|
- ("drk", include_bytes!("../../contrib/token/darkfi_token_list.min.json")),
|
|
|
|
|
- ("btc", include_bytes!("../../contrib/token/bitcoin_token_list.min.json")),
|
|
|
|
|
- ("eth", include_bytes!("../../contrib/token/erc20_token_list.min.json")),
|
|
|
|
|
- ("sol", include_bytes!("../../contrib/token/solana_token_list.min.json")),
|
|
|
|
|
- ])?);
|
|
|
|
|
-
|
|
|
|
|
// init_db()
|
|
// init_db()
|
|
|
wallet.init_db().await?;
|
|
wallet.init_db().await?;
|
|
|
|
|
|
|
@@ -496,19 +466,19 @@ mod tests {
|
|
|
let c3 = dummy_coin(&keypair.secret, 11, &token_id);
|
|
let c3 = dummy_coin(&keypair.secret, 11, &token_id);
|
|
|
|
|
|
|
|
// put_own_coin()
|
|
// put_own_coin()
|
|
|
- wallet.put_own_coin(c0, tokenlist.clone()).await?;
|
|
|
|
|
|
|
+ wallet.put_own_coin(c0).await?;
|
|
|
tree1.append(&MerkleNode::from_coin(&c0.coin));
|
|
tree1.append(&MerkleNode::from_coin(&c0.coin));
|
|
|
tree1.witness();
|
|
tree1.witness();
|
|
|
|
|
|
|
|
- wallet.put_own_coin(c1, tokenlist.clone()).await?;
|
|
|
|
|
|
|
+ wallet.put_own_coin(c1).await?;
|
|
|
tree1.append(&MerkleNode::from_coin(&c1.coin));
|
|
tree1.append(&MerkleNode::from_coin(&c1.coin));
|
|
|
tree1.witness();
|
|
tree1.witness();
|
|
|
|
|
|
|
|
- wallet.put_own_coin(c2, tokenlist.clone()).await?;
|
|
|
|
|
|
|
+ wallet.put_own_coin(c2).await?;
|
|
|
tree1.append(&MerkleNode::from_coin(&c2.coin));
|
|
tree1.append(&MerkleNode::from_coin(&c2.coin));
|
|
|
tree1.witness();
|
|
tree1.witness();
|
|
|
|
|
|
|
|
- wallet.put_own_coin(c3, tokenlist).await?;
|
|
|
|
|
|
|
+ wallet.put_own_coin(c3).await?;
|
|
|
tree1.append(&MerkleNode::from_coin(&c3.coin));
|
|
tree1.append(&MerkleNode::from_coin(&c3.coin));
|
|
|
tree1.witness();
|
|
tree1.witness();
|
|
|
|
|
|