Skip to main content

urma_node/
config.rs

1//! Built-in defaults that need one home. Seeds are DNS names whose records the
2//! operator publishes; the daemon dials whatever they resolve to. Regtest and
3//! Bitcoin test chains have no seeds.
4use crate::Error;
5use crate::model::{ArchiveConfig, ChainPoint, Retention};
6use libp2p::Multiaddr;
7use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
8use urma_chain::observation::Chain;
9use urma_runtime::p2p::Anchor;
10
11/// The product's directory under `%ProgramData%` and `%ProgramFiles%`.
12pub const WINDOWS_PRODUCT_DIR: &str = "URMA Node";
13
14/// The system service name: Windows service, Linux account and unit.
15pub const SERVICE_NAME: &str = "urma-node";
16
17/// The chain a fresh system install follows (URMA_NODE_INSTALL.md ยง1).
18pub const SERVICE_CHAIN: Chain = Chain::LitecoinTestnet;
19
20/// The loopback control API of the system service.
21pub const SERVICE_LISTEN: SocketAddr =
22    SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 28331));
23
24/// Network time slice per background object round, as `serve` defaults it.
25pub const SERVICE_OBJECT_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(15);
26
27/// The URMA overlay listener of the system service.
28pub const SERVICE_URMA_LISTEN: SocketAddr =
29    SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 28332));
30
31/// First-install archive config: the embedded header checkpoint of
32/// [`SERVICE_CHAIN`] as application start, unpruned.
33pub fn service_archive_config() -> Result<ArchiveConfig, Error> {
34    let anchor =
35        Anchor::embedded(SERVICE_CHAIN).map_err(|error| Error::Invalid(error.to_string()))?;
36    Ok(ArchiveConfig {
37        chain: SERVICE_CHAIN,
38        application_start: ChainPoint {
39            height: anchor.height,
40            hash: anchor.header.block_hash(),
41        },
42        retention: Retention::Unpruned,
43    })
44}
45
46/// `%ProgramData%`, where the Windows service keeps settings and state.
47#[cfg(windows)]
48pub fn program_data() -> std::path::PathBuf {
49    match std::env::var_os("ProgramData") {
50        Some(dir) => std::path::PathBuf::from(dir),
51        None => std::path::PathBuf::from(r"C:\ProgramData"),
52    }
53}
54
55#[cfg(windows)]
56pub fn program_files() -> std::path::PathBuf {
57    match std::env::var_os("ProgramFiles") {
58        Some(dir) => std::path::PathBuf::from(dir),
59        None => std::path::PathBuf::from(r"C:\Program Files"),
60    }
61}
62
63pub const SEEDS: &[(Chain, &str)] = &[
64    (Chain::LitecoinMainnet, "/dnsaddr/ltc-seed.urma.rosint.org"),
65    (Chain::LitecoinTestnet, "/dnsaddr/tltc-seed.urma.rosint.org"),
66];
67
68/// Parsed built-in seeds for `chain`.
69pub fn seeds(chain: Chain) -> Result<Vec<Multiaddr>, Error> {
70    let genesis = |chain: Chain| {
71        chain
72            .genesis()
73            .map(|identity| identity.0)
74            .map_err(|error| Error::Invalid(error.to_string()))
75    };
76    let wanted = genesis(chain)?;
77    let mut seeds = Vec::new();
78    for (seeded, address) in SEEDS {
79        if genesis(*seeded)? == wanted {
80            let parsed = address
81                .parse()
82                .map_err(|error| Error::Invalid(format!("built-in seed {address}: {error}")))?;
83            seeds.push(parsed);
84        }
85    }
86    Ok(seeds)
87}