Browse Source

Remove non-existing tx from script history

Janus 4 years ago
parent
commit
2efe436c0f
1 changed files with 45 additions and 63 deletions
  1. 45 63
      src/service/btc.rs

+ 45 - 63
src/service/btc.rs

@@ -200,13 +200,13 @@ impl Account {
         Script::new_p2pkh(&btc_pubkey_hash)
     }
 }
-fn print_status_change(txid: Txid, old: Option<ScriptStatus>, new: ScriptStatus) -> ScriptStatus {
+fn print_status_change(script: &Script, old: Option<ScriptStatus>, new: ScriptStatus) -> ScriptStatus {
     match (old, new) {
         (None, new_status) => {
-            debug!(target: "BTC BRIDGE", "Found relevant Bitcoin transaction: {:?} {:?}", txid, new_status);
+            debug!(target: "BTC BRIDGE", "Found relevant Bitcoin transaction: {:?} {:?}", script, new_status);
         }
         (Some(old_status), new_status) if old_status != new_status => {
-            debug!(target: "BTC BRIDGE", "Bitcoin transaction status changed: {:?} {} {}", txid, new_status, old_status);
+            debug!(target: "BTC BRIDGE", "Bitcoin transaction status changed: {:?} {} {}", script, new_status, old_status);
         }
         _ => {}
     }
@@ -244,7 +244,7 @@ impl Client {
         let interval = sync_interval(Duration::from_secs(300));
 
         Ok(Self {
-            electrum: electrum,
+            electrum,
             subscriptions: Arc::new(Mutex::new(Vec::new())),
             latest_block_height: BlockHeight::try_from(latest_block)
                 .map_err(|_| crate::Error::TryFromError)?,
@@ -273,10 +273,10 @@ impl Client {
             .map_err(|err| crate::Error::from(super::BtcFailed::from(err)))?;
 
         if latest_block_height > self.latest_block_height {
-            // debug!( target: "BTC BRIDGE", "{} {}"
-            //     u32::from(latest_block_height),
-            //     "Got notification for new block"
-            // );
+            debug!( target: "BTC BRIDGE", "{} {}",
+                u32::from(latest_block_height),
+                "Got notification for new block"
+            );
             self.latest_block_height = latest_block_height;
         }
 
@@ -304,34 +304,18 @@ impl Client {
         Ok(())
     }
 
-    pub fn status_of_script<T>(&mut self, tx: &T) -> BtcResult<ScriptStatus>
-    where
-        T: Watchable,
+    pub fn status_of_script(&mut self, script: Script) -> BtcResult<ScriptStatus>
     {
-        let txid = tx.id();
-        let script = tx.script();
-
-
         if !self.script_history.contains_key(&script) {
             self.script_history.insert(script.clone(), vec![]);
         }
-
         self.update_state()?;
 
-        let history = self.script_history.entry(script).or_default();
+        let history = self.script_history.entry(script.clone()).or_default();
 
-        let history_of_tx = history
-            .iter()
-            .filter(|entry| entry.tx_hash == txid)
-            .collect::<Vec<_>>();
-
-        match history_of_tx.as_slice() {
+        match history.as_slice() {
             [] => Ok(ScriptStatus::Unseen),
             [remaining @ .., last] => {
-                if !remaining.is_empty() {
-                    debug!("Found more than a single history entry for script. This is highly unexpected and those history entries will be ignored")
-                }
-
                 if last.height <= 0 {
                     Ok(ScriptStatus::InMempool)
                 } else {
@@ -383,7 +367,7 @@ impl BtcClient {
 
     async fn handle_subscribe_request(
         self: Arc<Self>,
-        tx: impl Watchable + Send + 'static,
+        //tx: impl Watchable + Send + 'static,
         btc_keys: Account,
         drk_pub_key: jubjub::SubgroupPoint,
     ) -> BtcResult<()> {
@@ -392,29 +376,36 @@ impl BtcClient {
             "Handle subscribe request"
         );
         let client = self.client.clone();
-        let electrum = &client.lock().await.electrum;
-        let script = tx.script();
-        let txid = tx.id();
+        debug!(
+            target: "BTC BRIDGE",
+            "electrum lock"
+        );
+        let keys_clone = btc_keys.clone();
+        let script = keys_clone.script_pubkey;
 
-        // Check if we're already subscribed
+        //Check if we're already subscribed
         if client.lock().await
             .subscriptions.lock().await.contains(&script) {
-            return Ok(());
+                return Ok(());
+            }
+        else {
+            client.lock().await
+                .subscriptions.lock().await.push(script.clone());
         }
-        //Fetch any current balance
-        let prev_balance = electrum.script_get_balance(&script)?;
 
+        debug!(
+            target: "BTC BRIDGE",
+            "subscriptions"
+        );
+
+        //Fetch any current balance
+        let prev_balance = client.lock().await.electrum.script_get_balance(&script)?;
         let cur_balance: GetBalanceRes;
-        //let status = client.script_subscribe(&script)?;
         let mut last_status = None;
 
-
-
         loop {
             async_std::task::sleep(Duration::from_secs(5)).await;
-            //let current_status = client.script_pop(&script)?;
-
-            let new_status = match client.lock().await.status_of_script(&tx) {
+            let new_status = match client.lock().await.status_of_script(script.clone()) {
                 Ok(new_status) => new_status,
                 Err(error) => {
                     debug!(target: "BTC BRIDGE", "Failed to get status of script: {:#}", error);
@@ -422,33 +413,39 @@ impl BtcClient {
                 }
             };
 
-            last_status = Some(print_status_change(txid, last_status, new_status));
+            last_status = Some(print_status_change(&script, last_status, new_status));
 
             match new_status {
                 ScriptStatus::Unseen => continue,
                 ScriptStatus::InMempool => continue,
                 ScriptStatus::Confirmed(inner) => {
                     let confirmations = inner.confirmations();
-                    debug!(target: "BTC BRIDGE", "Received confirmed tx: {:#}", confirmations);
                     if confirmations > 0 {
                         break
                     }
                 },
             }
 
-        } // Endloop
+        }
 
-        cur_balance = electrum.script_get_balance(&script)?;
+        let client2 = client.lock().await;
+        let mut subscriptions = client2.subscriptions.lock().await;
+        let index = subscriptions.iter().position(|p| p == &script);
+        if let Some(ind) = index {
+            debug!("Removing subscription from list");
+            subscriptions.remove(ind);
+        }
+        cur_balance = client.lock().await.electrum.script_get_balance(&script)?;
 
         let send_notification = self.notify_channel.0.clone();
 
-        if cur_balance.unconfirmed < prev_balance.unconfirmed {
+        if cur_balance.confirmed < prev_balance.confirmed {
             return Err(BtcFailed::Notification(
                 "New balance is less than previous balance".into(),
             ));
         }
-        //TODO: Wait until they're confirmed balances above
-        let amnt = cur_balance.unconfirmed - prev_balance.unconfirmed;
+
+        let amnt = cur_balance.confirmed - prev_balance.confirmed;
         let ui_amnt = amnt;
 
         send_notification
@@ -559,19 +556,12 @@ impl NetworkClient for BtcClient {
         let private_key = serialize(&keypair);
         let public_key = btc_keys.address.to_string();
 
-        let keys_clone = btc_keys.clone();
-        let script = keys_clone.script_pubkey;
-
-        let txid = self.client.lock().await.electrum
-            .script_get_history(&script).unwrap()[0].tx_hash;
-
         // start scheduler for checking balance
         debug!(target: "BRIDGE BITCOIN", "Subscribing for deposit");
 
         executor
             .spawn(async move {
                 let result = self.handle_subscribe_request(
-                    (txid, script),
                     btc_keys,
                     drk_pub_key
                 ).await;
@@ -599,17 +589,9 @@ impl NetworkClient for BtcClient {
         let btc_keys = Account::new(&keypair, self.network);
         let public_key = btc_keys.address.to_string();
 
-        let keys_clone = btc_keys.clone();
-        let script = keys_clone.script_pubkey;
-
-        //Ugly
-        let txid = self.client.lock().await.electrum.
-            script_get_history(&script).unwrap()[0].tx_hash;
-
         executor
             .spawn(async move {
                 let result = self.handle_subscribe_request(
-                    (txid, script),
                     btc_keys,
                     drk_pub_key
                 ).await;