diff --git a/src/bin/sol-test b/src/bin/sol-test.rs similarity index 80% rename from src/bin/sol-test rename to src/bin/sol-test.rs index 41490b6c1..1d547583e 100644 --- a/src/bin/sol-test +++ b/src/bin/sol-test.rs @@ -42,7 +42,7 @@ async fn run() -> Result<()> { let bridge_res = bridge_subscribtion.receiver.recv().await?; - // XXX this will not work + // XXX this will not work match bridge_res.payload { bridge::BridgeResponsePayload::Watch(_, token_pub) => { println!("watch this address {}", token_pub); @@ -57,19 +57,22 @@ async fn run() -> Result<()> { fn main() -> Result<()> { #[cfg(feature = "sol")] - let args = clap_app!(darkfid => - (@arg verbose: -v --verbose "Increase verbosity") - ) - .get_matches(); + { + let args = clap_app!(darkfid => + (@arg verbose: -v --verbose "Increase verbosity") + ) + .get_matches(); - let loglevel = if args.is_present("verbose") { - log::Level::Debug - } else { - log::Level::Info - }; + let loglevel = if args.is_present("verbose") { + log::Level::Debug + } else { + log::Level::Info + }; - simple_logger::init_with_level(loglevel)?; + simple_logger::init_with_level(loglevel)?; + } + #[cfg(feature = "sol")] smol::block_on(run())?; Ok(()) } diff --git a/src/service/bridge.rs b/src/service/bridge.rs index c55e5367f..05819a773 100644 --- a/src/service/bridge.rs +++ b/src/service/bridge.rs @@ -49,7 +49,7 @@ pub struct TokenNotification { } pub struct Bridge { - clients: Mutex>>, + clients: Mutex>>, //notifiers: Mutex, async_channel::Receiver>>, } @@ -64,7 +64,7 @@ impl Bridge { pub async fn add_clients( self: Arc, network: String, - client: Arc, + client: Arc, ) -> Result<()> { //let notifier = client.get_notifier().await?; @@ -97,6 +97,7 @@ impl Bridge { rep: async_channel::Sender, ) -> Result<()> { let req = req.recv().await?; + let network = req.network; if !self.clients.lock().await.contains_key(&network) { @@ -108,7 +109,13 @@ impl Bridge { return Ok(()); } - let client = &self.clients.lock().await[&network]; + + let client: Arc; + // avoid deadlock + { + let c = &self.clients.lock().await[&network]; + client = c.clone(); + } match req.payload { BridgeRequestsPayload::Watch(val) => match val { @@ -146,17 +153,17 @@ impl Bridge { } #[async_trait] -pub trait TokenClient { - async fn subscribe(&self) -> Result; +pub trait NetworkClient { + async fn subscribe(self: Arc) -> Result; // should check if the keypair in not already subscribed async fn subscribe_with_keypair( - &self, + self: Arc, private_key: Vec, public_key: Vec, ) -> Result; - async fn get_notifier(&self) -> Result>; + async fn get_notifier(self: Arc) -> Result>; - async fn send(&self, address: Vec, amount: u64) -> Result<()>; + async fn send(self: Arc, address: Vec, amount: u64) -> Result<()>; } diff --git a/src/service/btc.rs b/src/service/btc.rs index e2e9e78e4..71d2c9093 100644 --- a/src/service/btc.rs +++ b/src/service/btc.rs @@ -1,4 +1,4 @@ -use super::bridge::{TokenClient, TokenNotification, TokenSubscribtion}; +use super::bridge::{NetworkClient, TokenNotification, TokenSubscribtion}; use crate::serial::{serialize, Decodable, Encodable}; use crate::Result; @@ -155,8 +155,8 @@ impl BtcClient { } #[async_trait] -impl TokenClient for BtcClient { - async fn subscribe(&self) -> Result { +impl NetworkClient for BtcClient { + async fn subscribe(self: Arc) -> Result { //// Generate bitcoin Address let btc_keys = BitcoinKeys::new(self.client.clone(), self.network)?; @@ -178,7 +178,7 @@ impl TokenClient for BtcClient { } async fn subscribe_with_keypair( - &self, + self: Arc, _private_key: Vec, _public_key: Vec, ) -> Result { @@ -186,12 +186,12 @@ impl TokenClient for BtcClient { Ok(String::new()) } - async fn get_notifier(&self) -> Result> { + async fn get_notifier(self: Arc) -> Result> { // TODO this not implemented yet let (_, notifier) = async_channel::unbounded(); Ok(notifier) } - async fn send(&self, _address: Vec, _amount: u64) -> Result<()> { + async fn send(self: Arc, _address: Vec, _amount: u64) -> Result<()> { // TODO this not implemented yet Ok(()) } diff --git a/src/service/sol.rs b/src/service/sol.rs index 5c2067d45..4e893c9e9 100644 --- a/src/service/sol.rs +++ b/src/service/sol.rs @@ -5,7 +5,7 @@ use crate::rpc::{ use crate::serial::{deserialize, serialize, Decodable, Encodable}; use crate::{Error, Result}; -use super::bridge::{TokenClient, TokenNotification, TokenSubscribtion}; +use super::bridge::{NetworkClient, TokenNotification, TokenSubscribtion}; use async_native_tls::TlsConnector; use async_std::sync::{Arc, Mutex}; @@ -79,7 +79,7 @@ impl SolClient { let v: std::collections::HashMap = serde_json::from_str(&data).map_err(|err| Error::from(err))?; - // XXX this for testing + // XXX this for testing if v.contains_key(&String::from("result")) { json_res = JsonResult::Resp(JsonResponse { jsonrpc: v["jsonrpc"].clone(), @@ -170,7 +170,7 @@ impl SolClient { self.unsubscribe(sub_id, &keypair.pubkey()).await?; - self.send_to_main_account(&keypair, new_bal)?; + //self.send_to_main_account(&keypair, new_bal)?; debug!( target: "SOL BRIDGE", @@ -187,7 +187,7 @@ impl SolClient { Ok(()) } - fn send_to_main_account(&self, keypair: &Keypair, amount: u64) -> SolResult<()> { + pub fn send_to_main_account(&self, keypair: &Keypair, amount: u64) -> SolResult<()> { debug!( target: "SOL BRIDGE", "send received token to main account" @@ -207,7 +207,7 @@ impl SolClient { Ok(()) } - async fn handle_subscribe_request(&self, keypair: Keypair) -> Result<()> { + async fn handle_subscribe_request(self: Arc, keypair: Keypair) -> Result<()> { debug!( target: "SOL BRIDGE", "Handle subscribe request" @@ -299,14 +299,15 @@ impl SolClient { } #[async_trait] -impl TokenClient for SolClient { - async fn subscribe(&self) -> Result { +impl NetworkClient for SolClient { + async fn subscribe(self: Arc) -> Result { let keypair = Keypair::generate(&mut OsRng); let public_key = keypair.pubkey().to_string(); let secret_key = serialize(&keypair); - self.handle_subscribe_request(keypair).await?; + let self2 = self.clone(); + smol::spawn(self2.handle_subscribe_request(keypair)).detach(); Ok(TokenSubscribtion { secret_key, @@ -316,7 +317,7 @@ impl TokenClient for SolClient { // in solana case private key it's the same as keypair async fn subscribe_with_keypair( - &self, + self: Arc, private_key: Vec, _public_key: Vec, ) -> Result { @@ -324,16 +325,17 @@ impl TokenClient for SolClient { let public_key = keypair.pubkey().to_string(); - self.handle_subscribe_request(keypair).await?; + let self2 = self.clone(); + smol::spawn(self2.handle_subscribe_request(keypair)).detach(); Ok(public_key) } - async fn get_notifier(&self) -> Result> { + async fn get_notifier(self: Arc) -> Result> { Ok(self.notify_channel.1.clone()) } - async fn send(&self, address: Vec, amount: u64) -> Result<()> { + async fn send(self: Arc, address: Vec, amount: u64) -> Result<()> { let rpc = RpcClient::new(RPC_SERVER.to_string()); let address: Pubkey = deserialize(&address)?; let instruction = system_instruction::transfer(&self.keypair.pubkey(), &address, amount);