gateway.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. use std::{
  2. convert::From,
  3. net::{SocketAddr, ToSocketAddrs},
  4. sync::Arc,
  5. };
  6. use async_executor::Executor;
  7. use log::debug;
  8. use url::Url;
  9. use super::reqrep::{PeerId, Publisher, RepProtocol, Reply, ReqProtocol, Request, Subscriber};
  10. use crate::{
  11. blockchain::{rocks::columns, RocksColumn, Slab, SlabStore},
  12. serial::{deserialize, serialize},
  13. Error, Result,
  14. };
  15. pub type GatewaySlabsSubscriber = async_channel::Receiver<Slab>;
  16. #[repr(u8)]
  17. enum GatewayError {
  18. NoError,
  19. UpdateIndex,
  20. IndexNotExist,
  21. }
  22. #[repr(u8)]
  23. enum GatewayCommand {
  24. PutSlab,
  25. GetSlab,
  26. GetLastIndex,
  27. }
  28. pub struct GatewayService {
  29. slabstore: Arc<SlabStore>,
  30. addr: SocketAddr,
  31. pub_addr: SocketAddr,
  32. }
  33. impl GatewayService {
  34. pub fn new(
  35. addr: SocketAddr,
  36. pub_addr: SocketAddr,
  37. rocks: RocksColumn<columns::Slabs>,
  38. ) -> Result<Arc<GatewayService>> {
  39. let slabstore = SlabStore::new(rocks)?;
  40. Ok(Arc::new(GatewayService { slabstore, addr, pub_addr }))
  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. _ => return Err(Error::ServicesError("received wrong command")),
  137. }
  138. Ok(())
  139. }
  140. }
  141. pub struct GatewayClient {
  142. protocol: ReqProtocol,
  143. slabstore: Arc<SlabStore>,
  144. gateway_slabs_sub_s: async_channel::Sender<Slab>,
  145. gateway_slabs_sub_rv: GatewaySlabsSubscriber,
  146. is_running: bool,
  147. sub_addr: SocketAddr,
  148. }
  149. impl GatewayClient {
  150. pub fn new(addr: Url, sub_addr: Url, rocks: RocksColumn<columns::Slabs>) -> Result<Self> {
  151. // TODO: We'll want differentiation between TCP and TLS here.
  152. let addr_sock = (
  153. addr.host()
  154. .ok_or_else(|| Error::UrlParseError(format!("Missing host in {}", addr)))?
  155. .to_string(),
  156. addr.port().ok_or_else(|| Error::UrlParseError(format!("Missing port in {}", addr)))?,
  157. )
  158. .to_socket_addrs()?
  159. .next()
  160. .ok_or(Error::NoUrlFound)?;
  161. let protocol = ReqProtocol::new(addr_sock, String::from("GATEWAY CLIENT"));
  162. let slabstore = SlabStore::new(rocks)?;
  163. let (gateway_slabs_sub_s, gateway_slabs_sub_rv) = async_channel::unbounded::<Slab>();
  164. let sub_addr_sock = (
  165. sub_addr
  166. .host()
  167. .ok_or_else(|| Error::UrlParseError(format!("Missing host in {}", sub_addr)))?
  168. .to_string(),
  169. sub_addr
  170. .port()
  171. .ok_or_else(|| Error::UrlParseError(format!("Missing port in {}", sub_addr)))?,
  172. )
  173. .to_socket_addrs()?
  174. .next()
  175. .ok_or(Error::NoUrlFound)?;
  176. Ok(GatewayClient {
  177. protocol,
  178. slabstore,
  179. gateway_slabs_sub_s,
  180. gateway_slabs_sub_rv,
  181. is_running: false,
  182. sub_addr: sub_addr_sock,
  183. })
  184. }
  185. pub async fn start(&mut self) -> Result<()> {
  186. self.protocol.start().await?;
  187. self.sync().await?;
  188. self.is_running = true;
  189. Ok(())
  190. }
  191. pub async fn sync(&mut self) -> Result<u64> {
  192. debug!(target: "GATEWAY CLIENT", "Start Syncing");
  193. let local_last_index = self.slabstore.get_last_index()?;
  194. let last_index = self.get_last_index().await?;
  195. if last_index < local_last_index {
  196. return Err(Error::SlabsStore(
  197. "Local slabstore has higher index than gateway's slabstore.
  198. Run \" darkfid -r \" to refresh the database."
  199. .into(),
  200. ))
  201. }
  202. if last_index > 0 {
  203. for index in (local_last_index + 1)..(last_index + 1) {
  204. if self.get_slab(index).await?.is_none() {
  205. break
  206. }
  207. }
  208. }
  209. debug!(target: "GATEWAY CLIENT","End Syncing");
  210. Ok(last_index)
  211. }
  212. pub async fn get_slab(&mut self, index: u64) -> Result<Option<Slab>> {
  213. debug!(target: "GATEWAY CLIENT","Get slab");
  214. let handle_error = Arc::new(handle_error);
  215. let rep = self
  216. .protocol
  217. .request(GatewayCommand::GetSlab as u8, serialize(&index), handle_error)
  218. .await?;
  219. if let Some(slab) = rep {
  220. let slab: Slab = deserialize(&slab)?;
  221. self.gateway_slabs_sub_s.send(slab.clone()).await?;
  222. self.slabstore.put(slab.clone())?;
  223. return Ok(Some(slab))
  224. }
  225. Ok(None)
  226. }
  227. pub async fn put_slab(&mut self, mut slab: Slab) -> Result<()> {
  228. debug!(target: "GATEWAY CLIENT","Put slab");
  229. loop {
  230. let last_index = self.sync().await?;
  231. slab.set_index(last_index + 1);
  232. let slab = serialize(&slab);
  233. let handle_error = Arc::new(handle_error);
  234. let rep = self
  235. .protocol
  236. .request(GatewayCommand::PutSlab as u8, slab.clone(), handle_error)
  237. .await?;
  238. if rep.is_some() {
  239. break
  240. }
  241. }
  242. Ok(())
  243. }
  244. pub async fn get_last_index(&mut self) -> Result<u64> {
  245. debug!(target: "GATEWAY CLIENT","Get last index");
  246. let handle_error = Arc::new(handle_error);
  247. let rep =
  248. self.protocol.request(GatewayCommand::GetLastIndex as u8, vec![], handle_error).await?;
  249. if let Some(index) = rep {
  250. return deserialize(&index)
  251. }
  252. Ok(0)
  253. }
  254. pub fn get_slabstore(&self) -> Arc<SlabStore> {
  255. self.slabstore.clone()
  256. }
  257. pub async fn start_subscriber(
  258. &self,
  259. executor: Arc<Executor<'_>>,
  260. ) -> Result<GatewaySlabsSubscriber> {
  261. debug!(target: "GATEWAY CLIENT", "Start subscriber");
  262. let mut subscriber = Subscriber::new(self.sub_addr, String::from("GATEWAY CLIENT"));
  263. subscriber.start().await?;
  264. executor
  265. .spawn(Self::subscribe_loop(
  266. subscriber,
  267. self.slabstore.clone(),
  268. self.gateway_slabs_sub_s.clone(),
  269. ))
  270. .detach();
  271. Ok(self.gateway_slabs_sub_rv.clone())
  272. }
  273. async fn subscribe_loop(
  274. mut subscriber: Subscriber,
  275. slabstore: Arc<SlabStore>,
  276. gateway_slabs_sub_s: async_channel::Sender<Slab>,
  277. ) -> Result<()> {
  278. debug!(target: "GATEWAY CLIENT", "Start subscribe loop");
  279. loop {
  280. let slab = subscriber.fetch::<Slab>().await?;
  281. debug!(target: "GATEWAY CLIENT", "Received new slab");
  282. gateway_slabs_sub_s.send(slab.clone()).await?;
  283. slabstore.put(slab)?;
  284. }
  285. }
  286. pub fn is_running(&self) -> bool {
  287. self.is_running
  288. }
  289. }
  290. fn handle_error(status_code: u32) {
  291. match status_code {
  292. 1 => {
  293. debug!(target: "GATEWAY SERVICE", "Reply has an Error: Index is not updated");
  294. }
  295. 2 => {
  296. debug!(target: "GATEWAY SERVICE", "Reply has an Error: Index Not Exist");
  297. }
  298. _ => {}
  299. }
  300. }