protocol_sync.rs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2024 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use std::sync::Arc;
  19. use async_trait::async_trait;
  20. use log::{debug, error};
  21. use darkfi::{
  22. blockchain::{BlockInfo, Header, HeaderHash},
  23. impl_p2p_message,
  24. net::{
  25. protocol::protocol_generic::{
  26. ProtocolGenericAction, ProtocolGenericHandler, ProtocolGenericHandlerPtr,
  27. },
  28. session::SESSION_DEFAULT,
  29. Message, P2pPtr,
  30. },
  31. system::ExecutorPtr,
  32. validator::{consensus::Proposal, ValidatorPtr},
  33. Error, Result,
  34. };
  35. use darkfi_serial::{SerialDecodable, SerialEncodable};
  36. // Constant defining how many blocks we send during syncing.
  37. pub const BATCH: usize = 20;
  38. /// Structure represening a request to ask a node for their current
  39. /// canonical(confirmed) tip block hash, if they are synced. We also
  40. /// include our own tip, so they can verify we follow the same sequence.
  41. #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
  42. pub struct TipRequest {
  43. /// Canonical(confirmed) tip block hash
  44. pub tip: HeaderHash,
  45. }
  46. impl_p2p_message!(TipRequest, "tiprequest");
  47. /// Structure representing the response to `TipRequest`,
  48. /// containing a boolean flag to indicate if we are synced,
  49. /// and our canonical(confirmed) tip block height and hash.
  50. #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
  51. pub struct TipResponse {
  52. /// Flag indicating the node is synced
  53. pub synced: bool,
  54. /// Canonical(confirmed) tip block height
  55. pub height: Option<u32>,
  56. /// Canonical(confirmed) tip block hash
  57. pub hash: Option<HeaderHash>,
  58. }
  59. impl_p2p_message!(TipResponse, "tipresponse");
  60. /// Structure represening a request to ask a node for up to `BATCH` headers before
  61. /// the provided header height.
  62. #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
  63. pub struct HeaderSyncRequest {
  64. /// Header height
  65. pub height: u32,
  66. }
  67. impl_p2p_message!(HeaderSyncRequest, "headersyncrequest");
  68. /// Structure representing the response to `HeaderSyncRequest`,
  69. /// containing up to `BATCH` headers before the requested block height.
  70. #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
  71. pub struct HeaderSyncResponse {
  72. /// Response headers
  73. pub headers: Vec<Header>,
  74. }
  75. impl_p2p_message!(HeaderSyncResponse, "headersyncresponse");
  76. /// Structure represening a request to ask a node for up to`BATCH` blocks
  77. /// of provided headers.
  78. #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
  79. pub struct SyncRequest {
  80. /// Header hashes
  81. pub headers: Vec<HeaderHash>,
  82. }
  83. impl_p2p_message!(SyncRequest, "syncrequest");
  84. /// Structure representing the response to `SyncRequest`,
  85. /// containing up to `BATCH` blocks after the requested block height.
  86. #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
  87. pub struct SyncResponse {
  88. /// Response blocks
  89. pub blocks: Vec<BlockInfo>,
  90. }
  91. impl_p2p_message!(SyncResponse, "syncresponse");
  92. /// Structure represening a request to ask a node a fork sequence.
  93. /// If we include a specific fork tip, they have to return its sequence,
  94. /// otherwise they respond with their best fork sequence.
  95. /// We also include our own canonical(confirmed) tip, so they can verify
  96. /// we follow the same sequence.
  97. #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
  98. pub struct ForkSyncRequest {
  99. /// Canonical(confirmed) tip block hash
  100. pub tip: HeaderHash,
  101. /// Optional fork tip block hash
  102. pub fork_tip: Option<HeaderHash>,
  103. }
  104. impl_p2p_message!(ForkSyncRequest, "forksyncrequest");
  105. /// Structure representing the response to `ForkSyncRequest`,
  106. /// containing the requested fork sequence.
  107. #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
  108. pub struct ForkSyncResponse {
  109. /// Response fork proposals
  110. pub proposals: Vec<Proposal>,
  111. }
  112. impl_p2p_message!(ForkSyncResponse, "forksyncresponse");
  113. /// Structure represening a request to ask a node a fork header for the
  114. /// requested height. The fork is identified by the provided header hash.
  115. #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
  116. pub struct ForkHeaderHashRequest {
  117. /// Header height
  118. pub height: u32,
  119. /// Block header hash to identify the fork
  120. pub fork_header: HeaderHash,
  121. }
  122. impl_p2p_message!(ForkHeaderHashRequest, "forkheaderhashrequest");
  123. /// Structure representing the response to `ForkHeaderHashRequest`,
  124. /// containing the requested fork header hash, if it was found.
  125. #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
  126. pub struct ForkHeaderHashResponse {
  127. /// Response fork block header hash
  128. pub fork_header: Option<HeaderHash>,
  129. }
  130. impl_p2p_message!(ForkHeaderHashResponse, "forkheaderhashresponse");
  131. /// Structure represening a request to ask a node for up to `BATCH`
  132. /// fork headers for provided header hashes. The fork is identified
  133. /// by the provided header hash.
  134. #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
  135. pub struct ForkHeadersRequest {
  136. /// Header hashes
  137. pub headers: Vec<HeaderHash>,
  138. /// Block header hash to identify the fork
  139. pub fork_header: HeaderHash,
  140. }
  141. impl_p2p_message!(ForkHeadersRequest, "forkheadersrequest");
  142. /// Structure representing the response to `ForkHeadersRequest`,
  143. /// containing up to `BATCH` fork headers.
  144. #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
  145. pub struct ForkHeadersResponse {
  146. /// Response headers
  147. pub headers: Vec<Header>,
  148. }
  149. impl_p2p_message!(ForkHeadersResponse, "forkheadersresponse");
  150. /// Structure represening a request to ask a node for up to `BATCH`
  151. /// fork proposals for provided header hashes. The fork is identified
  152. /// by the provided header hash.
  153. #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
  154. pub struct ForkProposalsRequest {
  155. /// Header hashes
  156. pub headers: Vec<HeaderHash>,
  157. /// Block header hash to identify the fork
  158. pub fork_header: HeaderHash,
  159. }
  160. impl_p2p_message!(ForkProposalsRequest, "forkproposalsrequest");
  161. /// Structure representing the response to `ForkProposalsRequest`,
  162. /// containing up to `BATCH` fork headers.
  163. #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
  164. pub struct ForkProposalsResponse {
  165. /// Response proposals
  166. pub proposals: Vec<Proposal>,
  167. }
  168. impl_p2p_message!(ForkProposalsResponse, "forkproposalsresponse");
  169. /// Atomic pointer to the `ProtocolSync` handler.
  170. pub type ProtocolSyncHandlerPtr = Arc<ProtocolSyncHandler>;
  171. /// Handler managing all `ProtocolSync` messages, over generic P2P protocols.
  172. pub struct ProtocolSyncHandler {
  173. /// The generic handler for `TipRequest` messages.
  174. tip_handler: ProtocolGenericHandlerPtr<TipRequest, TipResponse>,
  175. /// The generic handler for `HeaderSyncRequest` messages.
  176. header_handler: ProtocolGenericHandlerPtr<HeaderSyncRequest, HeaderSyncResponse>,
  177. /// The generic handler for `SyncRequest` messages.
  178. sync_handler: ProtocolGenericHandlerPtr<SyncRequest, SyncResponse>,
  179. /// The generic handler for `ForkSyncRequest` messages.
  180. fork_sync_handler: ProtocolGenericHandlerPtr<ForkSyncRequest, ForkSyncResponse>,
  181. /// The generic handler for `ForkHeaderHashRequest` messages.
  182. fork_header_hash_handler:
  183. ProtocolGenericHandlerPtr<ForkHeaderHashRequest, ForkHeaderHashResponse>,
  184. /// The generic handler for `ForkHeadersRequest` messages.
  185. fork_headers_handler: ProtocolGenericHandlerPtr<ForkHeadersRequest, ForkHeadersResponse>,
  186. /// The generic handler for `ForkProposalsRequest` messages.
  187. fork_proposals_handler: ProtocolGenericHandlerPtr<ForkProposalsRequest, ForkProposalsResponse>,
  188. }
  189. impl ProtocolSyncHandler {
  190. /// Initialize the generic prototocol handlers for all `ProtocolSync` messages
  191. /// and register them to the provided P2P network, using the default session flag.
  192. pub async fn init(p2p: &P2pPtr) -> ProtocolSyncHandlerPtr {
  193. debug!(
  194. target: "darkfid::proto::protocol_sync::init",
  195. "Adding all sync protocols to the protocol registry"
  196. );
  197. let tip_handler =
  198. ProtocolGenericHandler::new(p2p, "ProtocolSyncTip", SESSION_DEFAULT).await;
  199. let header_handler =
  200. ProtocolGenericHandler::new(p2p, "ProtocolSyncHeader", SESSION_DEFAULT).await;
  201. let sync_handler = ProtocolGenericHandler::new(p2p, "ProtocolSync", SESSION_DEFAULT).await;
  202. let fork_sync_handler =
  203. ProtocolGenericHandler::new(p2p, "ProtocolSyncFork", SESSION_DEFAULT).await;
  204. let fork_header_hash_handler =
  205. ProtocolGenericHandler::new(p2p, "ProtocolSyncForkHeaderHash", SESSION_DEFAULT).await;
  206. let fork_headers_handler =
  207. ProtocolGenericHandler::new(p2p, "ProtocolSyncForkHeaders", SESSION_DEFAULT).await;
  208. let fork_proposals_handler =
  209. ProtocolGenericHandler::new(p2p, "ProtocolSyncForkProposals", SESSION_DEFAULT).await;
  210. Arc::new(Self {
  211. tip_handler,
  212. header_handler,
  213. sync_handler,
  214. fork_sync_handler,
  215. fork_header_hash_handler,
  216. fork_headers_handler,
  217. fork_proposals_handler,
  218. })
  219. }
  220. /// Start all `ProtocolSync` background tasks.
  221. pub async fn start(&self, executor: &ExecutorPtr, validator: &ValidatorPtr) -> Result<()> {
  222. debug!(
  223. target: "darkfid::proto::protocol_sync::start",
  224. "Starting sync protocols handlers tasks..."
  225. );
  226. self.tip_handler.task.clone().start(
  227. handle_receive_tip_request(self.tip_handler.clone(), validator.clone()),
  228. |res| async move {
  229. match res {
  230. Ok(()) | Err(Error::DetachedTaskStopped) => { /* Do nothing */ }
  231. Err(e) => error!(target: "darkfid::proto::protocol_sync::start", "Failed starting ProtocolSyncTip handler task: {e}"),
  232. }
  233. },
  234. Error::DetachedTaskStopped,
  235. executor.clone(),
  236. );
  237. self.header_handler.task.clone().start(
  238. handle_receive_header_request(self.header_handler.clone(), validator.clone()),
  239. |res| async move {
  240. match res {
  241. Ok(()) | Err(Error::DetachedTaskStopped) => { /* Do nothing */ }
  242. Err(e) => error!(target: "darkfid::proto::protocol_sync::start", "Failed starting ProtocolSyncHeader handler task: {e}"),
  243. }
  244. },
  245. Error::DetachedTaskStopped,
  246. executor.clone(),
  247. );
  248. self.sync_handler.task.clone().start(
  249. handle_receive_request(self.sync_handler.clone(), validator.clone()),
  250. |res| async move {
  251. match res {
  252. Ok(()) | Err(Error::DetachedTaskStopped) => { /* Do nothing */ }
  253. Err(e) => error!(target: "darkfid::proto::protocol_sync::start", "Failed starting ProtocolSync handler task: {e}"),
  254. }
  255. },
  256. Error::DetachedTaskStopped,
  257. executor.clone(),
  258. );
  259. self.fork_sync_handler.task.clone().start(
  260. handle_receive_fork_request(self.fork_sync_handler.clone(), validator.clone()),
  261. |res| async move {
  262. match res {
  263. Ok(()) | Err(Error::DetachedTaskStopped) => { /* Do nothing */ }
  264. Err(e) => error!(target: "darkfid::proto::protocol_sync::start", "Failed starting ProtocolSyncFork handler task: {e}"),
  265. }
  266. },
  267. Error::DetachedTaskStopped,
  268. executor.clone(),
  269. );
  270. self.fork_header_hash_handler.task.clone().start(
  271. handle_receive_fork_header_hash_request(self.fork_header_hash_handler.clone(), validator.clone()),
  272. |res| async move {
  273. match res {
  274. Ok(()) | Err(Error::DetachedTaskStopped) => { /* Do nothing */ }
  275. Err(e) => error!(target: "darkfid::proto::protocol_sync::start", "Failed starting ProtocolSyncForkHeaderHash handler task: {e}"),
  276. }
  277. },
  278. Error::DetachedTaskStopped,
  279. executor.clone(),
  280. );
  281. self.fork_headers_handler.task.clone().start(
  282. handle_receive_fork_headers_request(self.fork_headers_handler.clone(), validator.clone()),
  283. |res| async move {
  284. match res {
  285. Ok(()) | Err(Error::DetachedTaskStopped) => { /* Do nothing */ }
  286. Err(e) => error!(target: "darkfid::proto::protocol_sync::start", "Failed starting ProtocolSyncForkHeaders handler task: {e}"),
  287. }
  288. },
  289. Error::DetachedTaskStopped,
  290. executor.clone(),
  291. );
  292. self.fork_proposals_handler.task.clone().start(
  293. handle_receive_fork_proposals_request(self.fork_proposals_handler.clone(), validator.clone()),
  294. |res| async move {
  295. match res {
  296. Ok(()) | Err(Error::DetachedTaskStopped) => { /* Do nothing */ }
  297. Err(e) => error!(target: "darkfid::proto::protocol_sync::start", "Failed starting ProtocolSyncForkProposals handler task: {e}"),
  298. }
  299. },
  300. Error::DetachedTaskStopped,
  301. executor.clone(),
  302. );
  303. debug!(
  304. target: "darkfid::proto::protocol_sync::start",
  305. "Sync protocols handlers tasks started!"
  306. );
  307. Ok(())
  308. }
  309. /// Stop all `ProtocolSync` background tasks.
  310. pub async fn stop(&self) {
  311. debug!(target: "darkfid::proto::protocol_sync::stop", "Terminating sync protocols handlers tasks...");
  312. self.tip_handler.task.stop().await;
  313. self.header_handler.task.stop().await;
  314. self.sync_handler.task.stop().await;
  315. self.fork_sync_handler.task.stop().await;
  316. self.fork_header_hash_handler.task.stop().await;
  317. self.fork_headers_handler.task.stop().await;
  318. self.fork_proposals_handler.task.stop().await;
  319. debug!(target: "darkfid::proto::protocol_sync::stop", "Sync protocols handlers tasks terminated!");
  320. }
  321. }
  322. /// Background handler function for ProtocolSyncTip.
  323. async fn handle_receive_tip_request(
  324. handler: ProtocolGenericHandlerPtr<TipRequest, TipResponse>,
  325. validator: ValidatorPtr,
  326. ) -> Result<()> {
  327. debug!(target: "darkfid::proto::protocol_sync::handle_receive_tip_request", "START");
  328. loop {
  329. // Wait for a new tip request message
  330. let (channel, request) = match handler.receiver.recv().await {
  331. Ok(r) => r,
  332. Err(e) => {
  333. debug!(
  334. target: "darkfid::proto::protocol_sync::handle_receive_tip_request",
  335. "recv fail: {e}"
  336. );
  337. continue
  338. }
  339. };
  340. debug!(target: "darkfid::proto::protocol_sync::handle_receive_tip_request", "Received request: {request:?}");
  341. // Check if node has finished syncing its blockchain
  342. if !*validator.synced.read().await {
  343. debug!(
  344. target: "darkfid::proto::protocol_sync::handle_receive_tip_request",
  345. "Node still syncing blockchain"
  346. );
  347. handler
  348. .send_action(
  349. channel,
  350. ProtocolGenericAction::Response(TipResponse {
  351. synced: false,
  352. height: None,
  353. hash: None,
  354. }),
  355. )
  356. .await;
  357. continue
  358. }
  359. // Check we follow the same sequence
  360. match validator.blockchain.blocks.contains(&request.tip) {
  361. Ok(contains) => {
  362. if !contains {
  363. debug!(
  364. target: "darkfid::proto::protocol_sync::handle_receive_tip_request",
  365. "Node doesn't follow request sequence"
  366. );
  367. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  368. continue
  369. }
  370. }
  371. Err(e) => {
  372. error!(
  373. target: "darkfid::proto::protocol_sync::handle_receive_tip_request",
  374. "block_store.contains fail: {e}"
  375. );
  376. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  377. continue
  378. }
  379. }
  380. // Grab our current tip and return it
  381. let tip = match validator.blockchain.last() {
  382. Ok(v) => v,
  383. Err(e) => {
  384. error!(
  385. target: "darkfid::proto::protocol_sync::handle_receive_tip_request",
  386. "blockchain.last fail: {e}"
  387. );
  388. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  389. continue
  390. }
  391. };
  392. // Send response
  393. handler
  394. .send_action(
  395. channel,
  396. ProtocolGenericAction::Response(TipResponse {
  397. synced: true,
  398. height: Some(tip.0),
  399. hash: Some(tip.1),
  400. }),
  401. )
  402. .await;
  403. }
  404. }
  405. /// Background handler function for ProtocolSyncHeader.
  406. async fn handle_receive_header_request(
  407. handler: ProtocolGenericHandlerPtr<HeaderSyncRequest, HeaderSyncResponse>,
  408. validator: ValidatorPtr,
  409. ) -> Result<()> {
  410. debug!(target: "darkfid::proto::protocol_sync::handle_receive_header_request", "START");
  411. loop {
  412. // Wait for a new header request message
  413. let (channel, request) = match handler.receiver.recv().await {
  414. Ok(r) => r,
  415. Err(e) => {
  416. debug!(
  417. target: "darkfid::proto::protocol_sync::handle_receive_header_request",
  418. "recv fail: {e}"
  419. );
  420. continue
  421. }
  422. };
  423. // Check if node has finished syncing its blockchain
  424. if !*validator.synced.read().await {
  425. debug!(
  426. target: "darkfid::proto::protocol_sync::handle_receive_header_request",
  427. "Node still syncing blockchain, skipping..."
  428. );
  429. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  430. continue
  431. }
  432. debug!(target: "darkfid::proto::protocol_sync::handle_receive_header_request", "Received request: {request:?}");
  433. // Grab the corresponding headers
  434. let headers = match validator.blockchain.get_headers_before(request.height, BATCH) {
  435. Ok(v) => v,
  436. Err(e) => {
  437. error!(
  438. target: "darkfid::proto::protocol_sync::handle_receive_header_request",
  439. "get_headers_before fail: {}",
  440. e
  441. );
  442. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  443. continue
  444. }
  445. };
  446. // Send response
  447. handler
  448. .send_action(channel, ProtocolGenericAction::Response(HeaderSyncResponse { headers }))
  449. .await;
  450. }
  451. }
  452. /// Background handler function for ProtocolSync.
  453. async fn handle_receive_request(
  454. handler: ProtocolGenericHandlerPtr<SyncRequest, SyncResponse>,
  455. validator: ValidatorPtr,
  456. ) -> Result<()> {
  457. debug!(target: "darkfid::proto::protocol_sync::handle_receive_request", "START");
  458. loop {
  459. // Wait for a new sync request message
  460. let (channel, request) = match handler.receiver.recv().await {
  461. Ok(r) => r,
  462. Err(e) => {
  463. debug!(
  464. target: "darkfid::proto::protocol_sync::handle_receive_request",
  465. "recv fail: {e}"
  466. );
  467. continue
  468. }
  469. };
  470. // Check if node has finished syncing its blockchain
  471. if !*validator.synced.read().await {
  472. debug!(
  473. target: "darkfid::proto::protocol_sync::handle_receive_request",
  474. "Node still syncing blockchain, skipping..."
  475. );
  476. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  477. continue
  478. }
  479. // Check if request exists the configured limit
  480. if request.headers.len() > BATCH {
  481. debug!(
  482. target: "darkfid::proto::protocol_sync::handle_receive_request",
  483. "Node requested more blocks than allowed."
  484. );
  485. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  486. continue
  487. }
  488. debug!(target: "darkfid::proto::protocol_sync::handle_receive_request", "Received request: {request:?}");
  489. // Grab the corresponding blocks
  490. let blocks = match validator.blockchain.get_blocks_by_hash(&request.headers) {
  491. Ok(v) => v,
  492. Err(e) => {
  493. error!(
  494. target: "darkfid::proto::protocol_sync::handle_receive_request",
  495. "get_blocks_after fail: {}",
  496. e
  497. );
  498. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  499. continue
  500. }
  501. };
  502. // Send response
  503. handler
  504. .send_action(channel, ProtocolGenericAction::Response(SyncResponse { blocks }))
  505. .await;
  506. }
  507. }
  508. /// Background handler function for ProtocolSyncFork.
  509. async fn handle_receive_fork_request(
  510. handler: ProtocolGenericHandlerPtr<ForkSyncRequest, ForkSyncResponse>,
  511. validator: ValidatorPtr,
  512. ) -> Result<()> {
  513. debug!(target: "darkfid::proto::protocol_sync::handle_receive_fork_request", "START");
  514. loop {
  515. // Wait for a new fork sync request message
  516. let (channel, request) = match handler.receiver.recv().await {
  517. Ok(r) => r,
  518. Err(e) => {
  519. debug!(
  520. target: "darkfid::proto::protocol_sync::handle_receive_fork_request",
  521. "recv fail: {e}"
  522. );
  523. continue
  524. }
  525. };
  526. // Check if node has finished syncing its blockchain
  527. if !*validator.synced.read().await {
  528. debug!(
  529. target: "darkfid::proto::protocol_sync::handle_receive_fork_request",
  530. "Node still syncing blockchain, skipping..."
  531. );
  532. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  533. continue
  534. }
  535. debug!(target: "darkfid::proto::protocol_sync::handle_receive_fork_request", "Received request: {request:?}");
  536. // Retrieve proposals sequence
  537. let proposals = match validator
  538. .consensus
  539. .get_fork_proposals_after(request.tip, request.fork_tip, BATCH as u32)
  540. .await
  541. {
  542. Ok(p) => p,
  543. Err(e) => {
  544. debug!(
  545. target: "darkfid::proto::protocol_sync::handle_receive_fork_request",
  546. "Getting fork proposals failed: {}",
  547. e
  548. );
  549. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  550. continue
  551. }
  552. };
  553. // Send response
  554. handler
  555. .send_action(channel, ProtocolGenericAction::Response(ForkSyncResponse { proposals }))
  556. .await;
  557. }
  558. }
  559. /// Background handler function for ProtocolSyncForkHeaderHash.
  560. async fn handle_receive_fork_header_hash_request(
  561. handler: ProtocolGenericHandlerPtr<ForkHeaderHashRequest, ForkHeaderHashResponse>,
  562. validator: ValidatorPtr,
  563. ) -> Result<()> {
  564. debug!(target: "darkfid::proto::protocol_sync::handle_receive_fork_header_hash_request", "START");
  565. loop {
  566. // Wait for a new fork header hash request message
  567. let (channel, request) = match handler.receiver.recv().await {
  568. Ok(r) => r,
  569. Err(e) => {
  570. debug!(
  571. target: "darkfid::proto::protocol_sync::handle_receive_fork_header_hash_request",
  572. "recv fail: {e}"
  573. );
  574. continue
  575. }
  576. };
  577. // Check if node has finished syncing its blockchain
  578. if !*validator.synced.read().await {
  579. debug!(
  580. target: "darkfid::proto::protocol_sync::handle_receive_fork_header_hash_request",
  581. "Node still syncing blockchain, skipping..."
  582. );
  583. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  584. continue
  585. }
  586. debug!(target: "darkfid::proto::protocol_sync::handle_receive_fork_header_hash_request", "Received request: {request:?}");
  587. // Retrieve fork header
  588. let fork_header = match validator
  589. .consensus
  590. .get_fork_header_hash(request.height, &request.fork_header)
  591. .await
  592. {
  593. Ok(h) => h,
  594. Err(e) => {
  595. debug!(
  596. target: "darkfid::proto::protocol_sync::handle_receive_fork_header_hash_request",
  597. "Getting fork header hash failed: {}",
  598. e
  599. );
  600. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  601. continue
  602. }
  603. };
  604. // Send response
  605. handler
  606. .send_action(
  607. channel,
  608. ProtocolGenericAction::Response(ForkHeaderHashResponse { fork_header }),
  609. )
  610. .await;
  611. }
  612. }
  613. /// Background handler function for ProtocolSyncForkHeaders.
  614. async fn handle_receive_fork_headers_request(
  615. handler: ProtocolGenericHandlerPtr<ForkHeadersRequest, ForkHeadersResponse>,
  616. validator: ValidatorPtr,
  617. ) -> Result<()> {
  618. debug!(target: "darkfid::proto::protocol_sync::handle_receive_fork_headers_request", "START");
  619. loop {
  620. // Wait for a new fork header hash request message
  621. let (channel, request) = match handler.receiver.recv().await {
  622. Ok(r) => r,
  623. Err(e) => {
  624. debug!(
  625. target: "darkfid::proto::protocol_sync::handle_receive_fork_headers_request",
  626. "recv fail: {e}"
  627. );
  628. continue
  629. }
  630. };
  631. // Check if node has finished syncing its blockchain
  632. if !*validator.synced.read().await {
  633. debug!(
  634. target: "darkfid::proto::protocol_sync::handle_receive_fork_headers_request",
  635. "Node still syncing blockchain, skipping..."
  636. );
  637. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  638. continue
  639. }
  640. // Check if request exists the configured limit
  641. if request.headers.len() > BATCH {
  642. debug!(
  643. target: "darkfid::proto::protocol_sync::handle_receive_fork_headers_request",
  644. "Node requested more headers than allowed."
  645. );
  646. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  647. continue
  648. }
  649. debug!(target: "darkfid::proto::protocol_sync::handle_receive_fork_headers_request", "Received request: {request:?}");
  650. // Retrieve fork headers
  651. let headers = match validator
  652. .consensus
  653. .get_fork_headers(&request.headers, &request.fork_header)
  654. .await
  655. {
  656. Ok(h) => h,
  657. Err(e) => {
  658. debug!(
  659. target: "darkfid::proto::protocol_sync::handle_receive_fork_headers_request",
  660. "Getting fork headers failed: {}",
  661. e
  662. );
  663. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  664. continue
  665. }
  666. };
  667. // Send response
  668. handler
  669. .send_action(channel, ProtocolGenericAction::Response(ForkHeadersResponse { headers }))
  670. .await;
  671. }
  672. }
  673. /// Background handler function for ProtocolSyncForkProposals.
  674. async fn handle_receive_fork_proposals_request(
  675. handler: ProtocolGenericHandlerPtr<ForkProposalsRequest, ForkProposalsResponse>,
  676. validator: ValidatorPtr,
  677. ) -> Result<()> {
  678. debug!(target: "darkfid::proto::protocol_sync::handle_receive_fork_proposals_request", "START");
  679. loop {
  680. // Wait for a new fork header hash request message
  681. let (channel, request) = match handler.receiver.recv().await {
  682. Ok(r) => r,
  683. Err(e) => {
  684. debug!(
  685. target: "darkfid::proto::protocol_sync::handle_receive_fork_proposals_request",
  686. "recv fail: {e}"
  687. );
  688. continue
  689. }
  690. };
  691. // Check if node has finished syncing its blockchain
  692. if !*validator.synced.read().await {
  693. debug!(
  694. target: "darkfid::proto::protocol_sync::handle_receive_fork_proposals_request",
  695. "Node still syncing blockchain, skipping..."
  696. );
  697. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  698. continue
  699. }
  700. // Check if request exists the configured limit
  701. if request.headers.len() > BATCH {
  702. debug!(
  703. target: "darkfid::proto::protocol_sync::handle_receive_fork_proposals_request",
  704. "Node requested more proposals than allowed."
  705. );
  706. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  707. continue
  708. }
  709. debug!(target: "darkfid::proto::protocol_sync::handle_receive_fork_proposals_request", "Received request: {request:?}");
  710. // Retrieve fork headers
  711. let proposals = match validator
  712. .consensus
  713. .get_fork_proposals(&request.headers, &request.fork_header)
  714. .await
  715. {
  716. Ok(p) => p,
  717. Err(e) => {
  718. debug!(
  719. target: "darkfid::proto::protocol_sync::handle_receive_fork_proposals_request",
  720. "Getting fork proposals failed: {}",
  721. e
  722. );
  723. handler.send_action(channel, ProtocolGenericAction::Skip).await;
  724. continue
  725. }
  726. };
  727. // Send response
  728. handler
  729. .send_action(
  730. channel,
  731. ProtocolGenericAction::Response(ForkProposalsResponse { proposals }),
  732. )
  733. .await;
  734. }
  735. }