bridge.rs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. use std::collections::HashMap;
  2. use async_executor::Executor;
  3. use async_std::sync::{Arc, Mutex};
  4. use async_trait::async_trait;
  5. use futures::stream::{FuturesUnordered, StreamExt};
  6. use log::{debug, error};
  7. use crate::{
  8. crypto::keypair::PublicKey, types::*, util::NetworkName, wallet::cashierdb::TokenKey, Error,
  9. Result,
  10. };
  11. pub struct BridgeRequests {
  12. pub network: NetworkName,
  13. pub payload: BridgeRequestsPayload,
  14. }
  15. pub struct BridgeResponse {
  16. pub error: BridgeResponseError,
  17. pub payload: BridgeResponsePayload,
  18. }
  19. pub enum BridgeRequestsPayload {
  20. Send(Vec<u8>, u64), // send (address, amount)
  21. Watch(Option<TokenKey>), // if already has a keypair
  22. }
  23. pub enum BridgeResponsePayload {
  24. Watch(TokenSubscribtion),
  25. Address(String),
  26. Send,
  27. Empty,
  28. }
  29. #[repr(u8)]
  30. pub enum BridgeResponseError {
  31. NoError,
  32. NotSupportedClient,
  33. BridgeWatchSubscribtionError,
  34. BridgeSendSubscribtionError,
  35. }
  36. pub struct BridgeSubscribtion {
  37. pub sender: async_channel::Sender<BridgeRequests>,
  38. pub receiver: async_channel::Receiver<BridgeResponse>,
  39. }
  40. #[derive(Debug)]
  41. pub struct TokenSubscribtion {
  42. pub private_key: Vec<u8>,
  43. pub public_key: String,
  44. }
  45. #[derive(Debug)]
  46. pub struct TokenNotification {
  47. pub network: NetworkName,
  48. pub token_id: DrkTokenId,
  49. pub drk_pub_key: PublicKey,
  50. pub received_balance: u64,
  51. pub decimals: u16,
  52. }
  53. pub struct Bridge {
  54. clients: Mutex<HashMap<NetworkName, Arc<dyn NetworkClient + Send + Sync>>>,
  55. notifiers: FuturesUnordered<async_channel::Receiver<TokenNotification>>,
  56. }
  57. impl Bridge {
  58. pub fn new() -> Arc<Self> {
  59. Arc::new(Self { clients: Mutex::new(HashMap::new()), notifiers: FuturesUnordered::new() })
  60. }
  61. pub async fn add_clients(
  62. self: Arc<Self>,
  63. network: NetworkName,
  64. client: Arc<dyn NetworkClient + Send + Sync>,
  65. ) -> Result<()> {
  66. debug!(target: "BRIDGE", "Adding new client");
  67. let client2 = client.clone();
  68. let notifier = client2.get_notifier().await?;
  69. if !notifier.is_closed() {
  70. self.notifiers.push(notifier);
  71. }
  72. self.clients.lock().await.insert(network, client.clone());
  73. Ok(())
  74. }
  75. pub async fn listen(self: Arc<Self>) -> Option<Result<TokenNotification>> {
  76. if !self.notifiers.is_empty() {
  77. debug!(target: "BRIDGE", "Start listening for new notifications");
  78. let notification = self
  79. .notifiers
  80. .iter()
  81. .map(|n| n.recv())
  82. .collect::<FuturesUnordered<async_channel::Recv<TokenNotification>>>()
  83. .next()
  84. .await
  85. .map(|o| o.map_err(Error::from));
  86. debug!(target: "BRIDGE", "Stop listening for new notifications");
  87. notification
  88. } else {
  89. None
  90. }
  91. }
  92. pub async fn subscribe(
  93. self: Arc<Self>,
  94. drk_pub_key: PublicKey,
  95. mint: Option<String>,
  96. executor: Arc<Executor<'_>>,
  97. ) -> BridgeSubscribtion {
  98. debug!(target: "BRIDGE", "Start new subscription");
  99. let (sender, req) = async_channel::unbounded();
  100. let (rep, receiver) = async_channel::unbounded();
  101. executor
  102. .spawn(self.listen_for_new_subscription(req, rep, drk_pub_key, mint, executor.clone()))
  103. .detach();
  104. BridgeSubscribtion { sender, receiver }
  105. }
  106. async fn listen_for_new_subscription(
  107. self: Arc<Self>,
  108. req: async_channel::Receiver<BridgeRequests>,
  109. rep: async_channel::Sender<BridgeResponse>,
  110. drk_pub_key: PublicKey,
  111. mint: Option<String>,
  112. executor: Arc<Executor<'_>>,
  113. ) -> Result<()> {
  114. debug!(target: "BRIDGE", "Listen for new subscriptions");
  115. let req = req.recv().await?;
  116. let network = req.network;
  117. if !self.clients.lock().await.contains_key(&network) {
  118. let res = BridgeResponse {
  119. error: BridgeResponseError::NotSupportedClient,
  120. payload: BridgeResponsePayload::Empty,
  121. };
  122. rep.send(res).await?;
  123. return Ok(())
  124. }
  125. let mut mint_address: Option<String> = mint.clone();
  126. if mint.is_some() && mint.unwrap().is_empty() {
  127. mint_address = None;
  128. }
  129. let client: Arc<dyn NetworkClient + Send + Sync>;
  130. // avoid deadlock
  131. {
  132. let c = &self.clients.lock().await[&network];
  133. client = c.clone();
  134. }
  135. let res: BridgeResponse;
  136. match req.payload {
  137. BridgeRequestsPayload::Watch(val) => match val {
  138. Some(token_key) => {
  139. let pub_key = client
  140. .subscribe_with_keypair(
  141. token_key.secret_key,
  142. token_key.public_key,
  143. drk_pub_key,
  144. mint_address,
  145. executor,
  146. )
  147. .await;
  148. if pub_key.is_err() {
  149. error!(target: "BRIDGE", "{}", pub_key.unwrap_err().to_string());
  150. res = BridgeResponse {
  151. error: BridgeResponseError::BridgeWatchSubscribtionError,
  152. payload: BridgeResponsePayload::Empty,
  153. };
  154. } else {
  155. res = BridgeResponse {
  156. error: BridgeResponseError::NoError,
  157. payload: BridgeResponsePayload::Address(pub_key?),
  158. };
  159. }
  160. }
  161. None => {
  162. let sub = client.subscribe(drk_pub_key, mint_address, executor).await;
  163. if sub.is_err() {
  164. error!(target: "BRIDGE", "{}", sub.unwrap_err().to_string());
  165. res = BridgeResponse {
  166. error: BridgeResponseError::BridgeWatchSubscribtionError,
  167. payload: BridgeResponsePayload::Empty,
  168. };
  169. } else {
  170. let sub = sub?;
  171. res = BridgeResponse {
  172. error: BridgeResponseError::NoError,
  173. payload: BridgeResponsePayload::Watch(sub),
  174. };
  175. }
  176. }
  177. },
  178. BridgeRequestsPayload::Send(addr, amount) => {
  179. let result = client.send(addr, mint_address, amount).await;
  180. if result.is_err() {
  181. error!(target: "BRIDGE", "{}", result.unwrap_err().to_string());
  182. res = BridgeResponse {
  183. error: BridgeResponseError::BridgeSendSubscribtionError,
  184. payload: BridgeResponsePayload::Empty,
  185. };
  186. } else {
  187. res = BridgeResponse {
  188. error: BridgeResponseError::NoError,
  189. payload: BridgeResponsePayload::Send,
  190. };
  191. }
  192. }
  193. }
  194. rep.send(res).await?;
  195. Ok(())
  196. }
  197. }
  198. #[async_trait]
  199. pub trait NetworkClient {
  200. async fn subscribe(
  201. self: Arc<Self>,
  202. drk_pub_key: PublicKey,
  203. mint: Option<String>,
  204. executor: Arc<Executor<'_>>,
  205. ) -> Result<TokenSubscribtion>;
  206. // should check if the keypair in not already subscribed
  207. async fn subscribe_with_keypair(
  208. self: Arc<Self>,
  209. private_key: Vec<u8>,
  210. public_key: Vec<u8>,
  211. drk_pub_key: PublicKey,
  212. mint: Option<String>,
  213. executor: Arc<Executor<'_>>,
  214. ) -> Result<String>;
  215. async fn get_notifier(self: Arc<Self>) -> Result<async_channel::Receiver<TokenNotification>>;
  216. async fn send(
  217. self: Arc<Self>,
  218. address: Vec<u8>,
  219. mint: Option<String>,
  220. amount: u64,
  221. ) -> Result<()>;
  222. }