1use super::MeshId;
5use crate::workload_pkg::codec::hex_decode_exact;
6
7#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
9pub enum MeshIdConfigError {
10 #[error("kernel.mesh.genesis_hash must be 64 hex characters")]
12 BadGenesis,
13 #[error("kernel.mesh.mesh_nonce must be 64 hex characters (32 random bytes)")]
15 BadNonce,
16}
17
18pub fn mesh_id_from_config(
23 genesis_hash: Option<&str>,
24 mesh_nonce: Option<&str>,
25) -> Result<Option<MeshId>, MeshIdConfigError> {
26 let nonce = match mesh_nonce {
27 Some(n) => Some(hex_decode_exact::<32>(n).ok_or(MeshIdConfigError::BadNonce)?),
28 None => None,
29 };
30 let pin = match genesis_hash {
31 Some(g) => Some(hex_decode_exact::<32>(g).ok_or(MeshIdConfigError::BadGenesis)?),
32 None => None,
33 };
34 Ok(match (pin, nonce) {
35 (Some(p), Some(n)) => Some(MeshId::derive(&p, &n)),
36 _ => None,
37 })
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43
44 const PIN: &str = "aa00000000000000000000000000000000000000000000000000000000000001";
45 const NONCE: &str = "bb00000000000000000000000000000000000000000000000000000000000002";
46
47 #[test]
48 fn needs_both_and_matches_derive() {
49 assert_eq!(mesh_id_from_config(Some(PIN), None), Ok(None));
50 assert_eq!(mesh_id_from_config(None, Some(NONCE)), Ok(None));
51 let id = mesh_id_from_config(Some(PIN), Some(NONCE)).unwrap().unwrap();
52 assert_eq!(id, MeshId::derive(&[0xaa, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], &[0xbb, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]));
53 let other = "cc00000000000000000000000000000000000000000000000000000000000002";
54 assert_ne!(Some(id), mesh_id_from_config(Some(PIN), Some(other)).unwrap());
55 }
56
57 #[test]
58 fn malformed_values_are_errors() {
59 assert_eq!(mesh_id_from_config(Some(PIN), Some("zz")), Err(MeshIdConfigError::BadNonce));
60 assert_eq!(mesh_id_from_config(Some("12"), Some(NONCE)), Err(MeshIdConfigError::BadGenesis));
61 assert_eq!(mesh_id_from_config(None, Some("zz")), Err(MeshIdConfigError::BadNonce));
62 }
63}