Răsfoiți Sursa

Add subscribe to electrum script to BitcoinKeys

Janus 5 ani în urmă
părinte
comite
7da18619d8
2 a modificat fișierele cu 68 adăugiri și 25 ștergeri
  1. 56 10
      src/service/btc.rs
  2. 12 15
      src/service/cashier.rs

+ 56 - 10
src/service/btc.rs

@@ -6,14 +6,12 @@ use rand::{thread_rng, Rng};
 use bitcoin::util::address::Address;
 use bitcoin::util::ecdsa::{PrivateKey, PublicKey};
 use secp256k1::key::SecretKey;
-
+use bitcoin::blockdata::script::Script;
 use bitcoin::network::constants::Network;
-
-
-
-
-
-
+use async_std::sync::Arc;
+use async_executor::Executor;
+use log::*;
+use electrum_client::{Client as ElectrumClient, ElectrumApi};
 
 // Swap out these types for any future non bitcoin-rs types
 pub type PubAddress = Address;
@@ -24,12 +22,21 @@ pub type PrivKey = PrivateKey;
 pub struct BitcoinKeys {
     secret_key: SecretKey,
     bitcoin_private_key: PrivateKey,
+    btc_client: ElectrumClient,
     pub bitcoin_public_key: PublicKey,
     pub pub_address: Address,
+    pub script: Script,
 }
 
 impl BitcoinKeys {
-    pub fn new() -> Result<BitcoinKeys> {
+    pub fn new() -> Result<Arc<BitcoinKeys>> {
+
+        // Pull address from config later
+        let client_address = "";
+
+        // create client
+        let mut btc_client = ElectrumClient::new(&client_address).unwrap();
+
         let context = secp256k1::Secp256k1::new();
 
         // Probably not good enough for release
@@ -54,12 +61,51 @@ impl BitcoinKeys {
 
         let pub_address = Address::p2pkh(&bitcoin_public_key, Network::Testnet);
 
-        Ok(Self {
+        let script = Script::new_p2pk(&bitcoin_public_key);
+
+        Ok(Arc::new(BitcoinKeys {
             secret_key,
             bitcoin_private_key,
             bitcoin_public_key,
+            btc_client,
             pub_address,
-        })
+            script,
+        }))
+    }
+
+    pub async fn start_subscribe(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
+        debug!(target: "BTC", "Subscribe");
+
+        // Check if script is already subscribed
+        let status = self.btc_client.script_subscribe(&self.script).unwrap();
+        let subscribe_status_task =
+            executor.spawn(
+                self.subscribe_status_loop(executor.clone()),
+            );
+
+        let _ = subscribe_status_task.cancel().await;
+
+        Ok(())
+    }
+
+    async fn subscribe_status_loop(
+        self: Arc<Self>,
+        executor: Arc<Executor<'_>>,
+    ) -> Result<()> {
+        loop {
+            let check = self.btc_client.script_pop(&self.script);
+            match check {
+                // Script has a notification update
+                Ok(status) => {
+
+                }
+                // No update
+                Err(_) => {
+                    break
+                }
+            }
+        }
+        Ok(())
     }
 
     // This should do a db lookup to return the same obj

+ 12 - 15
src/service/cashier.rs

@@ -38,7 +38,6 @@ pub struct CashierService {
     addr: SocketAddr,
     wallet: CashierDbPtr,
     gateway: GatewayClient,
-    btc_endpoint: String,
     mint_params: groth16::Parameters<Bls12>,
     mint_pvk: groth16::PreparedVerifyingKey<Bls12>,
     spend_params: groth16::Parameters<Bls12>,
@@ -60,7 +59,6 @@ impl CashierService {
             addr,
             wallet,
             gateway,
-            btc_endpoint,
             mint_params,
             mint_pvk,
             spend_params,
@@ -74,10 +72,13 @@ impl CashierService {
         let mut protocol = RepProtocol::new(self.addr.clone(), service_name.clone());
 
         let (send, recv) = protocol.start().await?;
-        let _ex2 = executor.clone();
 
         let handle_request_task =
-            executor.spawn(self.handle_request_loop(send.clone(), recv.clone(), executor.clone()));
+            executor.spawn(self.handle_request_loop(
+                send.clone(),
+                recv.clone(),
+                executor.clone()
+            ));
 
         protocol.run(executor.clone()).await?;
 
@@ -86,15 +87,6 @@ impl CashierService {
         Ok(())
     }
 
-    pub async fn subscribe_to_address(&self, script: Script) -> Result<()> {
-        debug!(target: "BTC", "Subscribe");
-        let client = Client::new(&self.btc_endpoint).unwrap();
-
-        let _response = client.script_subscribe(&script).unwrap();
-
-        Ok(())
-    }
-
     async fn mint_dbtc(&mut self, dkey_pub: jubjub::SubgroupPoint, value: u64) -> Result<()> {
         let cashier_secret = self.wallet.get_cashier_private().unwrap();
 
@@ -158,7 +150,7 @@ impl CashierService {
         msg: (PeerId, Request),
         cashier_wallet: CashierDbPtr,
         send_queue: async_channel::Sender<(PeerId, Reply)>,
-        _executor: Arc<Executor<'_>>,
+        executor: Arc<Executor<'_>>,
     ) -> Result<()> {
         let request = msg.1;
         let peer = msg.0;
@@ -189,7 +181,12 @@ impl CashierService {
                 info!("Received dkey->btc msg");
 
                 // start scheduler for checking balance
-                //let _result = btc_keys.start_scheduler(executor.clone());
+                debug!(target: "BTC", "Subscribing");
+
+                btc_keys.start_subscribe(executor.clone()).await?;
+                //self.mint_dbtc(zkpub, 100);
+                //let _ = self.subscribe_to_address(script);
+
                 info!("Waiting for address balance");
             }
             1 => {