utils.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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::{collections::HashMap, sync::Arc};
  19. use log::{debug, error, info};
  20. use smol::{fs::read_to_string, Executor};
  21. use structopt_toml::StructOptToml;
  22. use darkfi::{
  23. net::{session::SESSION_DEFAULT, P2p, P2pPtr, Settings},
  24. rpc::jsonrpc::JsonSubscriber,
  25. util::path::get_config_path,
  26. validator::ValidatorPtr,
  27. Error, Result,
  28. };
  29. use crate::{
  30. proto::{ProtocolProposal, ProtocolSync, ProtocolTx},
  31. BlockchainNetwork, CONFIG_FILE,
  32. };
  33. /// Auxiliary function to generate the P2P network and register all its protocols.
  34. pub async fn spawn_p2p(
  35. settings: &Settings,
  36. validator: &ValidatorPtr,
  37. subscribers: &HashMap<&'static str, JsonSubscriber>,
  38. executor: Arc<Executor<'static>>,
  39. ) -> P2pPtr {
  40. info!(target: "darkfid", "Registering sync network P2P protocols...");
  41. let p2p = P2p::new(settings.clone(), executor.clone()).await;
  42. let registry = p2p.protocol_registry();
  43. let _validator = validator.clone();
  44. registry
  45. .register(SESSION_DEFAULT, move |channel, _p2p| {
  46. let validator = _validator.clone();
  47. async move { ProtocolSync::init(channel, validator).await.unwrap() }
  48. })
  49. .await;
  50. let _validator = validator.clone();
  51. let _subscriber = subscribers.get("proposals").unwrap().clone();
  52. registry
  53. .register(SESSION_DEFAULT, move |channel, p2p| {
  54. let validator = _validator.clone();
  55. let subscriber = _subscriber.clone();
  56. async move {
  57. ProtocolProposal::init(channel, validator, p2p, subscriber)
  58. .await
  59. .unwrap()
  60. }
  61. })
  62. .await;
  63. let _validator = validator.clone();
  64. let _subscriber = subscribers.get("txs").unwrap().clone();
  65. registry
  66. .register(SESSION_DEFAULT, move |channel, p2p| {
  67. let validator = _validator.clone();
  68. let subscriber = _subscriber.clone();
  69. async move { ProtocolTx::init(channel, validator, p2p, subscriber).await.unwrap() }
  70. })
  71. .await;
  72. p2p
  73. }
  74. /// Auxiliary function to parse darkfid configuration file and extract requested
  75. /// blockchain network config.
  76. pub async fn parse_blockchain_config(
  77. config: Option<String>,
  78. network: &str,
  79. ) -> Result<BlockchainNetwork> {
  80. // Grab config path
  81. let config_path = get_config_path(config, CONFIG_FILE)?;
  82. debug!(target: "darkfid", "Parsing configuration file: {:?}", config_path);
  83. // Parse TOML file contents
  84. let contents = read_to_string(&config_path).await?;
  85. let contents: toml::Value = match toml::from_str(&contents) {
  86. Ok(v) => v,
  87. Err(e) => {
  88. error!(target: "darkfid", "Failed parsing TOML config: {}", e);
  89. return Err(Error::ParseFailed("Failed parsing TOML config"))
  90. }
  91. };
  92. // Grab requested network config
  93. let Some(table) = contents.as_table() else { return Err(Error::ParseFailed("TOML not a map")) };
  94. let Some(network_configs) = table.get("network_config") else {
  95. return Err(Error::ParseFailed("TOML does not contain network configurations"))
  96. };
  97. let Some(network_configs) = network_configs.as_table() else {
  98. return Err(Error::ParseFailed("`network_config` not a map"))
  99. };
  100. let Some(network_config) = network_configs.get(network) else {
  101. return Err(Error::ParseFailed("TOML does not contain requested network configuration"))
  102. };
  103. let network_config = toml::to_string(&network_config).unwrap();
  104. let network_config =
  105. match BlockchainNetwork::from_iter_with_toml::<Vec<String>>(&network_config, vec![]) {
  106. Ok(v) => v,
  107. Err(e) => {
  108. error!(target: "darkfid", "Failed parsing requested network configuration: {}", e);
  109. return Err(Error::ParseFailed("Failed parsing requested network configuration"))
  110. }
  111. };
  112. debug!(target: "darkfid", "Parsed network configuration: {:?}", network_config);
  113. Ok(network_config)
  114. }