main.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. use std::{net::SocketAddr, path::PathBuf, sync::Arc};
  2. use async_executor::Executor;
  3. use clap::{IntoApp, Parser};
  4. use easy_parallel::Parallel;
  5. use log::debug;
  6. use serde::{Deserialize, Serialize};
  7. use simplelog::{ColorChoice, TermLogger, TerminalMode};
  8. use darkfi::{
  9. blockchain::{rocks::columns, Rocks, RocksColumn},
  10. node::service::gateway::GatewayService,
  11. util::{
  12. cli::{log_config, spawn_config, Config},
  13. expand_path, join_config_path,
  14. },
  15. Result,
  16. };
  17. /// The configuration for gatewayd
  18. #[derive(Serialize, Deserialize, Debug)]
  19. pub struct GatewaydConfig {
  20. /// The address where gatewayd should bind its protocol socket
  21. pub protocol_listen_address: SocketAddr,
  22. /// The address where gatewayd should bind its publisher socket
  23. pub publisher_listen_address: SocketAddr,
  24. /// Whether to listen with TLS or plain TCP
  25. pub serve_tls: bool,
  26. /// Path to DER-formatted PKCS#12 archive. (Unused if serve_tls=false)
  27. pub tls_identity_path: String,
  28. /// Password for the TLS identity. (Unused if serve_tls=false)
  29. pub tls_identity_password: String,
  30. /// Path to the database
  31. pub database_path: String,
  32. }
  33. /// Gatewayd cli
  34. #[derive(Parser)]
  35. #[clap(name = "gatewayd")]
  36. pub struct CliGatewayd {
  37. /// Sets a custom config file
  38. #[clap(short, long)]
  39. pub config: Option<String>,
  40. /// Increase verbosity
  41. #[clap(short, parse(from_occurrences))]
  42. pub verbose: u8,
  43. }
  44. const CONFIG_FILE_CONTENTS: &[u8] = include_bytes!("../gatewayd_config.toml");
  45. async fn start(executor: Arc<Executor<'_>>, config: &GatewaydConfig) -> Result<()> {
  46. let rocks = Rocks::new(&expand_path(&config.database_path)?)?;
  47. let rocks_slabstore_column = RocksColumn::<columns::Slabs>::new(rocks);
  48. let gateway = GatewayService::new(
  49. config.protocol_listen_address,
  50. config.publisher_listen_address,
  51. rocks_slabstore_column,
  52. )?;
  53. Ok(gateway.start(executor.clone()).await?)
  54. }
  55. #[async_std::main]
  56. async fn main() -> Result<()> {
  57. let args = CliGatewayd::parse();
  58. let matches = CliGatewayd::command().get_matches();
  59. let config_path = if args.config.is_some() {
  60. expand_path(&args.config.unwrap())?
  61. } else {
  62. join_config_path(&PathBuf::from("gatewayd.toml"))?
  63. };
  64. // Spawn config file if it's not in place already.
  65. spawn_config(&config_path, CONFIG_FILE_CONTENTS)?;
  66. let verbosity_level = matches.occurrences_of("verbose");
  67. let (lvl, conf) = log_config(verbosity_level)?;
  68. TermLogger::init(lvl, conf, TerminalMode::Mixed, ColorChoice::Auto)?;
  69. let config: GatewaydConfig = Config::<GatewaydConfig>::load(config_path)?;
  70. let ex = Arc::new(Executor::new());
  71. let (signal, shutdown) = async_channel::unbounded::<()>();
  72. let ex2 = ex.clone();
  73. let nthreads = num_cpus::get();
  74. debug!(target: "GATEWAY DAEMON", "Run {} executor threads", nthreads);
  75. let (_, result) = Parallel::new()
  76. .each(0..nthreads, |_| smol::future::block_on(ex.run(shutdown.recv())))
  77. // Run the main future on the current thread.
  78. .finish(|| {
  79. smol::future::block_on(async move {
  80. start(ex2, &config).await?;
  81. drop(signal);
  82. Ok::<(), darkfi::Error>(())
  83. })
  84. });
  85. result
  86. }