gateway_p2p.rs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. use async_std::sync::{Arc, Mutex};
  2. use std::io;
  3. use async_executor::Executor;
  4. use log::*;
  5. use crate::{
  6. blockchain::{rocks::columns, RocksColumn, Slab, SlabStore},
  7. net,
  8. net::{P2p, P2pPtr, Settings},
  9. util::{
  10. serial::{deserialize, serialize, Decodable, Encodable},
  11. sleep,
  12. },
  13. Error, Result,
  14. };
  15. pub struct Gateway {
  16. p2p: P2pPtr,
  17. slabstore: Arc<SlabStore>,
  18. last_indexes: Arc<Mutex<Vec<u64>>>,
  19. }
  20. impl Gateway {
  21. pub fn new(_settings: Settings, rocks: RocksColumn<columns::Slabs>) -> Result<Self> {
  22. let slabstore = SlabStore::new(rocks)?;
  23. let settings = Settings::default();
  24. let p2p = P2p::new(settings);
  25. let last_indexes = Arc::new(Mutex::new(vec![0; 10]));
  26. Ok(Self { p2p, slabstore, last_indexes })
  27. }
  28. pub async fn start(&self, executor: Arc<Executor<'_>>) -> Result<()> {
  29. self.p2p.clone().start(executor.clone()).await?;
  30. self.p2p.clone().run(executor.clone()).await?;
  31. Ok(())
  32. }
  33. async fn publish(&self, msg: GatewayMessage) -> Result<()> {
  34. self.p2p.broadcast(msg).await
  35. }
  36. async fn subscribe_loop(&self, executor: Arc<Executor<'_>>) -> Result<()> {
  37. let new_channel_sub = self.p2p.subscribe_channel().await;
  38. loop {
  39. let channel = new_channel_sub.receive().await?;
  40. let message_subsytem = channel.get_message_subsystem();
  41. message_subsytem.add_dispatch::<GatewayMessage>().await;
  42. let msg_sub = channel.subscribe_msg::<GatewayMessage>().await?;
  43. let jobsman = net::ProtocolJobsManager::new("GatewayMessage", channel);
  44. jobsman.clone().start(executor.clone());
  45. jobsman
  46. .spawn(Self::handle_msg(self.slabstore.clone(), msg_sub), executor.clone())
  47. .await;
  48. }
  49. }
  50. pub async fn handle_msg(
  51. slabstore: Arc<SlabStore>,
  52. msg_sub: net::MessageSubscription<GatewayMessage>,
  53. ) -> Result<()> {
  54. loop {
  55. let msg = msg_sub.receive().await?;
  56. match msg.get_command() {
  57. GatewayCommand::PutSlab => {
  58. debug!(target: "GATEWAY", "Received putslab msg");
  59. let slab = msg.get_payload();
  60. slabstore.put(deserialize(&slab)?)?;
  61. // TODO publish the new received slab
  62. }
  63. GatewayCommand::GetSlab => {
  64. debug!(target: "GATEWAY", "Received getslab msg");
  65. let index = msg.get_payload();
  66. let _slab = slabstore.get(index)?;
  67. // TODO publish the slab
  68. }
  69. GatewayCommand::GetLastIndex => {
  70. debug!(target: "GATEWAY","Received getlastindex msg");
  71. let _index = slabstore.get_last_index_as_bytes()?;
  72. // TODO publish the inex
  73. }
  74. }
  75. }
  76. }
  77. pub async fn sync(&self) -> Result<()> {
  78. debug!(target: "GATEWAY", "Start Syncing");
  79. loop {
  80. let local_last_index = self.slabstore.get_last_index()?;
  81. // start syncing every 4 seconds
  82. sleep(4).await;
  83. self.get_last_index().await?;
  84. let last_index = 0;
  85. if last_index < local_last_index {
  86. return Err(Error::SlabsStore(
  87. "Local slabstore has higher index than gateway's slabstore.
  88. Run \" darkfid -r \" to refresh the database."
  89. .into(),
  90. ))
  91. }
  92. if last_index > 0 {
  93. for index in (local_last_index + 1)..(last_index + 1) {
  94. self.get_slab(index).await?
  95. }
  96. }
  97. debug!(target: "GATEWAY","End Syncing");
  98. }
  99. }
  100. pub async fn get_slab(&self, index: u64) -> Result<()> {
  101. debug!(target: "GATEWAY","Send get slab msg");
  102. let msg = GatewayMessage::new(GatewayCommand::GetSlab, serialize(&index));
  103. self.publish(msg).await
  104. }
  105. pub async fn put_slab(&self, slab: Slab) -> Result<()> {
  106. debug!(target: "GATEWAY","Send put slab msg");
  107. let msg = GatewayMessage::new(GatewayCommand::PutSlab, serialize(&slab));
  108. self.publish(msg).await
  109. }
  110. pub async fn get_last_index(&self) -> Result<()> {
  111. debug!(target: "GATEWAY","Send get last index msg");
  112. let msg = GatewayMessage::new(GatewayCommand::PutSlab, vec![]);
  113. self.publish(msg).await
  114. }
  115. pub fn get_slabstore(&self) -> Arc<SlabStore> {
  116. self.slabstore.clone()
  117. }
  118. }
  119. #[derive(Debug, PartialEq, Clone)]
  120. pub enum GatewayCommand {
  121. PutSlab,
  122. GetSlab,
  123. GetLastIndex,
  124. }
  125. #[derive(Debug, PartialEq, Clone)]
  126. pub struct GatewayMessage {
  127. command: GatewayCommand,
  128. payload: Vec<u8>,
  129. }
  130. impl GatewayMessage {
  131. pub fn new(command: GatewayCommand, payload: Vec<u8>) -> Self {
  132. Self { command, payload }
  133. }
  134. pub fn get_command(&self) -> GatewayCommand {
  135. self.command.clone()
  136. }
  137. pub fn get_payload(&self) -> Vec<u8> {
  138. self.payload.clone()
  139. }
  140. }
  141. impl Encodable for GatewayMessage {
  142. fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
  143. let mut len = 0;
  144. len += (self.command.clone() as u8).encode(&mut s)?;
  145. len += self.payload.encode(&mut s)?;
  146. Ok(len)
  147. }
  148. }
  149. impl Decodable for GatewayMessage {
  150. fn decode<D: io::Read>(mut d: D) -> Result<Self> {
  151. let command_code: u8 = Decodable::decode(&mut d)?;
  152. let command = match command_code {
  153. 0 => GatewayCommand::PutSlab,
  154. 1 => GatewayCommand::GetSlab,
  155. _ => GatewayCommand::GetLastIndex,
  156. };
  157. Ok(Self { command, payload: Decodable::decode(&mut d)? })
  158. }
  159. }
  160. impl net::Message for GatewayMessage {
  161. fn name() -> &'static str {
  162. "reply"
  163. }
  164. }