ソースを参照

drk: mark spent coins on block scanning

aggstam 3 年 前
コミット
b1ca9721c8
2 ファイル変更27 行追加0 行削除
  1. 11 0
      bin/drk/src/rpc_blockchain.rs
  2. 16 0
      bin/drk/src/rpc_wallet.rs

+ 11 - 0
bin/drk/src/rpc_blockchain.rs

@@ -132,6 +132,7 @@ impl Drk {
     async fn scan_block(&self, block: &BlockInfo) -> Result<()> {
     async fn scan_block(&self, block: &BlockInfo) -> Result<()> {
         eprintln!("Iterating over {} transactions", block.txs.len());
         eprintln!("Iterating over {} transactions", block.txs.len());
 
 
+        let mut nullifiers: Vec<Nullifier> = vec![];
         let mut outputs: Vec<Output> = vec![];
         let mut outputs: Vec<Output> = vec![];
 
 
         // TODO: FIXME: This shouldn't be hardcoded here obviously.
         // TODO: FIXME: This shouldn't be hardcoded here obviously.
@@ -143,6 +144,9 @@ impl Drk {
                 {
                 {
                     eprintln!("Found Money::Transfer in call {} in tx {}", j, i);
                     eprintln!("Found Money::Transfer in call {} in tx {}", j, i);
                     let params: MoneyTransferParams = deserialize(&call.data[1..])?;
                     let params: MoneyTransferParams = deserialize(&call.data[1..])?;
+                    for input in params.inputs {
+                        nullifiers.push(input.nullifier);
+                    }
                     for output in params.outputs {
                     for output in params.outputs {
                         outputs.push(output);
                         outputs.push(output);
                     }
                     }
@@ -152,6 +156,9 @@ impl Drk {
                 if call.contract_id == contract_id && call.data[0] == MoneyFunction::OtcSwap as u8 {
                 if call.contract_id == contract_id && call.data[0] == MoneyFunction::OtcSwap as u8 {
                     eprintln!("Found Money::OtcSwap in call {} in tx {}", j, i);
                     eprintln!("Found Money::OtcSwap in call {} in tx {}", j, i);
                     let params: MoneyTransferParams = deserialize(&call.data[1..])?;
                     let params: MoneyTransferParams = deserialize(&call.data[1..])?;
+                    for input in params.inputs {
+                        nullifiers.push(input.nullifier);
+                    }
                     for output in params.outputs {
                     for output in params.outputs {
                         outputs.push(output);
                         outputs.push(output);
                     }
                     }
@@ -205,6 +212,10 @@ impl Drk {
         self.put_tree(&tree).await?;
         self.put_tree(&tree).await?;
         eprintln!("Merkle tree written successfully");
         eprintln!("Merkle tree written successfully");
 
 
+        eprintln!("Marking spent coins");
+        self.mark_spent_coins(nullifiers).await?;
+        eprintln!("Spent coins marked successfully");
+
         // This is the SQL query we'll be executing to insert coins into the wallet
         // This is the SQL query we'll be executing to insert coins into the wallet
         let query = format!(
         let query = format!(
             "INSERT INTO {} ({}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12);",
             "INSERT INTO {} ({}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12);",

+ 16 - 0
bin/drk/src/rpc_wallet.rs

@@ -446,6 +446,22 @@ impl Drk {
         Ok(())
         Ok(())
     }
     }
 
 
+    /// Marks all coins in the wallet as spent, if their nullifier is
+    /// in the provided set
+    pub async fn mark_spent_coins(&self, nullifiers: Vec<Nullifier>) -> Result<()> {
+        if nullifiers.is_empty() {
+            return Ok(())
+        }
+
+        for (coin, _) in self.wallet_coins(false).await? {
+            if nullifiers.contains(&coin.nullifier) {
+                self.mark_spent_coin(&coin.coin).await?;
+            }
+        }
+
+        Ok(())
+    }
+
     /// Mark a given coin in the wallet as unspent
     /// Mark a given coin in the wallet as unspent
     pub async fn unspend_coin(&self, coin: &Coin) -> Result<()> {
     pub async fn unspend_coin(&self, coin: &Coin) -> Result<()> {
         let query = format!(
         let query = format!(