bridge.rs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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;
  6. use futures::stream::StreamExt;
  7. use log::*;
  8. use crate::util::NetworkName;
  9. use crate::wallet::cashierdb::TokenKey;
  10. use crate::{types::*, Error, Result};
  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: DrkPublicKey,
  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 {
  60. clients: Mutex::new(HashMap::new()),
  61. notifiers: FuturesUnordered::new(),
  62. })
  63. }
  64. pub async fn add_clients(
  65. self: Arc<Self>,
  66. network: NetworkName,
  67. client: Arc<dyn NetworkClient + Send + Sync>,
  68. ) -> Result<()> {
  69. debug!(target: "BRIDGE", "Add new client");
  70. let client2 = client.clone();
  71. let notifier = client2.get_notifier().await?;
  72. if !notifier.is_closed() {
  73. self.notifiers.push(notifier);
  74. }
  75. self.clients.lock().await.insert(network, client.clone());
  76. Ok(())
  77. }
  78. pub async fn listen(self: Arc<Self>) -> Option<Result<TokenNotification>> {
  79. if !self.notifiers.is_empty() {
  80. debug!(target: "BRIDGE", "Start listening to new notification");
  81. let notification = self
  82. .notifiers
  83. .iter()
  84. .map(|n| n.recv())
  85. .collect::<FuturesUnordered<async_channel::Recv<TokenNotification>>>()
  86. .next()
  87. .await
  88. .map(|o| o.map_err(Error::from));
  89. debug!(target: "BRIDGE", "End listening to new notification");
  90. notification
  91. } else {
  92. None
  93. }
  94. }
  95. pub async fn subscribe(
  96. self: Arc<Self>,
  97. drk_pub_key: DrkPublicKey,
  98. mint: Option<String>,
  99. executor: Arc<Executor<'_>>,
  100. ) -> BridgeSubscribtion {
  101. debug!(target: "BRIDGE", "Start new subscription");
  102. let (sender, req) = async_channel::unbounded();
  103. let (rep, receiver) = async_channel::unbounded();
  104. executor
  105. .spawn(self.listen_for_new_subscription(req, rep, drk_pub_key, mint, executor.clone()))
  106. .detach();
  107. BridgeSubscribtion { sender, receiver }
  108. }
  109. async fn listen_for_new_subscription(
  110. self: Arc<Self>,
  111. req: async_channel::Receiver<BridgeRequests>,
  112. rep: async_channel::Sender<BridgeResponse>,
  113. drk_pub_key: DrkPublicKey,
  114. mint: Option<String>,
  115. executor: Arc<Executor<'_>>,
  116. ) -> Result<()> {
  117. debug!(target: "BRIDGE", "Listen for new subscription");
  118. let req = req.recv().await?;
  119. let network = req.network;
  120. if !self.clients.lock().await.contains_key(&network) {
  121. let res = BridgeResponse {
  122. error: BridgeResponseError::NotSupportedClient,
  123. payload: BridgeResponsePayload::Empty,
  124. };
  125. rep.send(res).await?;
  126. return Ok(());
  127. }
  128. let mut mint_address: Option<String> = mint.clone();
  129. if mint.is_some() && mint.unwrap().is_empty() {
  130. mint_address = None;
  131. }
  132. let client: Arc<dyn NetworkClient + Send + Sync>;
  133. // avoid deadlock
  134. {
  135. let c = &self.clients.lock().await[&network];
  136. client = c.clone();
  137. }
  138. let res: BridgeResponse;
  139. match req.payload {
  140. BridgeRequestsPayload::Watch(val) => match val {
  141. Some(token_key) => {
  142. let pub_key = client
  143. .subscribe_with_keypair(
  144. token_key.private_key,
  145. token_key.public_key,
  146. drk_pub_key,
  147. mint_address,
  148. executor,
  149. )
  150. .await;
  151. if pub_key.is_err() {
  152. error!(target: "BRIDGE", "{}", pub_key.unwrap_err().to_string());
  153. res = BridgeResponse {
  154. error: BridgeResponseError::BridgeWatchSubscribtionError,
  155. payload: BridgeResponsePayload::Empty,
  156. };
  157. } else {
  158. res = BridgeResponse {
  159. error: BridgeResponseError::NoError,
  160. payload: BridgeResponsePayload::Address(pub_key?),
  161. };
  162. }
  163. }
  164. None => {
  165. let sub = client.subscribe(drk_pub_key, mint_address, executor).await;
  166. if sub.is_err() {
  167. error!(target: "BRIDGE", "{}", sub.unwrap_err().to_string());
  168. res = BridgeResponse {
  169. error: BridgeResponseError::BridgeWatchSubscribtionError,
  170. payload: BridgeResponsePayload::Empty,
  171. };
  172. } else {
  173. let sub = sub?;
  174. res = BridgeResponse {
  175. error: BridgeResponseError::NoError,
  176. payload: BridgeResponsePayload::Watch(sub),
  177. };
  178. }
  179. }
  180. },
  181. BridgeRequestsPayload::Send(addr, amount) => {
  182. let result = client.send(addr, mint_address, amount).await;
  183. if result.is_err() {
  184. error!(target: "BRIDGE", "{}", result.unwrap_err().to_string());
  185. res = BridgeResponse {
  186. error: BridgeResponseError::BridgeSendSubscribtionError,
  187. payload: BridgeResponsePayload::Empty,
  188. };
  189. } else {
  190. res = BridgeResponse {
  191. error: BridgeResponseError::NoError,
  192. payload: BridgeResponsePayload::Send,
  193. };
  194. }
  195. }
  196. }
  197. rep.send(res).await?;
  198. Ok(())
  199. }
  200. }
  201. #[async_trait]
  202. pub trait NetworkClient {
  203. async fn subscribe(
  204. self: Arc<Self>,
  205. drk_pub_key: DrkPublicKey,
  206. mint: Option<String>,
  207. executor: Arc<Executor<'_>>,
  208. ) -> Result<TokenSubscribtion>;
  209. // should check if the keypair in not already subscribed
  210. async fn subscribe_with_keypair(
  211. self: Arc<Self>,
  212. private_key: Vec<u8>,
  213. public_key: Vec<u8>,
  214. drk_pub_key: DrkPublicKey,
  215. mint: Option<String>,
  216. executor: Arc<Executor<'_>>,
  217. ) -> Result<String>;
  218. async fn get_notifier(self: Arc<Self>) -> Result<async_channel::Receiver<TokenNotification>>;
  219. async fn send(
  220. self: Arc<Self>,
  221. address: Vec<u8>,
  222. mint: Option<String>,
  223. amount: u64,
  224. ) -> Result<()>;
  225. }