Skip to main content

urma_node/platform/
settings.rs

1//! `service.json`: what `urma-node service run` serves with
2//! (URMA_NODE_INSTALL.md ยง3).
3use super::paths::Paths;
4use crate::{Error, config};
5use libp2p::Multiaddr;
6use serde::{Deserialize, Serialize};
7use std::{
8    net::SocketAddr,
9    path::{Path, PathBuf},
10};
11
12#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
13#[serde(deny_unknown_fields)]
14pub struct CommitRpc {
15    pub url: String,
16    pub cookie: PathBuf,
17}
18
19#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
20#[serde(deny_unknown_fields)]
21pub struct ServiceSettings {
22    pub data: PathBuf,
23    pub config: PathBuf,
24    pub token: PathBuf,
25    pub peer_key: PathBuf,
26    pub listen: SocketAddr,
27    pub urma_listen: Option<SocketAddr>,
28    pub urma_announce: Vec<Multiaddr>,
29    pub chain_peers: Vec<SocketAddr>,
30    pub commit_rpc: Option<CommitRpc>,
31    pub commit_public: bool,
32}
33
34impl ServiceSettings {
35    const LIMIT: usize = 64 * 1024;
36
37    pub fn defaults(paths: &Paths) -> Self {
38        Self {
39            data: paths.data.clone(),
40            config: paths.config.clone(),
41            token: paths.token.clone(),
42            peer_key: paths.peer_key.clone(),
43            listen: config::SERVICE_LISTEN,
44            urma_listen: Some(config::SERVICE_URMA_LISTEN),
45            urma_announce: Vec::new(),
46            chain_peers: Vec::new(),
47            commit_rpc: None,
48            commit_public: true,
49        }
50    }
51
52    pub fn read(path: &Path) -> Result<Self, Error> {
53        Ok(serde_json::from_slice(&read_admin_file(
54            path,
55            Self::LIMIT,
56        )?)?)
57    }
58}
59
60/// Settings an administrator controls: the file and the directory holding it
61/// must be owned by and writable only by administrators (or the reader).
62pub(crate) fn read_admin_file(path: &Path, limit: usize) -> Result<Vec<u8>, Error> {
63    let refused = |what: &Path| {
64        Error::Invalid(format!(
65            "{} must be owned by and writable only by administrators",
66            what.display()
67        ))
68    };
69    let parent = urma_io::output_parent(path);
70    match urma_io::check_admin(parent) {
71        Ok(()) => {}
72        Err(urma_io::Error::PrivatePermissions) => return Err(refused(parent)),
73        Err(error) => return Err(std::io::Error::other(error).into()),
74    }
75    match urma_io::read_admin(path, limit) {
76        Ok(bytes) => Ok(bytes.to_vec()),
77        Err(urma_io::Error::PrivatePermissions) => Err(refused(path)),
78        Err(urma_io::Error::TooLarge { limit }) => Err(Error::Invalid(format!(
79            "{} exceeds {} KiB",
80            path.display(),
81            limit / 1024
82        ))),
83        Err(error) => Err(std::io::Error::other(error).into()),
84    }
85}