summaryrefslogtreecommitdiffstats
path: root/src/config
diff options
context:
space:
mode:
Diffstat (limited to 'src/config')
-rw-r--r--src/config/mod.rs67
1 files changed, 56 insertions, 11 deletions
diff --git a/src/config/mod.rs b/src/config/mod.rs
index 4f6c5e0..b4ea0aa 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -82,6 +82,13 @@ pub(crate) const OPTIONS: &[OptionSpec] = &[
"Users of the HTTP API (htpasswd file with Argon2 hashes). Required.",
),
option(
+ "protocol-writers",
+ Kind::List,
+ "USER,[USER...]",
+ None,
+ "HTTP API users (from htpasswd) who may write protocol data under /store/_continuum (remake records, members, forget records), e.g. to repair a stuck remake. Such writes act on the whole swarm and are logged. Epoch metadata and the swarm ID are never writable.",
+ ),
+ option(
"debug-api",
Kind::Flag,
"BOOL",
@@ -93,14 +100,28 @@ pub(crate) const OPTIONS: &[OptionSpec] = &[
Kind::List,
"STRING,[STRING...]",
None,
- "How to reach a node of the swarm to join: a Mycelium public key, a Mycelium IPv6 address, or a host name with an AAAA record for one. Without seeds, the node starts a new swarm (genesis).",
+ "How to reach a node of the swarm to join: a Mycelium public key, a Mycelium IPv6 address, or a host name with an AAAA record for one. A node keeps trying until it has joined.",
+ ),
+ option(
+ "genesis",
+ Kind::Flag,
+ "BOOL",
+ Some("false"),
+ "Start a new swarm, as its genesis node, instead of joining one through seeds. Every start with it starts another new swarm: drop it once the swarm exists, and give the node seeds instead. With a --state-file that remembers a swarm, it starts that swarm again instead (empty; nodes of it still running merge with this one).",
+ ),
+ option(
+ "state-file",
+ Kind::Text,
+ "PATH",
+ None,
+ "File where this node remembers its swarm across restarts: the swarm ID and some members to rejoin through (not the document). Written once ready, then rarely. Without it, a restarted node knows only its configured seeds.",
),
option(
"swarm-key-file",
Kind::Text,
"PATH",
None,
- "Pre-shared swarm key: only nodes that know it may join (raw bytes, at least 16; e.g. `head -c 32 /dev/urandom`). Without it, anyone who knows the swarm ID can.",
+ "Pre-shared swarm key: only nodes that know it may join (raw bytes, at least 16; e.g. `head -c 32 /dev/urandom`). Without it, any node that can reach a member may join.",
),
option(
"alias",
@@ -131,6 +152,13 @@ pub(crate) const OPTIONS: &[OptionSpec] = &[
"Members that renewed their alive stamp within this many days vote on remakes (a majority of them must agree). Matters on the node that coordinates a remake.",
),
option(
+ "blob-chunk-kib",
+ Kind::Integer,
+ "KIB",
+ Some("64"),
+ "Chunk size when serving large transfers to other nodes (e.g. an epoch's snapshot to a rejoining node), in KiB (1 to 4096).",
+ ),
+ option(
"mycelium-rest-url",
Kind::Text,
"SCHEME://HOSTNAME:PORT",
@@ -194,9 +222,14 @@ pub(crate) struct Settings {
pub(crate) bind_addr: SocketAddr,
pub(crate) htpasswd: String,
#[serde(default)]
+ pub(crate) protocol_writers: Vec<String>,
+ #[serde(default)]
pub(crate) debug_api: bool,
#[serde(default)]
pub(crate) seeds: Vec<String>,
+ #[serde(default)]
+ pub(crate) genesis: bool,
+ pub(crate) state_file: Option<PathBuf>,
pub(crate) swarm_key_file: Option<PathBuf>,
pub(crate) alias: Option<String>,
#[serde(default = "default_keepalive_secs")]
@@ -205,6 +238,8 @@ pub(crate) struct Settings {
pub(crate) neighbours: usize,
#[serde(default = "default_electorate_window_days")]
pub(crate) electorate_window_days: u64,
+ #[serde(default = "default_blob_chunk_kib")]
+ pub(crate) blob_chunk_kib: u32,
pub(crate) mycelium_rest_url: Option<String>,
pub(crate) mycelium_key_file: Option<PathBuf>,
pub(crate) mycelium_network_key_file: Option<PathBuf>,
@@ -227,6 +262,9 @@ fn default_neighbours() -> usize {
fn default_electorate_window_days() -> u64 {
7
}
+fn default_blob_chunk_kib() -> u32 {
+ 64
+}
fn default_mycelium_peers() -> Vec<String> {
vec!["tls://127.0.0.1:9651".to_owned()]
}
@@ -274,6 +312,9 @@ impl Settings {
if self.keepalive_secs == 0 {
bail!("keepalive-secs must be at least 1");
}
+ if !(1..=4096).contains(&self.blob_chunk_kib) {
+ bail!("blob-chunk-kib must be between 1 and 4096");
+ }
if self.electorate_window_days == 0 {
bail!("electorate-window-days must be at least 1");
}
@@ -376,15 +417,19 @@ fn unset_entry(provenance: Provenance) -> Entry {
/// values from earlier sources (lower precedence), so e.g. `--mycelium-rest-url` on the
/// command line overrides `mycelium-key-file` from a file. Both set in one source is an
/// error (`Settings::check`).
-const CONFLICTS: &[(&[&str], &[&str])] = &[(
- &["mycelium-rest-url"],
- &[
- "mycelium-key-file",
- "mycelium-network-key-file",
- "mycelium-network-name",
- "mycelium-tcp-listen-port",
- ],
-)];
+const CONFLICTS: &[(&[&str], &[&str])] = &[
+ (
+ &["mycelium-rest-url"],
+ &[
+ "mycelium-key-file",
+ "mycelium-network-key-file",
+ "mycelium-network-name",
+ "mycelium-tcp-listen-port",
+ ],
+ ),
+ // A new swarm has nobody to join.
+ (&["genesis"], &["seeds"]),
+];
/// The options `name` can't be combined with.
fn conflicting(name: &str) -> impl Iterator<Item = &'static str> + '_ {