Bladeren bron

walletdb: Implement query for coins by value and token_id.

parazyd 4 jaren geleden
bovenliggende
commit
eb665cc476
2 gewijzigde bestanden met toevoegingen van 70 en 1 verwijderingen
  1. 9 0
      src/node/client.rs
  2. 61 1
      src/wallet/walletdb.rs

+ 9 - 0
src/node/client.rs

@@ -219,6 +219,15 @@ impl Client {
         self.wallet.get_balances().await
         self.wallet.get_balances().await
     }
     }
 
 
+    pub async fn get_coins_valtok(
+        &self,
+        value: u64,
+        token_id: DrkTokenId,
+        unspent: bool,
+    ) -> Result<Vec<OwnCoin>> {
+        self.wallet.get_coins_valtok(value, token_id, unspent).await
+    }
+
     pub async fn get_tree(&self) -> Result<BridgeTree<MerkleNode, MERKLE_DEPTH>> {
     pub async fn get_tree(&self) -> Result<BridgeTree<MerkleNode, MERKLE_DEPTH>> {
         self.wallet.get_tree().await
         self.wallet.get_tree().await
     }
     }

+ 61 - 1
src/wallet/walletdb.rs

@@ -1,6 +1,7 @@
 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, LevelFilter};
 use log::{debug, error, info, LevelFilter};
 use rand::rngs::OsRng;
 use rand::rngs::OsRng;
@@ -283,6 +284,65 @@ impl WalletDb {
         Ok(own_coins)
         Ok(own_coins)
     }
     }
 
 
+    pub async fn get_coins_valtok(
+        &self,
+        value: u64,
+        token_id: DrkTokenId,
+        unspent: bool,
+    ) -> Result<Vec<OwnCoin>> {
+        debug!(
+            "Querying for coins with value {} and token_id {}",
+            value,
+            bs58::encode(token_id.to_repr()).into_string()
+        );
+
+        let mut conn = self.conn.acquire().await?;
+        let rows = match unspent {
+            true => {
+                sqlx::query(
+                    "SELECT * FROM coins WHERE is_spent = ?1 AND value = ?2 AND token_id = ?3;",
+                )
+                .bind(0)
+                .bind(serialize(&value))
+                .bind(serialize(&token_id))
+                .fetch_all(&mut conn)
+                .await?
+            }
+            false => {
+                sqlx::query("SELECT * FROM coins WHERE value = ?1 AND token_id = ?2;")
+                    .bind(serialize(&value))
+                    .bind(serialize(&token_id))
+                    .fetch_all(&mut conn)
+                    .await?
+            }
+        };
+
+        let mut coins = vec![];
+
+        for row in rows {
+            let coin = deserialize(row.get("coin"))?;
+
+            // Note
+            let serial = deserialize(row.get("serial"))?;
+            let coin_blind = deserialize(row.get("coin_blind"))?;
+            let value_blind = deserialize(row.get("valcom_blind"))?;
+            let value = deserialize(row.get("value"))?;
+            let token_id = deserialize(row.get("token_id"))?;
+            let token_blind = deserialize(row.get("token_blind"))?;
+            let note = Note { serial, value, token_id, coin_blind, value_blind, token_blind };
+
+            let secret = deserialize(row.get("secret"))?;
+            let nullifier = deserialize(row.get("nullifier"))?;
+            let leaf_position = deserialize(row.get("leaf_position"))?;
+
+            let oc = OwnCoin { coin, note, secret, nullifier, leaf_position };
+
+            coins.push(oc);
+        }
+
+        Ok(coins)
+    }
+
     pub async fn put_own_coin(&self, own_coin: OwnCoin) -> 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");
 
 
@@ -312,7 +372,7 @@ impl WalletDb {
         .bind(value_blind)
         .bind(value_blind)
         .bind(token_blind)
         .bind(token_blind)
         .bind(value)
         .bind(value)
-        .bind(token_id) // token_id
+        .bind(token_id)
         .bind(secret)
         .bind(secret)
         .bind(is_spent)
         .bind(is_spent)
         .bind(nullifier)
         .bind(nullifier)