aboutsummaryrefslogtreecommitdiffstats
path: root/src/transport
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-01 05:32:36 +0100
committertv <tv@krebsco.de>2026-11-01 05:32:36 +0100
commitd264f2df01c59bf4627b496290a553aa376369ef (patch)
treeb0830b6a5b730223f4ef92ad8e4df863e60bc87d /src/transport
parent9f8feeab71ccb864606c336097e20dbb8e1d8c86 (diff)
allow creating all key files
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/libp2p/config.rs31
-rw-r--r--src/transport/mycelium/mod.rs28
2 files changed, 50 insertions, 9 deletions
diff --git a/src/transport/libp2p/config.rs b/src/transport/libp2p/config.rs
index 6d26224..348a170 100644
--- a/src/transport/libp2p/config.rs
+++ b/src/transport/libp2p/config.rs
@@ -70,6 +70,9 @@ pub(crate) fn check(settings: &crate::config::Settings) -> Result<()> {
&settings.libp2p_ignore,
&settings.libp2p_prefer,
)?;
+ if settings.libp2p_key_create && settings.libp2p_key_file.is_none() {
+ bail!("libp2p-key-create creates the key at libp2p-key-file; set that too");
+ }
if settings.relay_only {
if settings.libp2p_listen.is_empty() {
bail!("relay-only needs libp2p-listen: where nodes reach the relay");
@@ -119,7 +122,10 @@ impl Libp2pConfig {
) -> Result<Self> {
let parse = parse_addresses;
Ok(Self {
- key: Self::load_key(settings.libp2p_key_file.as_deref())?,
+ key: Self::load_key(
+ settings.libp2p_key_file.as_deref(),
+ settings.libp2p_key_create,
+ )?,
listen: parse("libp2p-listen", &settings.libp2p_listen)?,
announce: parse("libp2p-announce", &settings.libp2p_announce)?,
relays: parse("libp2p-relays", &settings.libp2p_relays)?,
@@ -135,16 +141,25 @@ impl Libp2pConfig {
})
}
- /// The key in `path` (32 raw bytes, an Ed25519 secret key), or a new one each start
- /// without a file: the peer ID only says where a node is, so a new one costs nothing
- /// but the WHO that finds it again (`transport::identity`).
- pub(crate) fn load_key(path: Option<&Path>) -> Result<Keypair> {
+ /// The key in `path` (32 raw bytes, an Ed25519 secret key), created there with
+ /// `create` if there is no file; or a new one each start without a path: the peer
+ /// ID only says where a node is, so a new one costs nothing but the WHO that finds
+ /// it again (`transport::identity`).
+ pub(crate) fn load_key(path: Option<&Path>, create: bool) -> Result<Keypair> {
let Some(path) = path else {
return Ok(Keypair::generate_ed25519());
};
- let mut bytes = std::fs::read(path)
- .with_context(|| format!("Reading the libp2p key from {}", path.display()))?;
- crate::files::warn_if_readable_by_others(path, "libp2p key");
+ let (mut bytes, created) = crate::files::key_file(
+ path,
+ "libp2p key",
+ create,
+ "libp2p-key-create",
+ "a new peer ID",
+ 32,
+ )?;
+ if created {
+ info!(path = %path.display(), "Created a new libp2p key");
+ }
if bytes.len() != 32 {
bail!(
"The libp2p key in {} has {} bytes; it has 32",
diff --git a/src/transport/mycelium/mod.rs b/src/transport/mycelium/mod.rs
index 21c939d..9078134 100644
--- a/src/transport/mycelium/mod.rs
+++ b/src/transport/mycelium/mod.rs
@@ -104,6 +104,9 @@ pub(crate) fn check(settings: &crate::config::Settings) -> Result<()> {
);
}
}
+ if settings.mycelium_key_create && settings.mycelium_key_file.is_none() {
+ anyhow::bail!("mycelium-key-create creates the key at mycelium-key-file; set that too");
+ }
// A private network has both; one alone would be ignored or invented.
if settings.mycelium_network_key_file.is_some() != settings.mycelium_network_name.is_some() {
anyhow::bail!("mycelium-network-key-file and mycelium-network-name go together");
@@ -113,9 +116,10 @@ pub(crate) fn check(settings: &crate::config::Settings) -> Result<()> {
/// The options only a supervised Mycelium daemon takes, and whether each is set: the
/// other side of `config::CONFLICTS`' `mycelium-rest-url` (a test keeps them the same).
-pub(crate) fn supervised_only(settings: &crate::config::Settings) -> [(&'static str, bool); 4] {
+pub(crate) fn supervised_only(settings: &crate::config::Settings) -> [(&'static str, bool); 5] {
[
("mycelium-key-file", settings.mycelium_key_file.is_some()),
+ ("mycelium-key-create", settings.mycelium_key_create),
(
"mycelium-network-key-file",
settings.mycelium_network_key_file.is_some(),
@@ -138,6 +142,28 @@ pub(crate) async fn start(
settings: &crate::config::Settings,
mut stop: tokio::sync::watch::Receiver<bool>,
) -> Result<Option<MyceliumTransport>> {
+ // The daemon's key, 32 raw bytes (as `daemon` hands it an ephemeral one): read,
+ // or made, here, so a missing file fails before the daemon starts.
+ if let Some(path) = &settings.mycelium_key_file {
+ let (bytes, created) = crate::files::key_file(
+ path,
+ "Mycelium key",
+ settings.mycelium_key_create,
+ "mycelium-key-create",
+ "a new Mycelium address",
+ 32,
+ )?;
+ if bytes.len() != 32 {
+ anyhow::bail!(
+ "The Mycelium key in {} has {} bytes; it has 32",
+ path.display(),
+ bytes.len()
+ );
+ }
+ if created {
+ tracing::info!(path = %path.display(), "Created a new Mycelium key");
+ }
+ }
let spawn_config = MyceliumSpawnConfig {
rest_url_opt: settings
.mycelium_rest_url