primary/
primary_main.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//! Some heavy features to add in the future
//!
//! - Add an gRPC interface to stop including a certian relay in the scan(in a certian
//!   direction i.e towards it or away from it) during the runtime
//! - Abilityt to pause and resume
//! - Ability to load current graph from the database and start working
//! - Ability to choose only specific relays(i.e through the IP address)
//! - Ability to stop the gRPC server during the Runtime
//! - Ability to start the gRPC server during the Runtime

pub mod error;
mod primary;
mod shared;

use anyhow::Context;
use arti_client::{config::TorClientConfigBuilder, TorClient};
use clap::Parser;
use erpc_scanner::relay::NetDirProvider;
use log::info;
use primary::{
    args::Args, config::PrimaryWorkerConfig, worker::PrimaryWorker,
};
use std::process;
use std::sync::Arc;

#[tokio::main]
#[allow(clippy::map_entry, clippy::mutable_key_type)]
#[deny(clippy::await_holding_lock)]
#[deny(clippy::print_stderr)]
#[deny(clippy::print_stdout)]
async fn main() -> anyhow::Result<()> {
    // Loading the arguments and environment variables
    let args = Args::parse();

    // Setup validation and logging
    if let Err(e) = args.setup() {
        use std::io::{self, Write};
        let _ = writeln!(io::stderr(), "{}", e);
        process::exit(1);
    }

    dotenv::from_path(args.env.as_str())
        .context("The env file was not found")?;

    info!(
        "Loading the configs from {} and environment variables from {}",
        args.env, args.env
    );

    let primary_worker_config =
        Arc::new(PrimaryWorkerConfig::load_from_env_and_config(&args)?);
    info!("Current configs set to {primary_worker_config:#?}");

    info!("Spawning a bootstrapped arti_client::TorClient");
    let mut tor_client_config_builder = TorClientConfigBuilder::default();
    tor_client_config_builder.override_net_params().insert(
        String::from("cbtmintimeout"),
        primary_worker_config.primary.min_circuit_build_timeout,
    );
    let tor_client_config = tor_client_config_builder.build()?;
    let tor_client = TorClient::create_bootstrapped(tor_client_config).await?;
    info!("Spawned a bootstrapped arti_client::TorClient");

    let circmgr = tor_client.circmgr().clone();

    let dirmgr = tor_client.dirmgr().clone();
    let netdir_provider = NetDirProvider::from_dirmgr(dirmgr).await?;

    // Create primary worker based on configuration
    let primary_worker = PrimaryWorker::new(
        primary_worker_config,
        netdir_provider.clone(),
        circmgr,
    )
    .await?;

    primary_worker.start().await;
    Ok(())
}