gateway.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. use std::convert::From;
  2. use std::net::SocketAddr;
  3. use std::net::ToSocketAddrs;
  4. use std::sync::Arc;
  5. use async_executor::Executor;
  6. use log::debug;
  7. use url::Url;
  8. use super::reqrep::{PeerId, Publisher, RepProtocol, Reply, ReqProtocol, Request, Subscriber};
  9. use crate::blockchain::{rocks::columns, RocksColumn, Slab, SlabStore};
  10. use crate::{serial::deserialize, serial::serialize, Error, Result};
  11. pub type GatewaySlabsSubscriber = async_channel::Receiver<Slab>;
  12. #[repr(u8)]
  13. enum GatewayError {
  14. NoError,
  15. UpdateIndex,
  16. IndexNotExist,
  17. }
  18. #[repr(u8)]
  19. enum GatewayCommand {
  20. PutSlab,
  21. GetSlab,
  22. GetLastIndex,
  23. }
  24. pub struct GatewayService {
  25. slabstore: Arc<SlabStore>,
  26. addr: SocketAddr,
  27. pub_addr: SocketAddr,
  28. }
  29. impl GatewayService {
  30. pub fn new(
  31. addr: SocketAddr,
  32. pub_addr: SocketAddr,
  33. rocks: RocksColumn<columns::Slabs>,
  34. ) -> Result<Arc<GatewayService>> {
  35. let slabstore = SlabStore::new(rocks)?;
  36. Ok(Arc::new(GatewayService {
  37. slabstore,
  38. addr,
  39. pub_addr,
  40. }))
  41. }
  42. pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  43. let service_name = String::from("GATEWAY DAEMON");
  44. let mut protocol = RepProtocol::new(self.addr, service_name.clone());
  45. let (send, recv) = protocol.start().await?;
  46. let (publish_queue, publish_recv_queue) = async_channel::unbounded::<Vec<u8>>();
  47. let publisher_task = executor.spawn(Self::start_publisher(
  48. self.pub_addr,
  49. service_name,
  50. publish_recv_queue.clone(),
  51. ));
  52. let handle_request_task = executor.spawn(self.handle_request_loop(
  53. send.clone(),
  54. recv.clone(),
  55. publish_queue.clone(),
  56. executor.clone(),
  57. ));
  58. protocol.run(executor.clone()).await?;
  59. let _ = publisher_task.cancel().await;
  60. let _ = handle_request_task.cancel().await;
  61. Ok(())
  62. }
  63. async fn start_publisher(
  64. pub_addr: SocketAddr,
  65. service_name: String,
  66. publish_recv_queue: async_channel::Receiver<Vec<u8>>,
  67. ) -> Result<()> {
  68. let mut publisher = Publisher::new(pub_addr, service_name);
  69. publisher.start(publish_recv_queue).await?;
  70. Ok(())
  71. }
  72. async fn handle_request_loop(
  73. self: Arc<Self>,
  74. send_queue: async_channel::Sender<(PeerId, Reply)>,
  75. recv_queue: async_channel::Receiver<(PeerId, Request)>,
  76. publish_queue: async_channel::Sender<Vec<u8>>,
  77. executor: Arc<Executor<'_>>,
  78. ) -> Result<()> {
  79. while let Ok(msg) = recv_queue.recv().await {
  80. let slabstore = self.slabstore.clone();
  81. let _ = executor
  82. .spawn(Self::handle_request(
  83. msg,
  84. slabstore,
  85. send_queue.clone(),
  86. publish_queue.clone(),
  87. ))
  88. .detach();
  89. }
  90. Ok(())
  91. }
  92. async fn handle_request(
  93. msg: (PeerId, Request),
  94. slabstore: Arc<SlabStore>,
  95. send_queue: async_channel::Sender<(PeerId, Reply)>,
  96. publish_queue: async_channel::Sender<Vec<u8>>,
  97. ) -> Result<()> {
  98. let request = msg.1;
  99. let peer = msg.0;
  100. match request.get_command() {
  101. 0 => {
  102. debug!(target: "GATEWAY DAEMON" ,"Received putslab msg");
  103. // PUTSLAB
  104. let slab = request.get_payload();
  105. // add to slabstore
  106. let error = slabstore.put(deserialize(&slab)?)?;
  107. let mut reply = Reply::from(&request, GatewayError::NoError as u32, vec![]);
  108. if error.is_none() {
  109. reply.set_error(GatewayError::UpdateIndex as u32);
  110. }
  111. // send reply
  112. send_queue.send((peer, reply)).await?;
  113. // publish to all subscribes
  114. publish_queue.send(slab).await?;
  115. }
  116. 1 => {
  117. debug!(target: "GATEWAY DAEMON", "Received getslab msg");
  118. let index = request.get_payload();
  119. let slab = slabstore.get(index)?;
  120. let mut reply = Reply::from(&request, GatewayError::NoError as u32, vec![]);
  121. if let Some(payload) = slab {
  122. reply.set_payload(payload);
  123. } else {
  124. reply.set_error(GatewayError::IndexNotExist as u32);
  125. }
  126. send_queue.send((peer, reply)).await?;
  127. // GETSLAB
  128. }
  129. 2 => {
  130. debug!(target: "GATEWAY DAEMON","Received getlastindex msg");
  131. let index = slabstore.get_last_index_as_bytes()?;
  132. let reply = Reply::from(&request, GatewayError::NoError as u32, index);
  133. send_queue.send((peer, reply)).await?;
  134. // GETLASTINDEX
  135. }
  136. _ => {
  137. return Err(Error::ServicesError("received wrong command"));
  138. }
  139. }
  140. Ok(())
  141. }
  142. }
  143. pub struct GatewayClient {
  144. protocol: ReqProtocol,
  145. slabstore: Arc<SlabStore>,
  146. gateway_slabs_sub_s: async_channel::Sender<Slab>,
  147. gateway_slabs_sub_rv: GatewaySlabsSubscriber,
  148. is_running: bool,
  149. sub_addr: SocketAddr,
  150. }
  151. impl GatewayClient {
  152. pub fn new(addr: Url, sub_addr: Url, rocks: RocksColumn<columns::Slabs>) -> Result<Self> {
  153. // TODO: We'll want differentiation between TCP and TLS here.
  154. let addr_sock = (addr.host().unwrap().to_string(), addr.port().unwrap())
  155. .to_socket_addrs()?
  156. .next()
  157. .ok_or(Error::UrlParseError)?;
  158. let protocol = ReqProtocol::new(addr_sock, String::from("GATEWAY CLIENT"));
  159. let slabstore = SlabStore::new(rocks)?;
  160. let (gateway_slabs_sub_s, gateway_slabs_sub_rv) = async_channel::unbounded::<Slab>();
  161. let sub_addr_sock = (
  162. sub_addr.host().unwrap().to_string(),
  163. sub_addr.port().unwrap(),
  164. )
  165. .to_socket_addrs()?
  166. .next()
  167. .ok_or(Error::UrlParseError)?;
  168. Ok(GatewayClient {
  169. protocol,
  170. slabstore,
  171. gateway_slabs_sub_s,
  172. gateway_slabs_sub_rv,
  173. is_running: false,
  174. sub_addr: sub_addr_sock,
  175. })
  176. }
  177. pub async fn start(&mut self) -> Result<()> {
  178. self.protocol.start().await?;
  179. self.sync().await?;
  180. self.is_running = true;
  181. Ok(())
  182. }
  183. pub async fn sync(&mut self) -> Result<u64> {
  184. debug!(target: "GATEWAY CLIENT", "Start Syncing");
  185. let local_last_index = self.slabstore.get_last_index()?;
  186. let last_index = self.get_last_index().await?;
  187. if last_index < local_last_index {
  188. return Err(Error::SlabsStore(
  189. "Local slabstore has higher index than gateway's slabstore.
  190. Run \" darkfid -r \" to refresh the database."
  191. .into(),
  192. ));
  193. }
  194. if last_index > 0 {
  195. for index in (local_last_index + 1)..(last_index + 1) {
  196. if self.get_slab(index).await?.is_none() {
  197. break;
  198. }
  199. }
  200. }
  201. debug!(target: "GATEWAY CLIENT","End Syncing");
  202. Ok(last_index)
  203. }
  204. pub async fn get_slab(&mut self, index: u64) -> Result<Option<Slab>> {
  205. debug!(target: "GATEWAY CLIENT","Get slab");
  206. let handle_error = Arc::new(handle_error);
  207. let rep = self
  208. .protocol
  209. .request(
  210. GatewayCommand::GetSlab as u8,
  211. serialize(&index),
  212. handle_error,
  213. )
  214. .await?;
  215. if let Some(slab) = rep {
  216. let slab: Slab = deserialize(&slab)?;
  217. self.gateway_slabs_sub_s.send(slab.clone()).await?;
  218. self.slabstore.put(slab.clone())?;
  219. return Ok(Some(slab));
  220. }
  221. Ok(None)
  222. }
  223. pub async fn put_slab(&mut self, mut slab: Slab) -> Result<()> {
  224. debug!(target: "GATEWAY CLIENT","Put slab");
  225. loop {
  226. let last_index = self.sync().await?;
  227. slab.set_index(last_index + 1);
  228. let slab = serialize(&slab);
  229. let handle_error = Arc::new(handle_error);
  230. let rep = self
  231. .protocol
  232. .request(GatewayCommand::PutSlab as u8, slab.clone(), handle_error)
  233. .await?;
  234. if rep.is_some() {
  235. break;
  236. }
  237. }
  238. Ok(())
  239. }
  240. pub async fn get_last_index(&mut self) -> Result<u64> {
  241. debug!(target: "GATEWAY CLIENT","Get last index");
  242. let handle_error = Arc::new(handle_error);
  243. let rep = self
  244. .protocol
  245. .request(GatewayCommand::GetLastIndex as u8, vec![], handle_error)
  246. .await?;
  247. if let Some(index) = rep {
  248. return deserialize(&index);
  249. }
  250. Ok(0)
  251. }
  252. pub fn get_slabstore(&self) -> Arc<SlabStore> {
  253. self.slabstore.clone()
  254. }
  255. pub async fn start_subscriber(
  256. &self,
  257. executor: Arc<Executor<'_>>,
  258. ) -> Result<GatewaySlabsSubscriber> {
  259. debug!(target: "GATEWAY CLIENT","Start subscriber");
  260. let mut subscriber = Subscriber::new(self.sub_addr, String::from("GATEWAY CLIENT"));
  261. subscriber.start().await?;
  262. executor
  263. .spawn(Self::subscribe_loop(
  264. subscriber,
  265. self.slabstore.clone(),
  266. self.gateway_slabs_sub_s.clone(),
  267. ))
  268. .detach();
  269. Ok(self.gateway_slabs_sub_rv.clone())
  270. }
  271. async fn subscribe_loop(
  272. mut subscriber: Subscriber,
  273. slabstore: Arc<SlabStore>,
  274. gateway_slabs_sub_s: async_channel::Sender<Slab>,
  275. ) -> Result<()> {
  276. debug!(target: "GATEWAY CLIENT","Start subscribe loop");
  277. loop {
  278. let slab = subscriber.fetch::<Slab>().await?;
  279. debug!(target: "GATEWAY CLIENT","Received new slab");
  280. gateway_slabs_sub_s.send(slab.clone()).await?;
  281. slabstore.put(slab)?;
  282. }
  283. }
  284. pub fn is_running(&self) -> bool {
  285. self.is_running
  286. }
  287. }
  288. fn handle_error(status_code: u32) {
  289. match status_code {
  290. 1 => {
  291. debug!(target: "GATEWAY SERVICE", "Reply has an Error: Index is not updated");
  292. }
  293. 2 => {
  294. debug!(target: "GATEWAY SERVICE", "Reply has an Error: Index Not Exist");
  295. }
  296. _ => {}
  297. }
  298. }